9c5fd96241c1a58a496a92bd74b088d2f0d8743d
[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             OICFree(address);
289             OICFree(ifcName);
290             return;
291         }
292
293         // Notify network change to CA
294         CAWiFiNotifyNetworkChange(address, port, status);
295         OICFree(address);
296         OICFree(ifcName);
297     }
298     else
299     {
300         CAWiFiNotifyNetworkChange("", 0, status);
301
302         // Stop Unicast, Secured unicast and Multicast servers
303         CAWiFiStopServers();
304     }
305
306     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
307 }
308
309 #ifdef __WITH_DTLS__
310 uint32_t CAWiFiPacketSendCB(const char *ipAddress, const uint32_t port,
311                                  const void *data, const uint32_t dataLength)
312 {
313     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
314
315     uint32_t sentLength = CAWiFiSendData(ipAddress, port, data, dataLength, CA_FALSE, CA_TRUE);
316
317     OIC_LOG_V(DEBUG, WIFI_ADAPTER_TAG, "Successfully sent %d of encripted data!", sentLength);
318
319     return sentLength;
320 }
321 #endif
322
323 void CAWiFiPacketReceivedCB(const char *ipAddress, const uint32_t port,
324                             const void *data, const uint32_t dataLength, const CABool_t isSecured)
325 {
326     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
327     OIC_LOG_V(DEBUG, WIFI_ADAPTER_TAG, "Address: %s, port:%d, data:%s", ipAddress, port, data);
328
329     // CA is freeing this memory
330     CARemoteEndpoint_t *endPoint = CAAdapterCreateRemoteEndpoint(CA_WIFI, ipAddress, NULL);
331     if (NULL == endPoint)
332     {
333         OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "Out of memory");
334         return;
335     }
336     endPoint->addressInfo.IP.port = port;
337     endPoint->isSecured = isSecured;
338
339     void *buf = OICMalloc(dataLength + 1);
340     if (NULL == buf)
341     {
342         OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "Out of memory");
343         CAAdapterFreeRemoteEndpoint(endPoint);
344         return;
345     }
346     memcpy(buf, data, dataLength);
347     memset(buf + dataLength, 0, 1);
348     if (gNetworkPacketCallback)
349     {
350         gNetworkPacketCallback(endPoint, buf, dataLength);
351     }
352     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
353 }
354
355 CAResult_t CAInitializeWifi(CARegisterConnectivityCallback registerCallback,
356                             CANetworkPacketReceivedCallback networkPacketCallback,
357                             CANetworkChangeCallback netCallback, u_thread_pool_t handle)
358 {
359     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
360     VERIFY_NON_NULL(registerCallback, WIFI_ADAPTER_TAG, "registerCallback");
361     VERIFY_NON_NULL(networkPacketCallback, WIFI_ADAPTER_TAG, "networkPacketCallback");
362     VERIFY_NON_NULL(netCallback, WIFI_ADAPTER_TAG, "netCallback");
363     VERIFY_NON_NULL(handle, WIFI_ADAPTER_TAG, "thread pool handle");
364
365     gThreadPool  = handle;
366     gNetworkChangeCallback = netCallback;
367     gNetworkPacketCallback = networkPacketCallback;
368
369     CAResult_t ret = CAWiFiInitializeNetworkMonitor(gThreadPool);
370     if (CA_STATUS_OK != ret)
371     {
372         OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed to initialize n/w monitor![%d]", ret);
373         return ret;
374     }
375     CAWiFiSetConnectionStateChangeCallback(CAWiFiConnectionStateCB);
376
377     ret = CAWiFiInitializeServer(gThreadPool);
378     if (CA_STATUS_OK != ret)
379     {
380         OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed to initialize server![%d]", ret);
381         CATerminateWIfI();
382         return ret;
383     }
384
385     CAWiFiSetPacketReceiveCallback(CAWiFiPacketReceivedCB);
386 #ifdef __WITH_DTLS__
387     CAAdapterNetDtlsInit();
388     CADTLSSetAdapterCallbacks(CAWiFiPacketReceivedCB, CAWiFiPacketSendCB, DTLS_WIFI);
389 #endif
390
391     CAConnectivityHandler_t wifiHandler;
392     wifiHandler.startAdapter = CAStartWIFI;
393     wifiHandler.startListenServer = CAStartWIFIListeningServer;
394     wifiHandler.startDiscoverServer = CAStartWIFIDiscoveryServer;
395     wifiHandler.sendData = CASendWIFIUnicastData;
396     wifiHandler.sendDataToAll = CASendWIFIMulticastData;
397     wifiHandler.GetnetInfo = CAGetWIFIInterfaceInformation;
398     wifiHandler.readData = CAReadWIFIData;
399     wifiHandler.stopAdapter = CAStopWIFI;
400     wifiHandler.terminate = CATerminateWIfI;
401     registerCallback(wifiHandler, CA_WIFI);
402
403     if (CA_STATUS_OK != CAWiFiInitializeQueueHandles())
404     {
405         OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "Failed to Initialize Queue Handle");
406         CATerminateWIfI();
407         return CA_STATUS_FAILED;
408     }
409
410     OIC_LOG(INFO, WIFI_ADAPTER_TAG, "IntializeWifi is Success");
411     return CA_STATUS_OK;
412 }
413
414 CAResult_t CAStartWIFI()
415 {
416     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
417
418     // Start monitoring wifi network
419     CAResult_t ret = CAWiFiStartNetworkMonitor();
420     if (CA_STATUS_OK != ret)
421     {
422         OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "Failed to Start n/w monitor");
423     }
424
425     // Start send queue thread
426     if (CA_STATUS_OK != CAQueueingThreadStart(gSendQueueHandle))
427     {
428         OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "Failed to Start Send Data Thread");
429         return CA_STATUS_FAILED;
430     }
431
432     gStartUnicastServerRequested = true;
433     bool retVal = CAWiFiIsConnected();
434     if (false == retVal)
435     {
436         OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "WIFI is not Connected");
437         return CA_STATUS_OK;
438     }
439
440     char *ifcName;
441     char *ifcAdrs;
442     ret = CAWiFiGetInterfaceInfo(&ifcName, &ifcAdrs);
443     if(CA_STATUS_OK != ret)
444     {
445         OIC_LOG_V(DEBUG, WIFI_ADAPTER_TAG, "Failed to get wifi interface info [%d]", ret);
446         return ret;
447     }
448
449     int16_t unicastPort = CA_PORT;
450     int32_t serverFd = 0;
451     // Address is hardcoded as we are using Single Interface
452     ret = CAWiFiStartUnicastServer(ifcAdrs, &unicastPort, false, false, &serverFd);
453     if (CA_STATUS_OK == ret)
454     {
455         OIC_LOG_V(DEBUG, WIFI_ADAPTER_TAG, "Unicast server started on %d port", unicastPort);
456         CAWiFiSetUnicastSocket(serverFd);
457         gUnicastServerport = unicastPort;
458     }
459
460 #ifdef __WITH_DTLS__
461     // Address is hardcoded as we are using Single Interface
462     unicastPort = CA_SECURE_PORT;
463     ret = CAWiFiStartUnicastServer(ifcAdrs, &unicastPort, false, true, &serverFd);
464     if (CA_STATUS_OK == ret)
465     {
466         OIC_LOG_V(DEBUG, WIFI_ADAPTER_TAG, "Secure Unicast server started on %d port", unicastPort);
467         CAWiFiSetSecureUnicastSocket(serverFd);
468         gSecureUnicastServerport = unicastPort;
469     }
470 #endif
471     OICFree(ifcName);
472     OICFree(ifcAdrs);
473     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
474     return ret;;
475 }
476
477 CAResult_t CAStartWIFIListeningServer()
478 {
479     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
480
481     CAResult_t ret = CA_STATUS_OK;
482     int16_t multicastPort = CA_MCAST_PORT;
483
484     if (gIsMulticastServerStarted == true)
485     {
486         OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG,
487                   "Failed to Start Multicast Server, Already Started!");
488         return CA_SERVER_STARTED_ALREADY;
489     }
490
491     gStartMulticastServerRequested = true;
492     bool retVal = CAWiFiIsConnected();
493     if (false == retVal)
494     {
495         OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG,
496                   "Failed to Start Multicast Server, WIFI not Connected");
497         return CA_STATUS_OK;
498     }
499
500     char *ifcName;
501     char *ifcAdrs;
502     ret = CAWiFiGetInterfaceInfo(&ifcName, &ifcAdrs);
503     if(CA_STATUS_OK != ret)
504     {
505         OIC_LOG_V(DEBUG, WIFI_ADAPTER_TAG, "Failed to get wifi interface info [%d]", ret);
506         return ret;
507     }
508
509     int32_t multicastFd = 0;
510     ret = CAWiFiStartMulticastServer(ifcAdrs, CA_MULTICAST_IP, multicastPort, &multicastFd);
511     if (CA_STATUS_OK == ret)
512     {
513         OIC_LOG(INFO, WIFI_ADAPTER_TAG, "Multicast Server is Started Successfully");
514         gIsMulticastServerStarted = true;
515     }
516
517     OICFree(ifcName);
518     OICFree(ifcAdrs);
519     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
520     return ret;
521 }
522
523 CAResult_t CAStartWIFIDiscoveryServer()
524 {
525     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
526     return CAStartWIFIListeningServer();
527 }
528
529 uint32_t CASendWIFIUnicastData(const CARemoteEndpoint_t *remoteEndpoint, void *data,
530                                uint32_t dataLength)
531 {
532     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
533
534     uint32_t dataSize = 0;
535     VERIFY_NON_NULL_RET(remoteEndpoint, WIFI_ADAPTER_TAG, "remoteEndpoint", dataSize);
536     VERIFY_NON_NULL_RET(data, WIFI_ADAPTER_TAG, "data", dataSize);
537     VERIFY_NON_NULL_RET(gSendQueueHandle, WIFI_ADAPTER_TAG, "sendQueueHandle", dataSize);
538
539     if (0 == dataLength)
540     {
541         OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Invalid Data Length");
542         return dataSize;
543     }
544
545     // Create WifiData to add to queue
546     CAWiFiData *wifiData = CACreateWiFiData(remoteEndpoint, data, dataLength);
547     if (!wifiData)
548     {
549         OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed to create wifidata!");
550         return CA_MEMORY_ALLOC_FAILED;
551     }
552
553     // Add message to send queue
554     CAQueueingThreadAddData(gSendQueueHandle, wifiData, sizeof(CAWiFiData));
555
556     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
557     return dataLength;
558 }
559
560 uint32_t CASendWIFIMulticastData(void *data, uint32_t dataLength)
561 {
562     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
563
564     uint32_t dataSize = 0;
565     VERIFY_NON_NULL_RET(data, WIFI_ADAPTER_TAG, "data", dataSize);
566     VERIFY_NON_NULL_RET(gSendQueueHandle, WIFI_ADAPTER_TAG, "sendQueueHandle", dataSize);
567
568     if (0 == dataLength)
569     {
570         OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Invalid Data Length");
571         return dataSize;
572     }
573
574     // Create WifiData to add to queue
575     CAWiFiData *wifiData = CACreateWiFiData(NULL, data, dataLength);
576     if (!wifiData)
577     {
578         OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed to create wifidata!");
579         return CA_MEMORY_ALLOC_FAILED;
580     }
581
582     // Add message to send queue
583     CAQueueingThreadAddData(gSendQueueHandle, wifiData, sizeof(CAWiFiData));
584
585     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
586     return dataLength;
587 }
588
589 CAResult_t CAGetWIFIInterfaceInformation(CALocalConnectivity_t **info, uint32_t *size)
590 {
591     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
592     VERIFY_NON_NULL(info, WIFI_ADAPTER_TAG, "info");
593     VERIFY_NON_NULL(size, WIFI_ADAPTER_TAG, "size");
594
595     CALocalConnectivity_t *netInfo = NULL;
596     bool retVal = CAWiFiIsConnected();
597     if (false == retVal)
598     {
599         OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG,
600                   "Failed to get interface address, WIFI not Connected", CA_ADAPTER_NOT_ENABLED);
601         return CA_ADAPTER_NOT_ENABLED;
602     }
603
604     int32_t netInfoSize = 1;
605 #ifdef __WITH_DTLS__
606     if (gSecureUnicastServerport)
607     {
608         netInfoSize = 2;
609     }
610 #endif
611     netInfo = (CALocalConnectivity_t *) OICMalloc(sizeof(CALocalConnectivity_t) * netInfoSize);
612     VERIFY_NON_NULL_RET(netInfo, WIFI_ADAPTER_TAG, "malloc failed", CA_MEMORY_ALLOC_FAILED);
613     memset(netInfo, 0, sizeof(CALocalConnectivity_t) * netInfoSize);
614
615     char *ipAddress = NULL;
616     char *ifcName = NULL;
617     CAResult_t ret = CAWiFiGetInterfaceInfo(&ifcName, &ipAddress);
618     if (CA_STATUS_OK != ret || NULL == ipAddress)
619     {
620         OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed to get interface info [%d]", ret);
621
622         OICFree(netInfo);
623         OICFree(ipAddress);
624         OICFree(ifcName);
625         return ret;
626     }
627
628     // Create local endpoint using util function
629     CALocalConnectivity_t *endpoint = CAAdapterCreateLocalEndpoint(CA_WIFI, ipAddress);
630     if (NULL == endpoint)
631     {
632         OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed to create Local Endpoint!",
633                   CA_MEMORY_ALLOC_FAILED);
634         OICFree(netInfo);
635         OICFree(ipAddress);
636         OICFree(ifcName);
637         return CA_MEMORY_ALLOC_FAILED;
638     }
639
640     // copy unciast server information
641     endpoint->isSecured = CA_FALSE;
642     endpoint->addressInfo.IP.port = gUnicastServerport;
643     memcpy(&netInfo[0], endpoint, sizeof(CALocalConnectivity_t));
644     *size = 1;
645 #ifdef __WITH_DTLS__
646     // copy sevure unicast server information
647     if (gSecureUnicastServerport)
648     {
649         endpoint->isSecured = CA_TRUE;
650         endpoint->addressInfo.IP.port = gSecureUnicastServerport;
651         memcpy(&netInfo[1], endpoint, sizeof(CALocalConnectivity_t));
652         *size = 2;
653     }
654 #endif
655     *info = netInfo;
656
657     OICFree(ipAddress);
658     OICFree(ifcName);
659     CAAdapterFreeLocalEndpoint(endpoint);
660
661     OIC_LOG(INFO, WIFI_ADAPTER_TAG, "GetWIFIInterfaceInformation success");
662     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
663     return CA_STATUS_OK;
664 }
665
666 CAResult_t CAReadWIFIData()
667 {
668     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
669     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
670     return CA_STATUS_OK;
671 }
672
673 CAResult_t CAWiFiStopServers()
674 {
675     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
676
677     // Stop unicast server and set client socket accordingly
678     if (CA_STATUS_OK == CAWiFiStopUnicastServer())
679     {
680         CAWiFiSetUnicastSocket(-1);
681         gUnicastServerport = -1;
682     }
683 #ifdef __WITH_DTLS__
684     // Stop secure unicast server and set client socket accordingly
685     if (CA_STATUS_OK == CAWiFiStopSecureUnicastServer())
686     {
687         CAWiFiSetSecureUnicastSocket(-1);
688         gSecureUnicastServerport = -1;
689     }
690 #endif
691
692     //Stop multicast server and set the state accordingly
693     if (CA_STATUS_OK != CAWiFiStopMulticastServer())
694     {
695         gIsMulticastServerStarted = false;
696     }
697
698     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
699     return CA_STATUS_OK;
700 }
701
702 CAResult_t CAStopWIFI()
703 {
704     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
705
706     gStartUnicastServerRequested = false;
707     gStartMulticastServerRequested = false;
708
709     // Stop wifi network monitor
710     CAWiFiStopNetworkMonitor();
711
712     // Stop send queue thread
713     if (gSendQueueHandle && CA_FALSE == gSendQueueHandle->isStop)
714     {
715         CAQueueingThreadStop(gSendQueueHandle);
716     }
717
718     // Stop Unicast, Secured unicast and Multicast servers running
719     CAWiFiStopServers();
720
721     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
722     return CA_STATUS_OK;
723 }
724
725 void CATerminateWIfI()
726 {
727     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
728
729 #ifdef __WITH_DTLS__
730     CADTLSSetAdapterCallbacks(NULL, NULL, DTLS_WIFI);
731     CAAdapterNetDtlsDeInit();
732 #endif
733
734     // Stop wifi adapter
735     CAStopWIFI();
736
737     // Terminate network monitor
738     CAWiFiSetConnectionStateChangeCallback(NULL);
739     CAWiFiTerminateNetworkMonitor();
740
741     // Terminate message queue handler
742     CAWiFiDeinitializeQueueHandles();
743
744     CAWiFiSetPacketReceiveCallback(NULL);
745
746     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
747     return;
748 }
749
750 void CAWiFiSendDataThread(void *threadData)
751 {
752     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
753
754     CAWiFiData *wifiData = (CAWiFiData *) threadData;
755     if (!wifiData)
756     {
757         OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "Invalid wifidata!");
758         return;
759     }
760
761     if (NULL != wifiData->remoteEndpoint)
762     {
763         char *address = wifiData->remoteEndpoint->addressInfo.IP.ipAddress;
764         uint32_t port = wifiData->remoteEndpoint->addressInfo.IP.port;
765
766 #ifdef __WITH_DTLS__
767         if (!wifiData->remoteEndpoint->isSecured)
768         {
769             CAWiFiSendData(address, port, wifiData->data, wifiData->dataLen, false,
770                            wifiData->remoteEndpoint->isSecured);
771         }
772         else
773         {
774             OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "CAAdapterNetDtlsEncrypt called!");
775             uint8_t cacheFalg = 0;
776             CAResult_t  result = CAAdapterNetDtlsEncrypt(address, port, wifiData->data,
777                                  wifiData->dataLen, &cacheFalg, DTLS_WIFI);
778
779             if (CA_STATUS_OK != result)
780             {
781                 OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "CAAdapterNetDtlsEncrypt failed!");
782             }
783             OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "CAAdapterNetDtlsEncrypt returned with cache[%d]",
784                       cacheFalg);
785         }
786 #else
787         CAWiFiSendData(address, port, wifiData->data, wifiData->dataLen, false,
788                        wifiData->remoteEndpoint->isSecured);
789 #endif
790     }
791     else
792     {
793         OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "Send Multicast Data is called");
794         CAWiFiSendData(CA_MULTICAST_IP, CA_MCAST_PORT, wifiData->data,
795                        wifiData->dataLen, true, false);
796     }
797
798     //Free wifi data
799     CAFreeWiFiData(wifiData);
800
801     OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
802     return;
803 }
804
805 CAWiFiData *CACreateWiFiData(const CARemoteEndpoint_t *remoteEndpoint, void *data,
806                              uint32_t dataLength)
807 {
808     CAWiFiData *wifiData = (CAWiFiData *) OICMalloc(sizeof(CAWiFiData));
809     if (!wifiData)
810     {
811         OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "Memory allocation failed!");
812         return NULL;
813     }
814
815     wifiData->remoteEndpoint = CAAdapterCopyRemoteEndpoint(remoteEndpoint);
816     wifiData->data = (void *)OICMalloc(dataLength);
817     if (NULL == wifiData->data)
818     {
819         OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "Memory allocation failed!");
820         CAFreeWiFiData(wifiData);
821         return NULL;
822     }
823     memcpy(wifiData->data, data, dataLength);
824     wifiData->dataLen = dataLength;
825
826     return wifiData;
827 }
828
829 void CAFreeWiFiData(CAWiFiData *wifiData)
830 {
831     if (!wifiData)
832         return;
833
834     CAAdapterFreeRemoteEndpoint(wifiData->remoteEndpoint);
835     OICFree(wifiData->data);
836     OICFree(wifiData);
837 }