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