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