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