Tizen, Android BT , BLE optimization - making similar to wifi, eth adapters
[platform/upstream/iotivity.git] / resource / csdk / connectivity / src / wifi_adapter / cawifiadapter_singlethread.c
1 /******************************************************************
2  *
3  * Copyright 2014 Samsung Electronics All Rights Reserved.
4  *
5  *
6  *
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
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
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.
18  *
19  ******************************************************************/
20 #include "cawifiadapter_singlethread.h"
21
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <stdint.h>
26
27 #include "caadapterutils.h"
28 #include "logger.h"
29 #include "oic_malloc.h"
30 #include "cawifiinterface_singlethread.h"
31
32 /**
33  * @def WIFI_ETHERNET_ADAPTER_TAG
34  * @brief Logging tag for module name
35  */
36 #define WIFI_ADAPTER_TAG "WAST"
37
38 /**
39  * @def CA_PORT
40  * @brief Port to listen for incoming data. Port 5683 is as per COAP RFC.
41  */
42 #define CA_PORT   5683
43
44 /**
45  * @def CA_MCAST_PORT
46  * @brief Multicast Port Number
47  */
48 #define CA_MCAST_PORT   5298
49
50 /**
51  * @def CA_MULTICAST_IP
52  * @brief Multicast IP Address
53  */
54 #define CA_MULTICAST_IP "224.0.1.187"
55
56 /* Skip Queue */
57 /**
58  * @var gNetworkPacketCallback
59  * @brief Network Packet Received Callback to CA
60  */
61 static CANetworkPacketReceivedCallback gNetworkPacketCallback = NULL;
62
63 /**
64  * @var gNetworkChangeCb
65  * @brief Network Changed Callback to CA
66  */
67
68 static CANetworkChangeCallback gNetworkChangeCallback = NULL;
69
70 /**
71  * @var gIsMulticastServerStarted
72  * @brief Flag to check if multicast server is started
73  */
74 static bool gIsMulticastServerStarted = false;
75
76 /**
77  * @var gIsStartServerCalled
78  * @brief Flag to check if server start requested by CA.
79  */
80 static bool gStartUnicastServerRequested = false;
81
82 /**
83  * @var gUnicastServerport
84  * @brief port number on which unicast server is running.
85  */
86 static int16_t gUnicastServerport = 0;
87
88 /**
89  * @var gIsStartServerCalled
90  * @brief Flag to check if server start requested by CA.
91  */
92 static bool gStartMulticastServerRequested = false;
93
94
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();
102
103 void CAWiFiNotifyNetworkChange(const char *address, const int16_t port,
104                                const CANetworkStatus_t status)
105 {
106     CALocalConnectivity_t *localEndpoint = CAAdapterCreateLocalEndpoint(CA_WIFI, address);
107     if (!localEndpoint)
108     {
109         OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Out of memory");
110         return;
111     }
112     localEndpoint->addressInfo.IP.port = port;
113
114     if (NULL != gNetworkChangeCallback)
115     {
116         gNetworkChangeCallback(localEndpoint, status);
117     }
118
119     CAAdapterFreeLocalEndpoint(localEndpoint);
120 }
121
122 void CAWiFiConnectionStateCB(const char *ipAddr,
123                              const CANetworkStatus_t status)
124 {
125     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
126
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)
131     {
132         int16_t port = CA_PORT;
133         int32_t serverFd = -1;
134         /* Start Unicast server if requested earlier */
135         if (gStartUnicastServerRequested)
136         {
137             ret = CAWiFiStartUnicastServer("0.0.0.0", &port, false, &serverFd);
138             if (CA_STATUS_OK == ret)
139             {
140                 OIC_LOG_V(DEBUG, WIFI_ADAPTER_TAG, "Unicast server started on %d port", port);
141                 CAWiFiSetUnicastSocket(serverFd);
142                 gUnicastServerport = port;
143             }
144             else
145             {
146                 OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed [%d]", ret);
147             }
148         }
149
150         /* Start Multicast server if requested earlier */
151         if (gStartMulticastServerRequested)
152         {
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)
156             {
157                 OIC_LOG_V(DEBUG, WIFI_ADAPTER_TAG, "Multicast server started on %d port", multicastPort);
158                 gIsMulticastServerStarted = true;
159             }
160             else
161             {
162                 OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed [%d]", ret);
163             }
164         }
165
166         /* Notify network change to CA */
167         CAWiFiNotifyNetworkChange(ipAddr, port, status);
168     }
169     else
170     {
171         CAWiFiNotifyNetworkChange("", 0, status);
172         /* Stop both Unicast and Multicast servers */
173         ret = CAWiFiStopServers();
174         if (CA_STATUS_OK != ret)
175         {
176             OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed to Stop Servers![%d]", ret);
177             return;
178         }
179     }
180
181     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
182 }
183
184 void CAWiFiPacketReceivedCB(const char *ipAddress, const uint32_t port,
185                             const void *data, const uint32_t dataLength)
186 {
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);
190
191     /* CA is freeing this memory */
192     CARemoteEndpoint_t *endPoint = CAAdapterCreateRemoteEndpoint(CA_WIFI, ipAddress, NULL);
193     if (NULL == endPoint)
194     {
195         OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "Out of memory");
196         return;
197     }
198     endPoint->addressInfo.IP.port = port;
199
200     void *buf = OICMalloc(dataLength + 1);
201     if (NULL == buf)
202     {
203         OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "Out of memory");
204         CAAdapterFreeRemoteEndpoint(endPoint);
205         return;
206     }
207     memcpy(buf, data, dataLength);
208     memset(buf + dataLength, 0, 1);
209     if (gNetworkPacketCallback)
210     {
211         gNetworkPacketCallback(endPoint, buf, dataLength);
212     }
213     CAAdapterFreeRemoteEndpoint(endPoint);
214     OICFree(buf);
215     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
216 }
217
218 CAResult_t CAInitializeWifi(CARegisterConnectivityCallback registerCallback,
219                             CANetworkPacketReceivedCallback networkPacketCallback,
220                             CANetworkChangeCallback netCallback)
221 {
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");
226
227     gNetworkChangeCallback = netCallback;
228     gNetworkPacketCallback = networkPacketCallback;
229
230     CAResult_t ret = CAWiFiInitializeNetworkMonitor();
231     if (CA_STATUS_OK != ret)
232     {
233         OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed to initialize n/w monitor![%d]", ret);
234         return ret;
235     }
236     CAWiFiSetConnectionStateChangeCallback(CAWiFiConnectionStateCB);
237
238     // network monitor is yet to be implemented
239     ret = CAWiFiInitializeServer();
240     if (CA_STATUS_OK != ret)
241     {
242         OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed to initialize server![%d]", ret);
243         CATerminateWIfI();
244         return ret;
245     }
246     CAWiFiSetPacketReceiveCallback(CAWiFiPacketReceivedCB);
247
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);
259
260     OIC_LOG(INFO, WIFI_ADAPTER_TAG, "IntializeWifi Success");
261     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
262     return CA_STATUS_OK;
263 }
264
265 CAResult_t CAStartWIFI()
266 {
267     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
268
269     /* Start monitoring wifi network */
270     CAResult_t ret = CAWiFiStartNetworkMonitor();
271     if (CA_STATUS_OK != ret)
272     {
273         OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "Failed to Start n/w monitor");
274     }
275
276     gStartUnicastServerRequested = true;
277     bool retVal = CAWiFiIsConnected();
278     if (false == retVal)
279     {
280         OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "WIFI is not Connected");
281         return ret;
282     }
283
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)
289     {
290         OIC_LOG_V(DEBUG, WIFI_ADAPTER_TAG, "Unicast server started on %d port", unicastPort);
291         CAWiFiSetUnicastSocket(serverFd);
292         gUnicastServerport = unicastPort;
293     }
294
295     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
296     return ret;
297 }
298
299 CAResult_t CAStartWIFIListeningServer()
300 {
301     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
302
303     CAResult_t ret = CA_STATUS_OK;
304     int16_t multicastPort = CA_MCAST_PORT;
305
306     if (gIsMulticastServerStarted == true)
307     {
308         OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Multicast Server, Already Started!");
309         return CA_SERVER_STARTED_ALREADY;
310     }
311
312     gStartMulticastServerRequested = true;
313     bool retVal = CAWiFiIsConnected();
314     if (false == retVal)
315     {
316         OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed : WIFI not Connected");
317         return CA_ADAPTER_NOT_ENABLED;
318     }
319
320     ret = CAWiFiStartMulticastServer("0.0.0.0", CA_MULTICAST_IP, multicastPort, NULL);
321     if (CA_STATUS_OK == ret)
322     {
323         OIC_LOG(INFO, WIFI_ADAPTER_TAG, "Multicast Server Started Successfully");
324         gIsMulticastServerStarted = true;
325     }
326
327     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
328     return ret;
329 }
330
331 CAResult_t CAStartWIFIDiscoveryServer()
332 {
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();
337 }
338
339 uint32_t CASendWIFIUnicastData(const CARemoteEndpoint_t *remoteEndpoint, void *data,
340                                uint32_t dataLength)
341 {
342     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
343
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);
347     if (dataLength == 0)
348     {
349         OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Invalid Data Length");
350         return dataSize;
351     }
352
353     CAWiFiSendData(remoteEndpoint->addressInfo.IP.ipAddress,
354                    remoteEndpoint->addressInfo.IP.port, data, dataLength, false);
355     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
356     return dataLength;
357 }
358
359 uint32_t CASendWIFIMulticastData(void *data, uint32_t dataLength)
360 {
361     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
362
363     uint32_t dataSize = 0;
364     VERIFY_NON_NULL_RET(data, WIFI_ADAPTER_TAG, "data", dataSize);
365     if (dataLength == 0)
366     {
367         OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Invalid Data Length");
368         return dataSize;
369     }
370
371     CAWiFiSendData(CA_MULTICAST_IP, CA_MCAST_PORT, data, dataLength, true);
372     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
373     return dataLength;
374 }
375
376 CAResult_t CAGetWIFIInterfaceInformation(CALocalConnectivity_t **info, uint32_t *size)
377 {
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");
381
382     bool retVal = CAWiFiIsConnected();
383     if (false == retVal)
384     {
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;
388     }
389
390     char *ipAddress = NULL;
391     char *ifcName = NULL;
392     CAResult_t ret = CAWiFiGetInterfaceInfo(&ipAddress, &ifcName);
393     if (CA_STATUS_OK != ret)
394     {
395         OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed to get interface info [%d]", ret);
396         return ret;
397     }
398
399     // Create local endpoint using util function
400     (*info) = CAAdapterCreateLocalEndpoint(CA_WIFI, ipAddress);
401     if (NULL == (*info))
402     {
403         OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed to create Local Endpoint!",
404                   CA_MEMORY_ALLOC_FAILED);
405         OICFree(ipAddress);
406         OICFree(ifcName);
407         return CA_MEMORY_ALLOC_FAILED;
408     }
409
410     (*info)->addressInfo.IP.port = gUnicastServerport;
411     (*size) = 1;
412
413     OICFree(ipAddress);
414     OICFree(ifcName);
415
416     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
417     return CA_STATUS_OK;
418 }
419
420 CAResult_t CAReadWIFIData()
421 {
422     CAWiFiPullData();
423     return CA_STATUS_OK;
424 }
425
426 CAResult_t CAWiFiStopServers()
427 {
428     CAResult_t result = CAWiFiStopUnicastServer();
429     if (CA_STATUS_OK != result)
430     {
431         OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed to Stop Unicast Server![%d]", result);
432         return result;
433     }
434     CAWiFiSetUnicastSocket(-1);
435     gUnicastServerport = -1;
436
437     result = CAWiFiStopMulticastServer();
438     if (CA_STATUS_OK != result)
439     {
440         OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed to Stop Multicast Server![%d]", result);
441         return result;
442     }
443     gIsMulticastServerStarted = false;
444
445     return result;
446 }
447
448 CAResult_t CAStopWIFI()
449 {
450     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
451
452     gStartUnicastServerRequested = false;
453     gStartMulticastServerRequested = false;
454     CAWiFiStopNetworkMonitor();
455     CAResult_t result = CAWiFiStopServers();
456     if (CA_STATUS_OK != result)
457     {
458         OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed to Stop Servers![%d]", result);
459     }
460
461     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
462     return result;
463 }
464
465 void CATerminateWIfI()
466 {
467     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
468
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");
474     return;
475 }
476