Merging security-M3 to master
[platform/upstream/iotivity.git] / resource / csdk / connectivity / src / ip_adapter / caipadapter.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 "caipadapter.h"
21
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <stdint.h>
26
27 #include "caipinterface.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 "uarraylist.h"
35 #include "logger.h"
36 #include "oic_malloc.h"
37
38 /**
39  * @def IP_ADAPTER_TAG
40  * @brief Logging tag for module name
41  */
42 #define IP_ADAPTER_TAG "IP_ADAP"
43
44 /**
45  * @def CA_PORT
46  * @brief Port to listen for incoming data
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 /**
69  * @var CAIPData
70  * @brief Holds inter thread ip data information.
71  */
72 typedef struct
73 {
74     CARemoteEndpoint_t *remoteEndpoint;
75     void *data;
76     uint32_t dataLen;
77 } CAIPData;
78
79 /**
80  * @var g_networkPacketCallback
81  * @brief Network Packet Received Callback to CA
82  */
83 static CANetworkPacketReceivedCallback g_networkPacketCallback = NULL;
84
85 /**
86  * @var g_networkChangeCallback
87  * @brief Network Changed Callback to CA
88  */
89 static CANetworkChangeCallback g_networkChangeCallback = NULL;
90
91 /**
92  * @var g_sendQueueHandle
93  * @brief Queue handle for Send Data
94  */
95 static CAQueueingThread_t *g_sendQueueHandle = NULL;
96
97 /**
98  * @var g_threadPool
99  * @brief ThreadPool for storing ca_thread_pool_t handle passed from CA
100  */
101 static ca_thread_pool_t g_threadPool = NULL;
102
103 static CAResult_t CAIPInitializeQueueHandles();
104
105 static void CAIPDeinitializeQueueHandles();
106
107 static void CAIPNotifyNetworkChange(const char *address, uint16_t port,
108                                           CANetworkStatus_t status);
109
110 static void CAIPConnectionStateCB(const char *ipAddress, CANetworkStatus_t status);
111
112 static void CAIPPacketReceivedCB(const char *ipAddress, uint16_t port, const void *data,
113                                        uint32_t dataLength, bool isSecured,
114                                        const CARemoteId_t *identity);
115 #ifdef __WITH_DTLS__
116 static uint32_t CAIPPacketSendCB(const char *ipAddress, uint16_t port,
117                                        const void *data, uint32_t dataLength);
118 #endif
119
120 static CAResult_t CAIPStopServers();
121
122 static void CAIPSendDataThread(void *threadData);
123
124 static CAIPData *CACreateIPData(const CARemoteEndpoint_t *remoteEndpoint,
125                                             const void *data, uint32_t dataLength);
126 void CAFreeIPData(CAIPData *ipData);
127
128 static void CADataDestroyer(void *data, uint32_t size);
129
130 CAResult_t CAIPInitializeQueueHandles()
131 {
132     OIC_LOG(DEBUG, IP_ADAPTER_TAG, "IN");
133
134     // Check if the message queue is already initialized
135     if (g_sendQueueHandle)
136     {
137         OIC_LOG(DEBUG, IP_ADAPTER_TAG, "send queue handle is already initialized!");
138         return CA_STATUS_OK;
139     }
140
141     // Create send message queue
142     g_sendQueueHandle = OICMalloc(sizeof(CAQueueingThread_t));
143     if (!g_sendQueueHandle)
144     {
145         OIC_LOG(ERROR, IP_ADAPTER_TAG, "Memory allocation failed!");
146         return CA_MEMORY_ALLOC_FAILED;
147     }
148
149     if (CA_STATUS_OK != CAQueueingThreadInitialize(g_sendQueueHandle, g_threadPool,
150                                                    CAIPSendDataThread, CADataDestroyer))
151     {
152         OIC_LOG(ERROR, IP_ADAPTER_TAG, "Failed to Initialize send queue thread");
153         OICFree(g_sendQueueHandle);
154         g_sendQueueHandle = NULL;
155         return CA_STATUS_FAILED;
156     }
157
158     OIC_LOG(DEBUG, IP_ADAPTER_TAG, "OUT");
159     return CA_STATUS_OK;
160 }
161
162 void CAIPDeinitializeQueueHandles()
163 {
164     OIC_LOG(DEBUG, IP_ADAPTER_TAG, "IN");
165
166     CAQueueingThreadDestroy(g_sendQueueHandle);
167     OICFree(g_sendQueueHandle);
168     g_sendQueueHandle = NULL;
169
170     OIC_LOG(DEBUG, IP_ADAPTER_TAG, "OUT");
171 }
172
173 void CAIPNotifyNetworkChange(const char *address, uint16_t port, CANetworkStatus_t status)
174 {
175     OIC_LOG(DEBUG, IP_ADAPTER_TAG, "IN");
176
177     VERIFY_NON_NULL_VOID(address, IP_ADAPTER_TAG, "address is NULL");
178
179     CALocalConnectivity_t *localEndpoint = CAAdapterCreateLocalEndpoint(CA_IPV4, address);
180     if (!localEndpoint)
181     {
182         OIC_LOG(ERROR, IP_ADAPTER_TAG, "localEndpoint creation failed!");
183         return;
184     }
185
186     localEndpoint->addressInfo.IP.port = port;
187
188     if (g_networkChangeCallback)
189     {
190         g_networkChangeCallback(localEndpoint, status);
191     }
192     else
193     {
194         OIC_LOG(ERROR, IP_ADAPTER_TAG, "g_networkChangeCallback is NULL");
195     }
196
197     CAAdapterFreeLocalEndpoint(localEndpoint);
198
199     OIC_LOG(DEBUG, IP_ADAPTER_TAG, "OUT");
200 }
201
202 void CAIPConnectionStateCB(const char *ipAddress, CANetworkStatus_t status)
203 {
204     OIC_LOG(DEBUG, IP_ADAPTER_TAG, "IN");
205
206     VERIFY_NON_NULL_VOID(ipAddress, IP_ADAPTER_TAG, "ipAddress is NULL");
207
208     if (CA_INTERFACE_UP == status)
209     {
210         uint16_t port = CA_PORT;
211         CAResult_t ret = CAIPStartUnicastServer(ipAddress, &port, false, false);
212         if (CA_STATUS_OK == ret)
213         {
214             OIC_LOG_V(DEBUG, IP_ADAPTER_TAG, "Unicast server started on %d port", port);
215         }
216         else
217         {
218             OIC_LOG_V(ERROR, IP_ADAPTER_TAG, "Failed to start Unicast server port[%d]", ret);
219         }
220
221 #ifdef __WITH_DTLS__
222         port = CA_SECURE_PORT;
223         ret = CAIPStartUnicastServer(ipAddress, &port, false, true);
224         if (CA_STATUS_OK == ret)
225         {
226             OIC_LOG_V(DEBUG, IP_ADAPTER_TAG, "Secure Unicast server started on %d", port);
227         }
228         else
229         {
230             OIC_LOG_V(ERROR, IP_ADAPTER_TAG, "Failed to start secure Unicast server [%d]",
231                       ret);
232         }
233 #endif
234         ret = CAIPStartMulticastServer(ipAddress, CA_MULTICAST_IP, CA_MCAST_PORT);
235         if (CA_STATUS_OK == ret)
236         {
237             OIC_LOG_V(DEBUG, IP_ADAPTER_TAG, "Multicast server started on port[%d]",
238                       CA_MCAST_PORT);
239         }
240         else
241         {
242             OIC_LOG_V(ERROR, IP_ADAPTER_TAG, "Failed to start Multicast server port[%d]",
243                       ret);
244         }
245
246         // Notify network change to CA
247         CAIPNotifyNetworkChange(ipAddress, port, status);
248     }
249     else
250     {
251         CAIPNotifyNetworkChange(ipAddress, 0, status);
252
253         // Stop Unicast, Secured unicast and Multicast servers
254         CAIPStopServer(ipAddress);
255     }
256
257     OIC_LOG(DEBUG, IP_ADAPTER_TAG, "OUT");
258 }
259
260 #ifdef __WITH_DTLS__
261 uint32_t CAIPPacketSendCB(const char *ipAddress, uint16_t port,
262         const void *data, uint32_t dataLength)
263 {
264     OIC_LOG(DEBUG, IP_ADAPTER_TAG, "IN");
265
266     VERIFY_NON_NULL_RET(ipAddress, IP_ADAPTER_TAG, "ipAddress is NULL", 0);
267
268     VERIFY_NON_NULL_RET(data, IP_ADAPTER_TAG, "data is NULL", 0);
269
270     uint32_t sentLength = CAIPSendData(ipAddress, port, data, dataLength, false, true);
271
272     OIC_LOG_V(DEBUG, IP_ADAPTER_TAG, "Successfully sent %d of encrypted data!", sentLength);
273
274     OIC_LOG(DEBUG, IP_ADAPTER_TAG, "OUT");
275
276     return sentLength;
277 }
278 #endif
279
280 void CAIPPacketReceivedCB(const char *ipAddress, uint16_t port, const void *data,
281                                 uint32_t dataLength, bool isSecured,
282                                 const CARemoteId_t *identity)
283 {
284     OIC_LOG(DEBUG, IP_ADAPTER_TAG, "IN");
285
286     VERIFY_NON_NULL_VOID(ipAddress, IP_ADAPTER_TAG, "ipAddress is NULL");
287
288     VERIFY_NON_NULL_VOID(data, IP_ADAPTER_TAG, "data is NULL");
289
290     OIC_LOG_V(DEBUG, IP_ADAPTER_TAG, "Address: %s, port:%d", ipAddress, port);
291
292     // CA is freeing this memory
293     CARemoteEndpoint_t *endPoint = CAAdapterCreateRemoteEndpoint(CA_IPV4, ipAddress, NULL );
294     if (!endPoint)
295     {
296         OIC_LOG(ERROR, IP_ADAPTER_TAG, "EndPoint creation failed!");
297         return;
298     }
299     endPoint->addressInfo.IP.port = port;
300     endPoint->isSecured = isSecured;
301     if (identity)
302     {
303         endPoint->identity = *identity;
304     }
305
306
307     void *buf = OICCalloc(dataLength + 1, sizeof(char));
308     if (!buf)
309     {
310         OIC_LOG(ERROR, IP_ADAPTER_TAG, "Memory Allocation failed!");
311         CAAdapterFreeRemoteEndpoint(endPoint);
312         return;
313     }
314     memcpy(buf, data, dataLength);
315     if (g_networkPacketCallback)
316     {
317         g_networkPacketCallback(endPoint, buf, dataLength);
318     }
319     else
320     {
321         OICFree(buf);
322         CAAdapterFreeRemoteEndpoint(endPoint);
323     }
324
325     OIC_LOG(DEBUG, IP_ADAPTER_TAG, "OUT");
326 }
327
328 CAResult_t CAInitializeIP(CARegisterConnectivityCallback registerCallback,
329                                 CANetworkPacketReceivedCallback networkPacketCallback,
330                                 CANetworkChangeCallback netCallback, ca_thread_pool_t handle)
331 {
332     OIC_LOG(DEBUG, IP_ADAPTER_TAG, "IN");
333     VERIFY_NON_NULL(registerCallback, IP_ADAPTER_TAG, "registerCallback");
334     VERIFY_NON_NULL(networkPacketCallback, IP_ADAPTER_TAG, "networkPacketCallback");
335     VERIFY_NON_NULL(netCallback, IP_ADAPTER_TAG, "netCallback");
336     VERIFY_NON_NULL(handle, IP_ADAPTER_TAG, "thread pool handle");
337
338     g_threadPool = handle;
339     g_networkChangeCallback = netCallback;
340     g_networkPacketCallback = networkPacketCallback;
341
342     CAResult_t ret = CAIPInitializeNetworkMonitor(g_threadPool);
343     if (CA_STATUS_OK != ret)
344     {
345         OIC_LOG_V(ERROR, IP_ADAPTER_TAG, "Failed to initialize n/w monitor![%d]", ret);
346         return ret;
347     }
348     CAIPSetConnectionStateChangeCallback(CAIPConnectionStateCB);
349
350     ret = CAIPInitializeServer(g_threadPool);
351     if (CA_STATUS_OK != ret)
352     {
353         OIC_LOG_V(ERROR, IP_ADAPTER_TAG, "Failed to initialize server![%d]", ret);
354         CATerminateIP();
355         return ret;
356     }
357
358     CAIPSetPacketReceiveCallback(CAIPPacketReceivedCB);
359 #ifdef __WITH_DTLS__
360     CAAdapterNetDtlsInit();
361
362     CADTLSSetAdapterCallbacks(CAIPPacketReceivedCB, CAIPPacketSendCB, CA_IPV4);
363 #endif
364
365     CAConnectivityHandler_t ipHandler;
366     ipHandler.startAdapter = CAStartIP;
367     ipHandler.startListenServer = CAStartIPListeningServer;
368     ipHandler.startDiscoveryServer = CAStartIPDiscoveryServer;
369     ipHandler.sendData = CASendIPUnicastData;
370     ipHandler.sendDataToAll = CASendIPMulticastData;
371     ipHandler.GetnetInfo = CAGetIPInterfaceInformation;
372     ipHandler.readData = CAReadIPData;
373     ipHandler.stopAdapter = CAStopIP;
374     ipHandler.terminate = CATerminateIP;
375     registerCallback(ipHandler, CA_IPV4);
376
377     if (CA_STATUS_OK != CAIPInitializeQueueHandles())
378     {
379         OIC_LOG(ERROR, IP_ADAPTER_TAG, "Failed to Initialize Queue Handle");
380         CATerminateIP();
381         return CA_STATUS_FAILED;
382     }
383
384     OIC_LOG(INFO, IP_ADAPTER_TAG, "OUT IntializeIP is Success");
385     return CA_STATUS_OK;
386 }
387
388 CAResult_t CAStartIP()
389 {
390     OIC_LOG(DEBUG, IP_ADAPTER_TAG, "IN");
391
392     // Start monitoring IP network
393     CAResult_t ret = CAIPStartNetworkMonitor();
394     if (CA_STATUS_OK != ret)
395     {
396         OIC_LOG(ERROR, IP_ADAPTER_TAG, "Failed to Start n/w monitor");
397         return ret;
398     }
399
400     // Start send queue thread
401     if (CA_STATUS_OK != CAQueueingThreadStart(g_sendQueueHandle))
402     {
403         OIC_LOG(ERROR, IP_ADAPTER_TAG, "Failed to Start Send Data Thread");
404         return CA_STATUS_FAILED;
405     }
406
407     bool retVal = CAIPIsConnected();
408     if (false == retVal)
409     {
410         OIC_LOG(DEBUG, IP_ADAPTER_TAG, "IP is not Connected");
411         return CA_STATUS_OK;
412     }
413
414     u_arraylist_t *netInterfaceList = u_arraylist_create();
415
416     VERIFY_NON_NULL(netInterfaceList, IP_ADAPTER_TAG, "netInterfaceList is NULL");
417
418     ret = CAIPGetInterfaceInfo(&netInterfaceList);
419     if (CA_STATUS_OK != ret)
420     {
421         OIC_LOG_V(ERROR, IP_ADAPTER_TAG, "Failed to get IP interface info [%d]", ret);
422         CAClearNetInterfaceInfoList(netInterfaceList);
423         return ret;
424     }
425
426     uint32_t listIndex = 0;
427     uint32_t listLength = u_arraylist_length(netInterfaceList);
428     for (listIndex = 0; listIndex < listLength; listIndex++)
429     {
430         CANetInfo_t *netInfo = (CANetInfo_t *) u_arraylist_get(netInterfaceList, listIndex);
431         if (!netInfo)
432         {
433             continue;
434         }
435         uint16_t unicastPort = CA_PORT;
436         ret = CAIPStartUnicastServer(netInfo->ipAddress, &unicastPort, false, false);
437         if (CA_STATUS_OK == ret)
438         {
439             OIC_LOG_V(DEBUG, IP_ADAPTER_TAG, "Unicast server started on %d port",
440                       unicastPort);
441         }
442
443 #ifdef __WITH_DTLS__
444         unicastPort = CA_SECURE_PORT;
445         ret = CAIPStartUnicastServer(netInfo->ipAddress, &unicastPort, false, true);
446
447         if (CA_STATUS_OK == ret)
448         {
449             OIC_LOG_V(DEBUG, IP_ADAPTER_TAG,
450                       "Secure Unicast server started on %d port", unicastPort);
451         }
452 #endif
453     }
454     CAClearNetInterfaceInfoList(netInterfaceList);
455     OIC_LOG(DEBUG, IP_ADAPTER_TAG, "OUT");
456     return ret;
457 }
458
459 CAResult_t CAStartIPListeningServer()
460 {
461     OIC_LOG(DEBUG, IP_ADAPTER_TAG, "IN");
462
463     bool retVal = CAIPIsConnected();
464     if (false == retVal)
465     {
466         OIC_LOG(DEBUG, IP_ADAPTER_TAG,
467                   "IP not Connected. Couldn't start multicast server");
468         return CA_STATUS_OK;
469     }
470
471     u_arraylist_t *netInterfaceList = u_arraylist_create();
472
473     VERIFY_NON_NULL(netInterfaceList, IP_ADAPTER_TAG, "netInterfaceList is NULL");
474
475     CAResult_t ret = CAIPGetInterfaceInfo(&netInterfaceList);
476     if (CA_STATUS_OK != ret)
477     {
478         OIC_LOG_V(ERROR, IP_ADAPTER_TAG, "Failed to get IP interface info [%d]", ret);
479         CAClearNetInterfaceInfoList(netInterfaceList);
480         return ret;
481     }
482
483     uint32_t listIndex = 0;
484     uint32_t listLength = u_arraylist_length(netInterfaceList);
485     for (listIndex = 0; listIndex < listLength; listIndex++)
486     {
487
488         CANetInfo_t *netInfo = (CANetInfo_t *) u_arraylist_get(netInterfaceList, listIndex);
489         if (!netInfo)
490         {
491             continue;
492         }
493
494         OIC_LOG_V(DEBUG, IP_ADAPTER_TAG, "Ip address for multicast interface %s",
495                   netInfo->ipAddress);
496         ret = CAIPStartMulticastServer(netInfo->ipAddress, CA_MULTICAST_IP, CA_MCAST_PORT);
497         if (CA_STATUS_OK == ret)
498         {
499             OIC_LOG(INFO, IP_ADAPTER_TAG, "Multicast Server is Started Successfully");
500         }
501     }
502
503     CAClearNetInterfaceInfoList(netInterfaceList);
504     OIC_LOG(DEBUG, IP_ADAPTER_TAG, "OUT");
505     return ret;
506 }
507
508 CAResult_t CAStartIPDiscoveryServer()
509 {
510     OIC_LOG(DEBUG, IP_ADAPTER_TAG, "IN");
511     return CAStartIPListeningServer();
512 }
513
514 int32_t CASendIPUnicastData(const CARemoteEndpoint_t *remoteEndpoint, const void *data,
515                                   uint32_t dataLength)
516 {
517     OIC_LOG(DEBUG, IP_ADAPTER_TAG, "IN");
518
519     VERIFY_NON_NULL_RET(remoteEndpoint, IP_ADAPTER_TAG, "remoteEndpoint", -1);
520     VERIFY_NON_NULL_RET(data, IP_ADAPTER_TAG, "data", -1);
521     VERIFY_NON_NULL_RET(g_sendQueueHandle, IP_ADAPTER_TAG, "sendQueueHandle", -1);
522
523     if (0 == dataLength)
524     {
525         OIC_LOG(ERROR, IP_ADAPTER_TAG, "Invalid Data Length");
526         return -1;
527     }
528
529     // Create IPData to add to queue
530     CAIPData *ipData = CACreateIPData(remoteEndpoint, data, dataLength);
531     if (!ipData)
532     {
533         OIC_LOG(ERROR, IP_ADAPTER_TAG, "Failed to create ipData!");
534         return -1;
535     }
536     else
537     {
538         // Add message to send queue
539         CAQueueingThreadAddData(g_sendQueueHandle, ipData, sizeof(CAIPData));
540
541         OIC_LOG(DEBUG, IP_ADAPTER_TAG, "OUT");
542         return dataLength;
543     }
544 }
545
546 int32_t CASendIPMulticastData(const void *data, uint32_t dataLength)
547 {
548     OIC_LOG(DEBUG, IP_ADAPTER_TAG, "IN");
549
550     VERIFY_NON_NULL_RET(data, IP_ADAPTER_TAG, "data", -1);
551     VERIFY_NON_NULL_RET(g_sendQueueHandle, IP_ADAPTER_TAG, "sendQueueHandle", -1);
552
553     if (0 == dataLength)
554     {
555         OIC_LOG(ERROR, IP_ADAPTER_TAG, "Invalid Data Length");
556         return -1;
557     }
558
559     // Create IPData to add to queue
560     CAIPData *ipData = CACreateIPData(NULL, data, dataLength);
561     if (!ipData)
562     {
563         OIC_LOG(ERROR, IP_ADAPTER_TAG, "Failed to create ipData!");
564         return -1;
565     }
566     else
567     {
568         // Add message to send queue
569         CAQueueingThreadAddData(g_sendQueueHandle, ipData, sizeof(CAIPData));
570
571         OIC_LOG(DEBUG, IP_ADAPTER_TAG, "OUT");
572         return dataLength;
573     }
574 }
575
576 CAResult_t CAGetIPInterfaceInformation(CALocalConnectivity_t **info, uint32_t *size)
577 {
578     OIC_LOG(DEBUG, IP_ADAPTER_TAG, "IN");
579
580     VERIFY_NON_NULL(info, IP_ADAPTER_TAG, "info is NULL");
581     VERIFY_NON_NULL(size, IP_ADAPTER_TAG, "size is NULL");
582
583     bool retVal = CAIPIsConnected();
584     if (false == retVal)
585     {
586         OIC_LOG(ERROR, IP_ADAPTER_TAG,
587                 "Failed to get interface address, IP not Connected");
588         return CA_ADAPTER_NOT_ENABLED;
589     }
590
591     u_arraylist_t *netInterfaceList = u_arraylist_create();
592
593     VERIFY_NON_NULL(netInterfaceList, IP_ADAPTER_TAG, "netInterfaceList is NULL");
594
595     CAResult_t ret = CAIPGetInterfaceInfo(&netInterfaceList);
596     if (CA_STATUS_OK != ret)
597     {
598         OIC_LOG_V(ERROR, IP_ADAPTER_TAG, "CAIPGetInterfaceInfo failed:%d", ret);
599         CAClearNetInterfaceInfoList(netInterfaceList);
600         return ret;
601     }
602
603     uint32_t listLength = u_arraylist_length(netInterfaceList);
604     uint32_t netInfoSize = listLength;
605
606 #ifdef __WITH_DTLS__
607     if (listLength)
608     {
609         netInfoSize = listLength * 2;
610     }
611 #endif
612
613     CALocalConnectivity_t *conInfo = (CALocalConnectivity_t *) OICCalloc(
614                                       netInfoSize, sizeof(CALocalConnectivity_t));
615     if (!conInfo)
616     {
617         OIC_LOG(ERROR, IP_ADAPTER_TAG, "Malloc Failed");
618         CAClearNetInterfaceInfoList(netInterfaceList);
619         return CA_MEMORY_ALLOC_FAILED;
620     }
621
622     uint32_t listIndex = 0;
623     uint32_t count = 0;
624     for (listIndex = 0; listIndex < listLength; listIndex++)
625     {
626         CANetInfo_t *netInfo = (CANetInfo_t *) u_arraylist_get(netInterfaceList, listIndex);
627         if (!netInfo)
628         {
629             continue;
630         }
631
632         conInfo[count].type = CA_IPV4;
633         conInfo[count].isSecured = false;
634         conInfo[count].addressInfo.IP.port = CAGetServerPortNum(netInfo->ipAddress, false);
635         strncpy(conInfo[count].addressInfo.IP.ipAddress, netInfo->ipAddress,
636                 strlen(netInfo->ipAddress));
637
638 #ifdef __WITH_DTLS__
639         // copy secure unicast server information
640         {
641             count ++;
642             conInfo[count].type = CA_IPV4;
643             conInfo[count].isSecured = true;
644             conInfo[count].addressInfo.IP.port = CAGetServerPortNum(netInfo->ipAddress, true);
645             strncpy(conInfo[count].addressInfo.IP.ipAddress, netInfo->ipAddress,
646                     strlen(netInfo->ipAddress));
647         }
648 #endif
649         count ++;
650     }
651     *size = count;
652     *info = conInfo;
653     CAClearNetInterfaceInfoList(netInterfaceList);
654
655     OIC_LOG(DEBUG, IP_ADAPTER_TAG, "OUT");
656     return CA_STATUS_OK;
657 }
658
659 CAResult_t CAReadIPData()
660 {
661     OIC_LOG(DEBUG, IP_ADAPTER_TAG, "IN");
662
663     OIC_LOG(DEBUG, IP_ADAPTER_TAG, "OUT");
664     return CA_STATUS_OK;
665 }
666
667 CAResult_t CAIPStopServers()
668 {
669     OIC_LOG(DEBUG, IP_ADAPTER_TAG, "IN");
670
671     // Stop all unicast and multicast servers.
672     if (CA_STATUS_OK == CAIPStopAllServers())
673     {
674         OIC_LOG(DEBUG, IP_ADAPTER_TAG, "CAIPStopAllServers success");
675     }
676
677     OIC_LOG(DEBUG, IP_ADAPTER_TAG, "OUT");
678     return CA_STATUS_OK;
679 }
680
681 CAResult_t CAStopIP()
682 {
683     OIC_LOG(DEBUG, IP_ADAPTER_TAG, "IN");
684
685 #ifdef __WITH_DTLS__
686     CAAdapterNetDtlsDeInit();
687 #endif
688
689     // Stop IP network monitor
690     CAIPStopNetworkMonitor();
691
692     // Stop send queue thread
693     if (g_sendQueueHandle)
694     {
695         CAQueueingThreadStop(g_sendQueueHandle);
696     }
697
698     // Stop Unicast, Secured unicast and Multicast servers running
699     CAIPStopServers();
700
701     OIC_LOG(DEBUG, IP_ADAPTER_TAG, "OUT");
702     return CA_STATUS_OK;
703 }
704
705 void CATerminateIP()
706 {
707     OIC_LOG(DEBUG, IP_ADAPTER_TAG, "IN");
708
709     // Stop IP adapter
710     CAStopIP();
711
712 #ifdef __WITH_DTLS__
713     CADTLSSetAdapterCallbacks(NULL, NULL, CA_IPV4);
714 #endif
715
716     CAIPSetPacketReceiveCallback(NULL);
717
718     // Terminate IP server
719     CAIPTerminateServer();
720
721     // Terminate network monitor
722     CAIPSetConnectionStateChangeCallback(NULL);
723     CAIPTerminateNetworkMonitor();
724
725     // Terminate message queue handler
726     CAIPDeinitializeQueueHandles();
727
728     OIC_LOG(DEBUG, IP_ADAPTER_TAG, "OUT");
729 }
730
731 void CAIPSendDataThread(void *threadData)
732 {
733     OIC_LOG(DEBUG, IP_ADAPTER_TAG, "IN");
734
735     CAIPData *ipData = (CAIPData *) threadData;
736     if (!ipData)
737     {
738         OIC_LOG(DEBUG, IP_ADAPTER_TAG, "Invalid ip data!");
739         return;
740     }
741
742     //If remoteEndpoint is NULL, its Multicast, else its Unicast.
743     if (ipData->remoteEndpoint)
744     {
745         //Processing for sending unicast
746         char *address = ipData->remoteEndpoint->addressInfo.IP.ipAddress;
747         uint16_t port = ipData->remoteEndpoint->addressInfo.IP.port;
748
749 #ifdef __WITH_DTLS__
750         if (!ipData->remoteEndpoint->isSecured)
751         {
752             OIC_LOG(DEBUG, IP_ADAPTER_TAG, "Send Unicast Data is called");
753             CAIPSendData(address, port, ipData->data, ipData->dataLen, false,
754                                ipData->remoteEndpoint->isSecured);
755         }
756         else
757         {
758             OIC_LOG(DEBUG, IP_ADAPTER_TAG, "CAAdapterNetDtlsEncrypt called!");
759             CAResult_t result = CAAdapterNetDtlsEncrypt(address, port, ipData->data,
760                                                         ipData->dataLen, CA_IPV4);
761
762             if (CA_STATUS_OK != result)
763             {
764                 OIC_LOG(ERROR, IP_ADAPTER_TAG, "CAAdapterNetDtlsEncrypt failed!");
765             }
766             OIC_LOG_V(DEBUG, IP_ADAPTER_TAG,
767                       "CAAdapterNetDtlsEncrypt returned with result[%d]", result);
768         }
769 #else
770         CAIPSendData(address, port, ipData->data, ipData->dataLen, false,
771                            ipData->remoteEndpoint->isSecured);
772 #endif
773     }
774     else
775     {
776         //Processing for sending multicast
777         OIC_LOG(DEBUG, IP_ADAPTER_TAG, "Send Multicast Data is called");
778         CAIPSendData(CA_MULTICAST_IP, CA_MCAST_PORT, ipData->data,
779                            ipData->dataLen, true, false);
780     }
781
782     OIC_LOG(DEBUG, IP_ADAPTER_TAG, "OUT");
783 }
784
785 CAIPData *CACreateIPData(const CARemoteEndpoint_t *remoteEndpoint, const void *data,
786                                      uint32_t dataLength)
787 {
788     VERIFY_NON_NULL_RET(data, IP_ADAPTER_TAG, "IPData is NULL", NULL);
789
790     CAIPData *ipData = (CAIPData *) OICMalloc(sizeof(CAIPData));
791     if (!ipData)
792     {
793         OIC_LOG(ERROR, IP_ADAPTER_TAG, "Memory allocation failed!");
794         return NULL;
795     }
796
797     ipData->remoteEndpoint = CAAdapterCopyRemoteEndpoint(remoteEndpoint);
798     ipData->data = (void *) OICMalloc(dataLength);
799     if (!ipData->data)
800     {
801         OIC_LOG(ERROR, IP_ADAPTER_TAG, "Memory allocation failed!");
802         CAFreeIPData(ipData);
803         return NULL;
804     }
805
806     memcpy(ipData->data, data, dataLength);
807     ipData->dataLen = dataLength;
808
809     return ipData;
810 }
811
812 void CAFreeIPData(CAIPData *ipData)
813 {
814     VERIFY_NON_NULL_VOID(ipData, IP_ADAPTER_TAG, "ipData is NULL");
815
816     CAAdapterFreeRemoteEndpoint(ipData->remoteEndpoint);
817     OICFree(ipData->data);
818     OICFree(ipData);
819 }
820
821 void CADataDestroyer(void *data, uint32_t size)
822 {
823     CAIPData *etdata = (CAIPData *) data;
824
825     CAFreeIPData(etdata);
826 }
827