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