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