API change , Retransmission Callback on expiry , remove glib source for dynamic linking
[platform/upstream/iotivity.git] / resource / csdk / connectivity / src / wifi_adapter / cawifiadapter.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.h"
21
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <stdint.h>
26
27 #include "cawifiinterface.h"
28 #include "caqueueingthread.h"
29 #include "caadapterutils.h"
30 #ifdef __WITH_DTLS__
31 #include "caadapternetdtls.h"
32 #endif
33 #include "umutex.h"
34 #include "logger.h"
35 #include "oic_malloc.h"
36
37 /**
38  * @def WIFI_ADAPTER_TAG
39  * @brief Logging tag for module name
40  */
41 #define WIFI_ADAPTER_TAG "WIFI_ADAP"
42
43 /**
44  * @def CA_PORT
45  * @brief Port to listen for incoming data. port 5683 is as per COAP RFC.
46  */
47 #define CA_PORT   5683
48
49 /**
50  * @def CA_SECURE_PORT
51  * @brief Secure port to listen for incoming data
52  */
53 #define CA_SECURE_PORT   5684
54
55 /**
56  * @def CA_MCAST_PORT
57  * @brief Multicast Port Number
58  */
59 #define CA_MCAST_PORT   5298
60
61 /**
62  * @def CA_MULTICAST_IP
63  * @brief Multicast IP Address
64  */
65 #define CA_MULTICAST_IP "224.0.1.187"
66
67
68 typedef struct
69 {
70     CARemoteEndpoint_t *remoteEndpoint;
71     void *data;
72     uint32_t dataLen;
73 } CAWiFiData;
74
75 /**
76  * @var gNetworkPacketCallback
77  * @brief Network Packet Received Callback to CA
78  */
79 static CANetworkPacketReceivedCallback gNetworkPacketCallback = NULL;
80
81 /**
82  * @var gNetworkChangeCb
83  * @brief Network Changed Callback to CA
84  */
85 static CANetworkChangeCallback gNetworkChangeCallback = NULL;
86
87 /**
88  * @var gIsMulticastServerStarted
89  * @brief Flag to check if multicast server is started
90  */
91 static bool gIsMulticastServerStarted = false;
92
93 /**
94  * @var gIsStartServerCalled
95  * @brief Flag to check if server start requested by CA.
96  */
97 static bool gStartUnicastServerRequested = false;
98
99 /**
100  * @var gUnicastServerport
101  * @brief port number on which unicast server is running.
102  */
103 static int16_t gUnicastServerport = 0;
104
105 #ifdef __WITH_DTLS__
106 /**
107  * @var gSecureUnicastServerport
108  * @brief port number on which secure unicast server is running.
109  */
110 static int16_t gSecureUnicastServerport = 0;
111 #endif
112
113 /**
114  * @var gIsStartServerCalled
115  * @brief Flag to check if server start requested by CA.
116  */
117 static bool gStartMulticastServerRequested = false;
118
119 /**
120  * @var gSendQueueHandle
121  * @brief Queue handle for Send Data
122  */
123 static CAQueueingThread_t *gSendQueueHandle = NULL;
124
125 /**
126  * @var gThreadPool
127  * @brief ThreadPool for storing u_thread_pool_t handle passed from CA
128  */
129 static u_thread_pool_t gThreadPool = NULL;
130
131 static CAResult_t CAWiFiInitializeQueueHandles();
132 static void CAWiFiDeinitializeQueueHandles();
133 static void CAWiFiNotifyNetworkChange(const char *address, const int16_t port,
134                                       const CANetworkStatus_t status);
135 static void CAWiFiConnectionStateCB(const char *ipAddress,
136                                     const CANetworkStatus_t status);
137 static void CAWiFiPacketReceivedCB(const char *ipAddress, const uint32_t port,
138                                    const void *data, const uint32_t dataLength,
139                                    const CABool_t isSecured);
140 #ifdef __WITH_DTLS__
141 static uint32_t CAWiFiPacketSendCB(const char *ipAddress, const uint32_t port,
142                                    const void *data, const uint32_t dataLength);
143 #endif
144 static CAResult_t CAWiFiStopServers();
145 static void CAWiFiSendDataThread(void *threadData);
146 static CAWiFiData *CACreateWiFiData(const CARemoteEndpoint_t *remoteEndpoint, void *data,
147                                     uint32_t dataLength);
148 void CAFreeWiFiData(CAWiFiData *wifiData);
149
150
151 CAResult_t CAWiFiInitializeQueueHandles()
152 {
153     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
154
155     // Check if the message queue is already initialized
156     if (gSendQueueHandle)
157     {
158         OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "Already queue is initialized!");
159         return CA_STATUS_OK;
160     }
161
162     // Create send message queue
163     gSendQueueHandle = OICMalloc(sizeof(CAQueueingThread_t));
164     if (!gSendQueueHandle)
165     {
166         OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "Memory allocation failed!");
167         return CA_MEMORY_ALLOC_FAILED;
168     }
169
170     if (CA_STATUS_OK != CAQueueingThreadInitialize(gSendQueueHandle, gThreadPool,
171             CAWiFiSendDataThread))
172     {
173         OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "Failed to Initialize send queue thread");
174         OICFree(gSendQueueHandle);
175         gSendQueueHandle = NULL;
176         return CA_STATUS_FAILED;
177     }
178
179     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
180     return CA_STATUS_OK;
181 }
182
183 void CAWiFiDeinitializeQueueHandles()
184 {
185     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
186
187     CAQueueingThreadDestroy(gSendQueueHandle);
188     OICFree(gSendQueueHandle);
189     gSendQueueHandle = NULL;
190
191     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
192 }
193
194 void CAWiFiNotifyNetworkChange(const char *address, const int16_t port,
195                                const CANetworkStatus_t status)
196 {
197     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
198
199     CALocalConnectivity_t *localEndpoint = CAAdapterCreateLocalEndpoint(CA_WIFI, address);
200     if (!localEndpoint)
201     {
202         OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Out of memory");
203         return;
204     }
205
206     localEndpoint->addressInfo.IP.port = port;
207     if (NULL != gNetworkChangeCallback)
208     {
209         gNetworkChangeCallback(localEndpoint, status);
210     }
211
212     CAAdapterFreeLocalEndpoint(localEndpoint);
213 }
214
215 void CAWiFiConnectionStateCB(const char *ipAddress,
216                              const CANetworkStatus_t status)
217 {
218     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
219
220     CAResult_t ret = CA_STATUS_FAILED;
221
222     /**
223      * If Wifi is connected, then get the latest IP from the WIFI Interface
224      * and start unicast and multicast servers if requested earlier
225      */
226     if (CA_INTERFACE_UP == status)
227     {
228         int16_t port = CA_PORT;
229         int32_t serverFd = -1;
230
231         // Start Unicast server if requested earlier
232         if (gStartUnicastServerRequested)
233         {
234             ret = CAWiFiStartUnicastServer("0.0.0.0", &port, false, false, &serverFd);
235             if (CA_STATUS_OK == ret)
236             {
237                 OIC_LOG_V(DEBUG, WIFI_ADAPTER_TAG, "Unicast server started on %d port", port);
238                 CAWiFiSetUnicastSocket(serverFd);
239                 gUnicastServerport = port;
240             }
241             else
242             {
243                 OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed to start Unicast server [%d]", ret);
244             }
245
246 #ifdef __WITH_DTLS__
247             port = CA_SECURE_PORT;
248             ret = CAWiFiStartUnicastServer("0.0.0.0", &port, false, true, &serverFd);
249             if (CA_STATUS_OK == ret)
250             {
251                 OIC_LOG_V(DEBUG, WIFI_ADAPTER_TAG, "Secure Unicast server started on %d", port);
252                 CAWiFiSetSecureUnicastSocket(serverFd);
253                 gSecureUnicastServerport = port;
254             }
255             else
256             {
257                 OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed to start secure Unicast server [%d]",
258                           ret);
259             }
260 #endif
261         }
262
263         // Start Multicast server if requested earlier
264         if (gStartMulticastServerRequested)
265         {
266             int16_t multicastPort = CA_MCAST_PORT;
267             int32_t multicastFd = 0;
268             ret = CAWiFiStartMulticastServer("0.0.0.0", CA_MULTICAST_IP, multicastPort,
269                                              &multicastFd);
270             if (CA_STATUS_OK == ret)
271             {
272                 OIC_LOG_V(DEBUG, WIFI_ADAPTER_TAG, "Multicast server started on %d port",
273                           multicastPort);
274                 gIsMulticastServerStarted = true;
275             }
276             else
277             {
278                 OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed to start Multicast server [%d]", ret);
279             }
280         }
281
282         char *address = NULL;
283         char *ifcName = NULL;
284         ret = CAWiFiGetInterfaceInfo(&ifcName, &address);
285         if (CA_STATUS_OK != ret || NULL == address)
286         {
287             OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed to get interface info [%d]", ret);
288             if(address)
289             {
290                 OICFree(address);
291             }
292             if(ifcName)
293             {
294                 OICFree(ifcName);
295             }
296             return;
297         }
298
299         // Notify network change to CA
300         CAWiFiNotifyNetworkChange(address, port, status);
301         if(address)
302         {
303             OICFree(address);
304         }
305         if(ifcName)
306         {
307             OICFree(ifcName);
308         }
309     }
310     else
311     {
312         CAWiFiNotifyNetworkChange("", 0, status);
313
314         // Stop Unicast, Secured unicast and Multicast servers
315         CAWiFiStopServers();
316     }
317
318     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
319 }
320
321 #ifdef __WITH_DTLS__
322 uint32_t CAWiFiPacketSendCB(const char *ipAddress, const uint32_t port,
323                             const void *data, const uint32_t dataLength)
324 {
325     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
326
327     uint32_t sentLength = CAWiFiSendData(ipAddress, port, data, dataLength, CA_FALSE, CA_TRUE);
328
329     OIC_LOG_V(DEBUG, WIFI_ADAPTER_TAG, "Successfully sent %d of encripted data!", sentLength);
330
331     return sentLength;
332 }
333 #endif
334
335 void CAWiFiPacketReceivedCB(const char *ipAddress, const uint32_t port,
336                             const void *data, const uint32_t dataLength, const CABool_t isSecured)
337 {
338     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
339     OIC_LOG_V(DEBUG, WIFI_ADAPTER_TAG, "Address: %s, port:%d, data:%s", ipAddress, port, data);
340
341     // CA is freeing this memory
342     CARemoteEndpoint_t *endPoint = CAAdapterCreateRemoteEndpoint(CA_WIFI, ipAddress, NULL);
343     if (NULL == endPoint)
344     {
345         OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "Out of memory");
346         return;
347     }
348     endPoint->addressInfo.IP.port = port;
349     endPoint->isSecured = isSecured;
350
351     void *buf = OICMalloc(dataLength + 1);
352     if (NULL == buf)
353     {
354         OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "Out of memory");
355         CAAdapterFreeRemoteEndpoint(endPoint);
356         return;
357     }
358     memcpy(buf, data, dataLength);
359     memset(buf + dataLength, 0, 1);
360     if (gNetworkPacketCallback)
361     {
362         gNetworkPacketCallback(endPoint, buf, dataLength);
363     }
364     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
365 }
366
367 CAResult_t CAInitializeWifi(CARegisterConnectivityCallback registerCallback,
368                             CANetworkPacketReceivedCallback networkPacketCallback,
369                             CANetworkChangeCallback netCallback, u_thread_pool_t handle)
370 {
371     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
372     VERIFY_NON_NULL(registerCallback, WIFI_ADAPTER_TAG, "registerCallback");
373     VERIFY_NON_NULL(networkPacketCallback, WIFI_ADAPTER_TAG, "networkPacketCallback");
374     VERIFY_NON_NULL(netCallback, WIFI_ADAPTER_TAG, "netCallback");
375     VERIFY_NON_NULL(handle, WIFI_ADAPTER_TAG, "thread pool handle");
376
377     gThreadPool  = handle;
378     gNetworkChangeCallback = netCallback;
379     gNetworkPacketCallback = networkPacketCallback;
380
381     CAResult_t ret = CAWiFiInitializeNetworkMonitor(gThreadPool);
382     if (CA_STATUS_OK != ret)
383     {
384         OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed to initialize n/w monitor![%d]", ret);
385         return ret;
386     }
387     CAWiFiSetConnectionStateChangeCallback(CAWiFiConnectionStateCB);
388
389     ret = CAWiFiInitializeServer(gThreadPool);
390     if (CA_STATUS_OK != ret)
391     {
392         OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed to initialize server![%d]", ret);
393         CATerminateWIfI();
394         return ret;
395     }
396
397     CAWiFiSetPacketReceiveCallback(CAWiFiPacketReceivedCB);
398 #ifdef __WITH_DTLS__
399     CAAdapterNetDtlsInit();
400     CADTLSSetAdapterCallbacks(CAWiFiPacketReceivedCB, CAWiFiPacketSendCB, DTLS_WIFI);
401 #endif
402
403     CAConnectivityHandler_t wifiHandler;
404     wifiHandler.startAdapter = CAStartWIFI;
405     wifiHandler.startListenServer = CAStartWIFIListeningServer;
406     wifiHandler.startDiscoverServer = CAStartWIFIDiscoveryServer;
407     wifiHandler.sendData = CASendWIFIUnicastData;
408     wifiHandler.sendDataToAll = CASendWIFIMulticastData;
409     wifiHandler.GetnetInfo = CAGetWIFIInterfaceInformation;
410     wifiHandler.readData = CAReadWIFIData;
411     wifiHandler.stopAdapter = CAStopWIFI;
412     wifiHandler.terminate = CATerminateWIfI;
413     registerCallback(wifiHandler, CA_WIFI);
414
415     if (CA_STATUS_OK != CAWiFiInitializeQueueHandles())
416     {
417         OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "Failed to Initialize Queue Handle");
418         CATerminateWIfI();
419         return CA_STATUS_FAILED;
420     }
421
422     OIC_LOG(INFO, WIFI_ADAPTER_TAG, "IntializeWifi is Success");
423     return CA_STATUS_OK;
424 }
425
426 CAResult_t CAStartWIFI()
427 {
428     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
429
430     // Start monitoring wifi network
431     CAResult_t ret = CAWiFiStartNetworkMonitor();
432     if (CA_STATUS_OK != ret)
433     {
434         OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "Failed to Start n/w monitor");
435     }
436
437     // Start send queue thread
438     if (CA_STATUS_OK != CAQueueingThreadStart(gSendQueueHandle))
439     {
440         OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "Failed to Start Send Data Thread");
441         return CA_STATUS_FAILED;
442     }
443
444     gStartUnicastServerRequested = true;
445     bool retVal = CAWiFiIsConnected();
446     if (false == retVal)
447     {
448         OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "WIFI is not Connected");
449         return CA_STATUS_OK;
450     }
451
452     char *ifcName = NULL;
453     char *ifcAdrs = NULL;
454     ret = CAWiFiGetInterfaceInfo(&ifcName, &ifcAdrs);
455     if (CA_STATUS_OK != ret)
456     {
457         OIC_LOG_V(DEBUG, WIFI_ADAPTER_TAG, "Failed to get wifi interface info [%d]", ret);
458         return ret;
459     }
460
461     int16_t unicastPort = CA_PORT;
462     int32_t serverFd = 0;
463     // Address is hardcoded as we are using Single Interface
464     ret = CAWiFiStartUnicastServer(ifcAdrs, &unicastPort, false, false, &serverFd);
465     if (CA_STATUS_OK == ret)
466     {
467         OIC_LOG_V(DEBUG, WIFI_ADAPTER_TAG, "Unicast server started on %d port", unicastPort);
468         CAWiFiSetUnicastSocket(serverFd);
469         gUnicastServerport = unicastPort;
470     }
471
472 #ifdef __WITH_DTLS__
473     // Address is hardcoded as we are using Single Interface
474     unicastPort = CA_SECURE_PORT;
475     ret = CAWiFiStartUnicastServer(ifcAdrs, &unicastPort, false, true, &serverFd);
476     if (CA_STATUS_OK == ret)
477     {
478         OIC_LOG_V(DEBUG, WIFI_ADAPTER_TAG, "Secure Unicast server started on %d port", unicastPort);
479         CAWiFiSetSecureUnicastSocket(serverFd);
480         gSecureUnicastServerport = unicastPort;
481     }
482 #endif
483     if(ifcName)
484     {
485          OICFree(ifcName);
486     }
487     if(ifcAdrs)
488     {
489          OICFree(ifcAdrs);
490     }
491     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
492     return ret;
493 }
494
495 CAResult_t CAStartWIFIListeningServer()
496 {
497     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
498
499     CAResult_t ret = CA_STATUS_OK;
500     int16_t multicastPort = CA_MCAST_PORT;
501
502     if (gIsMulticastServerStarted == true)
503     {
504         OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG,
505                   "Failed to Start Multicast Server, Already Started!");
506         return CA_SERVER_STARTED_ALREADY;
507     }
508
509     gStartMulticastServerRequested = true;
510     bool retVal = CAWiFiIsConnected();
511     if (false == retVal)
512     {
513         OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG,
514                   "Failed to Start Multicast Server, WIFI not Connected");
515         return CA_STATUS_OK;
516     }
517
518     char *ifcName = NULL;
519     char *ifcAdrs = NULL;
520     ret = CAWiFiGetInterfaceInfo(&ifcName, &ifcAdrs);
521     if (CA_STATUS_OK != ret)
522     {
523         OIC_LOG_V(DEBUG, WIFI_ADAPTER_TAG, "Failed to get wifi interface info [%d]", ret);
524         return ret;
525     }
526
527     int32_t multicastFd = 0;
528     ret = CAWiFiStartMulticastServer(ifcAdrs, CA_MULTICAST_IP, multicastPort, &multicastFd);
529     if (CA_STATUS_OK == ret)
530     {
531         OIC_LOG(INFO, WIFI_ADAPTER_TAG, "Multicast Server is Started Successfully");
532         gIsMulticastServerStarted = true;
533     }
534
535     if(ifcName)
536     {
537          OICFree(ifcName);
538     }
539     if(ifcAdrs)
540     {
541         OICFree(ifcAdrs);
542     }
543     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
544     return ret;
545 }
546
547 CAResult_t CAStartWIFIDiscoveryServer()
548 {
549     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
550     return CAStartWIFIListeningServer();
551 }
552
553 uint32_t CASendWIFIUnicastData(const CARemoteEndpoint_t *remoteEndpoint, void *data,
554                                uint32_t dataLength)
555 {
556     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
557
558     uint32_t dataSize = 0;
559     VERIFY_NON_NULL_RET(remoteEndpoint, WIFI_ADAPTER_TAG, "remoteEndpoint", dataSize);
560     VERIFY_NON_NULL_RET(data, WIFI_ADAPTER_TAG, "data", dataSize);
561     VERIFY_NON_NULL_RET(gSendQueueHandle, WIFI_ADAPTER_TAG, "sendQueueHandle", dataSize);
562
563     if (0 == dataLength)
564     {
565         OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Invalid Data Length");
566         return dataSize;
567     }
568
569     // Create WifiData to add to queue
570     CAWiFiData *wifiData = CACreateWiFiData(remoteEndpoint, data, dataLength);
571     if (!wifiData)
572     {
573         OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed to create wifidata!");
574         return CA_MEMORY_ALLOC_FAILED;
575     }
576
577     // Add message to send queue
578     CAQueueingThreadAddData(gSendQueueHandle, wifiData, sizeof(CAWiFiData));
579
580     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
581     return dataLength;
582 }
583
584 uint32_t CASendWIFIMulticastData(void *data, uint32_t dataLength)
585 {
586     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
587
588     uint32_t dataSize = 0;
589     VERIFY_NON_NULL_RET(data, WIFI_ADAPTER_TAG, "data", dataSize);
590     VERIFY_NON_NULL_RET(gSendQueueHandle, WIFI_ADAPTER_TAG, "sendQueueHandle", dataSize);
591
592     if (0 == dataLength)
593     {
594         OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Invalid Data Length");
595         return dataSize;
596     }
597
598     // Create WifiData to add to queue
599     CAWiFiData *wifiData = CACreateWiFiData(NULL, data, dataLength);
600     if (!wifiData)
601     {
602         OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed to create wifidata!");
603         return CA_MEMORY_ALLOC_FAILED;
604     }
605
606     // Add message to send queue
607     CAQueueingThreadAddData(gSendQueueHandle, wifiData, sizeof(CAWiFiData));
608
609     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
610     return dataLength;
611 }
612
613 CAResult_t CAGetWIFIInterfaceInformation(CALocalConnectivity_t **info, uint32_t *size)
614 {
615     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
616     VERIFY_NON_NULL(info, WIFI_ADAPTER_TAG, "info");
617     VERIFY_NON_NULL(size, WIFI_ADAPTER_TAG, "size");
618
619     CALocalConnectivity_t *netInfo = NULL;
620     bool retVal = CAWiFiIsConnected();
621     if (false == retVal)
622     {
623         OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG,
624                   "Failed to get interface address, WIFI not Connected", CA_ADAPTER_NOT_ENABLED);
625         return CA_ADAPTER_NOT_ENABLED;
626     }
627
628     int32_t netInfoSize = 1;
629 #ifdef __WITH_DTLS__
630     if (gSecureUnicastServerport)
631     {
632         netInfoSize = 2;
633     }
634 #endif
635     netInfo = (CALocalConnectivity_t *) OICMalloc(sizeof(CALocalConnectivity_t) * netInfoSize);
636     VERIFY_NON_NULL_RET(netInfo, WIFI_ADAPTER_TAG, "malloc failed", CA_MEMORY_ALLOC_FAILED);
637     memset(netInfo, 0, sizeof(CALocalConnectivity_t) * netInfoSize);
638
639     char *ipAddress = NULL;
640     char *ifcName = NULL;
641     CAResult_t ret = CAWiFiGetInterfaceInfo(&ifcName, &ipAddress);
642     if (CA_STATUS_OK != ret || NULL == ipAddress)
643     {
644         OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed to get interface info [%d]", ret);
645
646         if(netInfo)
647         {
648             OICFree(netInfo);
649         }
650         if(ipAddress)
651         {
652             OICFree(ipAddress);
653         }
654         if(ifcName)
655         {
656             OICFree(ifcName);
657         }
658         return ret;
659     }
660
661     // Create local endpoint using util function
662     CALocalConnectivity_t *endpoint = CAAdapterCreateLocalEndpoint(CA_WIFI, ipAddress);
663     if (NULL == endpoint)
664     {
665         OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed to create Local Endpoint!",
666                   CA_MEMORY_ALLOC_FAILED);
667         if(netInfo)
668         {
669             OICFree(netInfo);
670         }
671         if(ipAddress)
672         {
673             OICFree(ipAddress);
674         }
675         if(ifcName)
676         {
677             OICFree(ifcName);
678         }
679         return CA_MEMORY_ALLOC_FAILED;
680     }
681
682     // copy unciast server information
683     endpoint->isSecured = CA_FALSE;
684     endpoint->addressInfo.IP.port = gUnicastServerport;
685     memcpy(&netInfo[0], endpoint, sizeof(CALocalConnectivity_t));
686     *size = 1;
687 #ifdef __WITH_DTLS__
688     // copy sevure unicast server information
689     if (gSecureUnicastServerport)
690     {
691         endpoint->isSecured = CA_TRUE;
692         endpoint->addressInfo.IP.port = gSecureUnicastServerport;
693         memcpy(&netInfo[1], endpoint, sizeof(CALocalConnectivity_t));
694         *size = 2;
695     }
696 #endif
697     *info = netInfo;
698
699     if(ipAddress)
700     {
701         OICFree(ipAddress);
702     }
703     if(ifcName)
704     {
705         OICFree(ifcName);
706     }
707     CAAdapterFreeLocalEndpoint(endpoint);
708
709     OIC_LOG(INFO, WIFI_ADAPTER_TAG, "GetWIFIInterfaceInformation success");
710     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
711     return CA_STATUS_OK;
712 }
713
714 CAResult_t CAReadWIFIData()
715 {
716     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
717     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
718     return CA_STATUS_OK;
719 }
720
721 CAResult_t CAWiFiStopServers()
722 {
723     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
724
725     // Stop unicast server and set client socket accordingly
726     if (CA_STATUS_OK == CAWiFiStopUnicastServer())
727     {
728         CAWiFiSetUnicastSocket(-1);
729         gUnicastServerport = -1;
730     }
731 #ifdef __WITH_DTLS__
732     // Stop secure unicast server and set client socket accordingly
733     if (CA_STATUS_OK == CAWiFiStopSecureUnicastServer())
734     {
735         CAWiFiSetSecureUnicastSocket(-1);
736         gSecureUnicastServerport = -1;
737     }
738 #endif
739
740     //Stop multicast server and set the state accordingly
741     if (CA_STATUS_OK != CAWiFiStopMulticastServer())
742     {
743         gIsMulticastServerStarted = false;
744     }
745
746     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
747     return CA_STATUS_OK;
748 }
749
750 CAResult_t CAStopWIFI()
751 {
752     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
753
754     gStartUnicastServerRequested = false;
755     gStartMulticastServerRequested = false;
756
757     // Stop wifi network monitor
758     CAWiFiStopNetworkMonitor();
759
760     // Stop send queue thread
761     if (gSendQueueHandle && CA_FALSE == gSendQueueHandle->isStop)
762     {
763         CAQueueingThreadStop(gSendQueueHandle);
764     }
765
766     // Stop Unicast, Secured unicast and Multicast servers running
767     CAWiFiStopServers();
768
769     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
770     return CA_STATUS_OK;
771 }
772
773 void CATerminateWIfI()
774 {
775     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
776
777 #ifdef __WITH_DTLS__
778     CADTLSSetAdapterCallbacks(NULL, NULL, DTLS_WIFI);
779     CAAdapterNetDtlsDeInit();
780 #endif
781
782     // Stop wifi adapter
783     CAStopWIFI();
784
785     // Terminate wifi server
786     CAWiFiTerminateServer();
787
788     // Terminate network monitor
789     CAWiFiSetConnectionStateChangeCallback(NULL);
790     CAWiFiTerminateNetworkMonitor();
791
792     // Terminate message queue handler
793     CAWiFiDeinitializeQueueHandles();
794
795     CAWiFiSetPacketReceiveCallback(NULL);
796
797     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
798     return;
799 }
800
801 void CAWiFiSendDataThread(void *threadData)
802 {
803     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
804
805     CAWiFiData *wifiData = (CAWiFiData *) threadData;
806     if (!wifiData)
807     {
808         OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "Invalid wifidata!");
809         return;
810     }
811
812     if (NULL != wifiData->remoteEndpoint)
813     {
814         char *address = wifiData->remoteEndpoint->addressInfo.IP.ipAddress;
815         uint32_t port = wifiData->remoteEndpoint->addressInfo.IP.port;
816
817 #ifdef __WITH_DTLS__
818         if (!wifiData->remoteEndpoint->isSecured)
819         {
820             CAWiFiSendData(address, port, wifiData->data, wifiData->dataLen, false,
821                            wifiData->remoteEndpoint->isSecured);
822         }
823         else
824         {
825             OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "CAAdapterNetDtlsEncrypt called!");
826             uint8_t cacheFalg = 0;
827             CAResult_t  result = CAAdapterNetDtlsEncrypt(address, port, wifiData->data,
828                                  wifiData->dataLen, &cacheFalg, DTLS_WIFI);
829
830             if (CA_STATUS_OK != result)
831             {
832                 OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "CAAdapterNetDtlsEncrypt failed!");
833             }
834             OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "CAAdapterNetDtlsEncrypt returned with cache[%d]",
835                       cacheFalg);
836         }
837 #else
838         CAWiFiSendData(address, port, wifiData->data, wifiData->dataLen, false,
839                        wifiData->remoteEndpoint->isSecured);
840 #endif
841     }
842     else
843     {
844         OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "Send Multicast Data is called");
845         CAWiFiSendData(CA_MULTICAST_IP, CA_MCAST_PORT, wifiData->data,
846                        wifiData->dataLen, true, false);
847     }
848
849     //Free wifi data
850     CAFreeWiFiData(wifiData);
851
852     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
853     return;
854 }
855
856 CAWiFiData *CACreateWiFiData(const CARemoteEndpoint_t *remoteEndpoint, void *data,
857                              uint32_t dataLength)
858 {
859     CAWiFiData *wifiData = (CAWiFiData *) OICMalloc(sizeof(CAWiFiData));
860     if (!wifiData)
861     {
862         OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "Memory allocation failed!");
863         return NULL;
864     }
865
866     wifiData->remoteEndpoint = CAAdapterCopyRemoteEndpoint(remoteEndpoint);
867     wifiData->data = (void *)OICMalloc(dataLength);
868     if (NULL == wifiData->data)
869     {
870         OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "Memory allocation failed!");
871         CAFreeWiFiData(wifiData);
872         return NULL;
873     }
874     memcpy(wifiData->data, data, dataLength);
875     wifiData->dataLen = dataLength;
876
877     return wifiData;
878 }
879
880 void CAFreeWiFiData(CAWiFiData *wifiData)
881 {
882     if (!wifiData)
883         return;
884
885     CAAdapterFreeRemoteEndpoint(wifiData->remoteEndpoint);
886     OICFree(wifiData->data);
887     OICFree(wifiData);
888 }