1 /******************************************************************
3 * Copyright 2014 Samsung Electronics All Rights Reserved.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
19 ******************************************************************/
20 #include "cawifiadapter_singlethread.h"
27 #include "caadapterutils.h"
29 #include "oic_malloc.h"
30 #include "cawifiinterface_singlethread.h"
33 * @def WIFI_ETHERNET_ADAPTER_TAG
34 * @brief Logging tag for module name
36 #define WIFI_ADAPTER_TAG "WAST"
40 * @brief Port to listen for incoming data. Port 5683 is as per COAP RFC.
46 * @brief Multicast Port Number
48 #define CA_MCAST_PORT 5298
51 * @def CA_MULTICAST_IP
52 * @brief Multicast IP Address
54 #define CA_MULTICAST_IP "224.0.1.187"
58 * @var gNetworkPacketCallback
59 * @brief Network Packet Received Callback to CA
61 static CANetworkPacketReceivedCallback gNetworkPacketCallback = NULL;
64 * @var gNetworkChangeCb
65 * @brief Network Changed Callback to CA
68 static CANetworkChangeCallback gNetworkChangeCallback = NULL;
71 * @var gIsMulticastServerStarted
72 * @brief Flag to check if multicast server is started
74 static bool gIsMulticastServerStarted = false;
77 * @var gIsStartServerCalled
78 * @brief Flag to check if server start requested by CA.
80 static bool gStartUnicastServerRequested = false;
83 * @var gUnicastServerport
84 * @brief port number on which unicast server is running.
86 static int16_t gUnicastServerport = 0;
89 * @var gIsStartServerCalled
90 * @brief Flag to check if server start requested by CA.
92 static bool gStartMulticastServerRequested = false;
95 static void CAWiFiNotifyNetworkChange(const char *address, const int16_t port,
96 const CANetworkStatus_t status);
97 static void CAWiFiConnectionStateCB(const char *ipAddress,
98 const CANetworkStatus_t status);
99 static void CAWiFiPacketReceivedCB(const char *ipAddress, const uint32_t port,
100 const void *data, const uint32_t dataLength);
101 static CAResult_t CAWiFiStopServers();
103 void CAWiFiNotifyNetworkChange(const char *address, const int16_t port,
104 const CANetworkStatus_t status)
106 CALocalConnectivity_t *localEndpoint = CAAdapterCreateLocalEndpoint(CA_WIFI, address);
109 OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Out of memory");
112 localEndpoint->addressInfo.IP.port = port;
114 if (NULL != gNetworkChangeCallback)
116 gNetworkChangeCallback(localEndpoint, status);
119 CAAdapterFreeLocalEndpoint(localEndpoint);
122 void CAWiFiConnectionStateCB(const char *ipAddr,
123 const CANetworkStatus_t status)
125 OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
127 CAResult_t ret = CA_STATUS_FAILED;
128 /* If Wifi is connected, then get the latest IP from the WIFI Interface
129 * and start unicast and multicast servers if requested earlier */
130 if (CA_INTERFACE_UP == status)
132 int16_t port = CA_PORT;
133 int32_t serverFd = -1;
134 /* Start Unicast server if requested earlier */
135 if (gStartUnicastServerRequested)
137 ret = CAWiFiStartUnicastServer("0.0.0.0", &port, false, &serverFd);
138 if (CA_STATUS_OK == ret)
140 OIC_LOG_V(DEBUG, WIFI_ADAPTER_TAG, "Unicast server started on %d port", port);
141 CAWiFiSetUnicastSocket(serverFd);
142 gUnicastServerport = port;
146 OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed [%d]", ret);
150 /* Start Multicast server if requested earlier */
151 if (gStartMulticastServerRequested)
153 int16_t multicastPort = CA_MCAST_PORT;
154 ret = CAWiFiStartMulticastServer("0.0.0.0", CA_MULTICAST_IP, multicastPort, &serverFd);
155 if (CA_STATUS_OK == ret)
157 OIC_LOG_V(DEBUG, WIFI_ADAPTER_TAG, "Multicast server started on %d port", multicastPort);
158 gIsMulticastServerStarted = true;
162 OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed [%d]", ret);
166 /* Notify network change to CA */
167 CAWiFiNotifyNetworkChange(ipAddr, port, status);
171 CAWiFiNotifyNetworkChange("", 0, status);
172 /* Stop both Unicast and Multicast servers */
173 ret = CAWiFiStopServers();
174 if (CA_STATUS_OK != ret)
176 OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed to Stop Servers![%d]", ret);
181 OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
184 void CAWiFiPacketReceivedCB(const char *ipAddress, const uint32_t port,
185 const void *data, const uint32_t dataLength)
187 OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
188 OIC_LOG_V(DEBUG, WIFI_ADAPTER_TAG, "Address: %s, port:%d ", ipAddress, port);
189 OIC_LOG_V(DEBUG, WIFI_ADAPTER_TAG, "Data:%s", data);
191 /* CA is freeing this memory */
192 CARemoteEndpoint_t *endPoint = CAAdapterCreateRemoteEndpoint(CA_WIFI, ipAddress, NULL);
193 if (NULL == endPoint)
195 OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "Out of memory");
198 endPoint->addressInfo.IP.port = port;
200 void *buf = OICMalloc(dataLength + 1);
203 OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "Out of memory");
204 CAAdapterFreeRemoteEndpoint(endPoint);
207 memcpy(buf, data, dataLength);
208 memset(buf + dataLength, 0, 1);
209 if (gNetworkPacketCallback)
211 gNetworkPacketCallback(endPoint, buf, dataLength);
213 CAAdapterFreeRemoteEndpoint(endPoint);
215 OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
218 CAResult_t CAInitializeWifi(CARegisterConnectivityCallback registerCallback,
219 CANetworkPacketReceivedCallback networkPacketCallback,
220 CANetworkChangeCallback netCallback)
222 OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
223 VERIFY_NON_NULL(registerCallback, WIFI_ADAPTER_TAG, "registerCallback");
224 VERIFY_NON_NULL(networkPacketCallback, WIFI_ADAPTER_TAG, "networkPacketCallback");
225 VERIFY_NON_NULL(netCallback, WIFI_ADAPTER_TAG, "netCallback");
227 gNetworkChangeCallback = netCallback;
228 gNetworkPacketCallback = networkPacketCallback;
230 CAResult_t ret = CAWiFiInitializeNetworkMonitor();
231 if (CA_STATUS_OK != ret)
233 OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed to initialize n/w monitor![%d]", ret);
236 CAWiFiSetConnectionStateChangeCallback(CAWiFiConnectionStateCB);
238 // network monitor is yet to be implemented
239 ret = CAWiFiInitializeServer();
240 if (CA_STATUS_OK != ret)
242 OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed to initialize server![%d]", ret);
246 CAWiFiSetPacketReceiveCallback(CAWiFiPacketReceivedCB);
248 CAConnectivityHandler_t wifiHandler;
249 wifiHandler.startAdapter = CAStartWIFI;
250 wifiHandler.startListenServer = CAStartWIFIListeningServer;
251 wifiHandler.startDiscoverServer = CAStartWIFIDiscoveryServer;
252 wifiHandler.sendData = CASendWIFIUnicastData;
253 wifiHandler.sendDataToAll = CASendWIFIMulticastData;
254 wifiHandler.GetnetInfo = CAGetWIFIInterfaceInformation;
255 wifiHandler.readData = CAReadWIFIData;
256 wifiHandler.stopAdapter = CAStopWIFI;
257 wifiHandler.terminate = CATerminateWIfI;
258 registerCallback(wifiHandler, CA_WIFI);
260 OIC_LOG(INFO, WIFI_ADAPTER_TAG, "IntializeWifi Success");
261 OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
265 CAResult_t CAStartWIFI()
267 OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
269 /* Start monitoring wifi network */
270 CAResult_t ret = CAWiFiStartNetworkMonitor();
271 if (CA_STATUS_OK != ret)
273 OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "Failed to Start n/w monitor");
276 gStartUnicastServerRequested = true;
277 bool retVal = CAWiFiIsConnected();
280 OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "WIFI is not Connected");
284 int16_t unicastPort = CA_PORT;
285 int32_t serverFd = 0;
286 // Address is hardcoded as we are using Single Interface
287 ret = CAWiFiStartUnicastServer("0.0.0.0", &unicastPort, false, &serverFd);
288 if (CA_STATUS_OK == ret)
290 OIC_LOG_V(DEBUG, WIFI_ADAPTER_TAG, "Unicast server started on %d port", unicastPort);
291 CAWiFiSetUnicastSocket(serverFd);
292 gUnicastServerport = unicastPort;
295 OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
299 CAResult_t CAStartWIFIListeningServer()
301 OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
303 CAResult_t ret = CA_STATUS_OK;
304 int16_t multicastPort = CA_MCAST_PORT;
306 if (gIsMulticastServerStarted == true)
308 OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Multicast Server, Already Started!");
309 return CA_SERVER_STARTED_ALREADY;
312 gStartMulticastServerRequested = true;
313 bool retVal = CAWiFiIsConnected();
316 OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed : WIFI not Connected");
317 return CA_ADAPTER_NOT_ENABLED;
320 ret = CAWiFiStartMulticastServer("0.0.0.0", CA_MULTICAST_IP, multicastPort, NULL);
321 if (CA_STATUS_OK == ret)
323 OIC_LOG(INFO, WIFI_ADAPTER_TAG, "Multicast Server Started Successfully");
324 gIsMulticastServerStarted = true;
327 OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
331 CAResult_t CAStartWIFIDiscoveryServer()
333 OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
334 /* Both listening and discovery server are same */
335 OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
336 return CAStartWIFIListeningServer();
339 uint32_t CASendWIFIUnicastData(const CARemoteEndpoint_t *remoteEndpoint, void *data,
342 OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
344 uint32_t dataSize = 0;
345 VERIFY_NON_NULL_RET(remoteEndpoint, WIFI_ADAPTER_TAG, "remoteEndpoint", dataSize);
346 VERIFY_NON_NULL_RET(data, WIFI_ADAPTER_TAG, "data", dataSize);
349 OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Invalid Data Length");
353 CAWiFiSendData(remoteEndpoint->addressInfo.IP.ipAddress,
354 remoteEndpoint->addressInfo.IP.port, data, dataLength, false);
355 OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
359 uint32_t CASendWIFIMulticastData(void *data, uint32_t dataLength)
361 OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
363 uint32_t dataSize = 0;
364 VERIFY_NON_NULL_RET(data, WIFI_ADAPTER_TAG, "data", dataSize);
367 OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Invalid Data Length");
371 CAWiFiSendData(CA_MULTICAST_IP, CA_MCAST_PORT, data, dataLength, true);
372 OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
376 CAResult_t CAGetWIFIInterfaceInformation(CALocalConnectivity_t **info, uint32_t *size)
378 OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
379 VERIFY_NON_NULL(info, WIFI_ADAPTER_TAG, "info");
380 VERIFY_NON_NULL(size, WIFI_ADAPTER_TAG, "size");
382 bool retVal = CAWiFiIsConnected();
385 OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG,
386 "Failed to get interface address, WIFI not Connected", CA_ADAPTER_NOT_ENABLED);
387 return CA_ADAPTER_NOT_ENABLED;
390 char *ipAddress = NULL;
391 char *ifcName = NULL;
392 CAResult_t ret = CAWiFiGetInterfaceInfo(&ipAddress, &ifcName);
393 if (CA_STATUS_OK != ret)
395 OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed to get interface info [%d]", ret);
399 // Create local endpoint using util function
400 (*info) = CAAdapterCreateLocalEndpoint(CA_WIFI, ipAddress);
403 OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed to create Local Endpoint!",
404 CA_MEMORY_ALLOC_FAILED);
407 return CA_MEMORY_ALLOC_FAILED;
410 (*info)->addressInfo.IP.port = gUnicastServerport;
416 OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
420 CAResult_t CAReadWIFIData()
426 CAResult_t CAWiFiStopServers()
428 CAResult_t result = CAWiFiStopUnicastServer();
429 if (CA_STATUS_OK != result)
431 OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed to Stop Unicast Server![%d]", result);
434 CAWiFiSetUnicastSocket(-1);
435 gUnicastServerport = -1;
437 result = CAWiFiStopMulticastServer();
438 if (CA_STATUS_OK != result)
440 OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed to Stop Multicast Server![%d]", result);
443 gIsMulticastServerStarted = false;
448 CAResult_t CAStopWIFI()
450 OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
452 gStartUnicastServerRequested = false;
453 gStartMulticastServerRequested = false;
454 CAWiFiStopNetworkMonitor();
455 CAResult_t result = CAWiFiStopServers();
456 if (CA_STATUS_OK != result)
458 OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed to Stop Servers![%d]", result);
461 OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
465 void CATerminateWIfI()
467 OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
469 CAWiFiSetConnectionStateChangeCallback(NULL);
470 CAWiFiTerminateNetworkMonitor();
471 OIC_LOG(INFO, WIFI_ADAPTER_TAG, "nw monitor terminated");
472 CAWiFiSetPacketReceiveCallback(NULL);
473 OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");