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