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