Update snapshot(2018-01-04)
[platform/upstream/iotivity.git] / resource / csdk / connectivity / src / cainterfacecontroller.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
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <inttypes.h>
25
26 #include "logger.h"
27 #include "oic_malloc.h"
28 #include "caadapterutils.h"
29 #include "canetworkconfigurator.h"
30 #include "cainterfacecontroller.h"
31 #include "caedradapter.h"
32 #include "caleadapter.h"
33 #include "canfcadapter.h"
34 #include "caremotehandler.h"
35 #include "cathreadpool.h"
36 #include "caipadapter.h"
37 #include "cainterface.h"
38 #include "caipinterface.h"
39 #include <coap/utlist.h>
40 #include "octhread.h"
41
42 #ifdef RA_ADAPTER
43 #include "caraadapter.h"
44 #endif
45
46 #ifdef TCP_ADAPTER
47 #include "catcpadapter.h"
48 #endif
49
50 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
51 #include "ca_adapter_net_ssl.h"
52 #endif
53
54 #define TAG "OIC_CA_INF_CTR"
55
56 #define CA_MEMORY_ALLOC_CHECK(arg) {if (arg == NULL) \
57     {OIC_LOG(ERROR, TAG, "memory error");goto memory_error_exit;} }
58
59 static CAConnectivityHandler_t *g_adapterHandler = NULL;
60
61 static uint32_t g_numberOfAdapters = 0;
62
63 static CANetworkPacketReceivedCallback g_networkPacketReceivedCallback = NULL;
64
65 static CAErrorHandleCallback g_errorHandleCallback = NULL;
66
67 static struct CANetworkCallback_t * g_networkChangeCallbackList = NULL;
68
69 /**
70  * Mutex to synchronize network change list.
71  */
72 static oc_mutex g_mutexNetCallbackList = NULL;
73
74 /**
75  * network callback structure is handling
76  * for adapter state changed and connection state changed event.
77  */
78 typedef struct CANetworkCallback_t {
79
80     /** Linked list; for multiple callback list.*/
81     struct CANetworkCallback_t * next;
82
83     /** Adapter state changed event callback. */
84     CAAdapterStateChangedCB adapter;
85
86     /** Connection state changed event callback. */
87     CAConnectionStateChangedCB conn;
88
89 } CANetworkCallback_t;
90
91 static int CAGetAdapterIndex(CATransportAdapter_t cType)
92 {
93     for (uint32_t index=0 ; index < g_numberOfAdapters ; index++)
94     {
95         if (cType == g_adapterHandler[index].cType )
96          {
97              return index;
98          }
99     }
100     OIC_LOG_V(ERROR, TAG, "adapter info [%d]", g_numberOfAdapters);
101     return -1;
102 }
103
104 static void CARegisterCallback(CAConnectivityHandler_t handler)
105 {
106     if (handler.startAdapter == NULL ||
107         handler.startListenServer == NULL ||
108         handler.stopListenServer == NULL ||
109         handler.startDiscoveryServer == NULL ||
110         handler.sendData == NULL ||
111         handler.sendDataToAll == NULL ||
112         handler.GetnetInfo == NULL ||
113         handler.readData == NULL ||
114         handler.stopAdapter == NULL ||
115         handler.terminate == NULL)
116     {
117         OIC_LOG(ERROR, TAG, "connectivity handler is not enough to be used!");
118         return;
119     }
120     uint32_t numberofAdapters = g_numberOfAdapters + 1;
121     CAConnectivityHandler_t *adapterHandler = OICRealloc(g_adapterHandler,
122                                    (numberofAdapters) * sizeof(*adapterHandler));
123     if (NULL == adapterHandler)
124     {
125         OIC_LOG(ERROR, TAG, "Memory allocation failed during registration");
126         return;
127     }
128     g_adapterHandler = adapterHandler;
129     g_numberOfAdapters = numberofAdapters;
130     g_adapterHandler[g_numberOfAdapters-1] = handler;
131
132     OIC_LOG_V(DEBUG, TAG, "%d type adapter, register complete!", handler.cType);
133 }
134
135 /**
136  * Add a network callback from caller to the network callback list
137  *
138  * @param adapterCB  adapter state changed callback
139  * @param connCB     connection state changed callback
140  *
141  * @return
142  *     CAResult_t
143  */
144 static CAResult_t AddNetworkStateChangedCallback(CAAdapterStateChangedCB adapterCB,
145                                                  CAConnectionStateChangedCB connCB)
146 {
147     OIC_LOG(DEBUG, TAG, "Add NetworkStateChanged Callback");
148
149     if (!adapterCB || !connCB)
150     {
151         OIC_LOG(ERROR, TAG, "parameter is null");
152         return CA_STATUS_INVALID_PARAM;
153     }
154
155     oc_mutex_lock(g_mutexNetCallbackList);
156     CANetworkCallback_t* callback = NULL;
157     LL_FOREACH(g_networkChangeCallbackList, callback)
158     {
159         if (callback && adapterCB == callback->adapter && connCB == callback->conn)
160         {
161             OIC_LOG(DEBUG, TAG, "this callback is already added");
162             oc_mutex_unlock(g_mutexNetCallbackList);
163             return CA_STATUS_OK;
164         }
165     }
166
167     callback = (CANetworkCallback_t *) OICCalloc(1, sizeof(CANetworkCallback_t));
168     if (NULL == callback)
169     {
170         OIC_LOG(ERROR, TAG, "Memory allocation failed during registration");
171         oc_mutex_unlock(g_mutexNetCallbackList);
172         return CA_MEMORY_ALLOC_FAILED;
173     }
174
175     callback->adapter = adapterCB;
176     callback->conn = connCB;
177     LL_APPEND(g_networkChangeCallbackList, callback);
178     oc_mutex_unlock(g_mutexNetCallbackList);
179     OIC_LOG_V(INFO, TAG, "Added NetworkStateChanged Callback [%p]", callback);
180
181     return CA_STATUS_OK;
182 }
183
184 /**
185  * Remove a network callback from the network callback list
186  *
187  * @param adapterCB  adapter state changed callback
188  * @param connCB     connection state changed callback
189  *
190  * @return
191  *     CAResult_t
192  */
193 static CAResult_t RemoveNetworkStateChangedCallback(CAAdapterStateChangedCB adapterCB,
194                                                     CAConnectionStateChangedCB connCB)
195 {
196     OIC_LOG(DEBUG, TAG, "Remove NetworkStateChanged Callback");
197
198     oc_mutex_lock(g_mutexNetCallbackList);
199     CANetworkCallback_t* callback = NULL;
200     LL_FOREACH(g_networkChangeCallbackList, callback)
201     {
202         if (callback && adapterCB == callback->adapter && connCB == callback->conn)
203         {
204             OIC_LOG(DEBUG, TAG, "remove specific callback");
205             LL_DELETE(g_networkChangeCallbackList, callback);
206             oc_mutex_unlock(g_mutexNetCallbackList);
207             OICFree(callback);
208             return CA_STATUS_OK;
209         }
210     }
211     oc_mutex_unlock(g_mutexNetCallbackList);
212
213     return CA_STATUS_OK;
214 }
215
216 #ifdef RA_ADAPTER
217 CAResult_t CASetAdapterRAInfo(const CARAInfo_t *caraInfo)
218 {
219     return CASetRAInfo(caraInfo);
220 }
221 #endif
222
223 static CAResult_t CAReceivedPacketCallback(const CASecureEndpoint_t *sep,
224                                            const void *data, uint32_t dataLen)
225 {
226     if (g_networkPacketReceivedCallback != NULL)
227     {
228         return g_networkPacketReceivedCallback(sep, data, dataLen);
229     }
230     else
231     {
232         OIC_LOG(INFO, TAG, "network packet received callback is NULL!");
233         return CA_STATUS_OK;
234     }
235 }
236
237 static void CAAdapterChangedCallback(CATransportAdapter_t adapter, CANetworkStatus_t status)
238 {
239
240     oc_mutex_lock(g_mutexNetCallbackList);
241     // Call the callback.
242     CANetworkCallback_t* callback  = NULL;
243     LL_FOREACH(g_networkChangeCallbackList, callback)
244     {
245         if (callback && callback->adapter)
246         {
247             OIC_LOG_V(INFO, TAG, "IN application adapter changed callback [%p]", callback);
248             if (CA_INTERFACE_UP == status)
249             {
250                 callback->adapter(adapter, true);
251             }
252             else if (CA_INTERFACE_DOWN == status)
253             {
254                 callback->adapter(adapter, false);
255             }
256             OIC_LOG_V(INFO, TAG, "OUT application adapter changed callback [%p]", callback);
257         }
258     }
259     oc_mutex_unlock(g_mutexNetCallbackList);
260     OIC_LOG_V(DEBUG, TAG, "[%d] adapter status is changed to [%d]", adapter, status);
261 }
262
263 #if defined(TCP_ADAPTER) || defined(EDR_ADAPTER) || defined(LE_ADAPTER)
264 static void CAConnectionChangedCallback(const CAEndpoint_t *info, bool isConnected)
265 {
266     oc_mutex_lock(g_mutexNetCallbackList);
267     // Call the callback.
268     CANetworkCallback_t* callback = NULL;
269     LL_FOREACH(g_networkChangeCallbackList, callback)
270     {
271         if (callback && callback->conn)
272         {
273             callback->conn(info, isConnected);
274         }
275     }
276     oc_mutex_unlock(g_mutexNetCallbackList);
277     OIC_LOG_V(DEBUG, TAG, "[%s] connection status is changed to [%d]", info->addr, isConnected);
278 }
279 #endif
280
281 static void CAAdapterErrorHandleCallback(const CAEndpoint_t *endpoint,
282                                          const void *data, uint32_t dataLen,
283                                          CAResult_t result)
284 {
285     OIC_LOG(DEBUG, TAG, "received error from adapter in interfacecontroller");
286
287     // Call the callback.
288     if (g_errorHandleCallback != NULL)
289     {
290         g_errorHandleCallback(endpoint, data, dataLen, result);
291     }
292 }
293
294 static void CADestroyMutex()
295 {
296     if (g_mutexNetCallbackList)
297     {
298         oc_mutex_free(g_mutexNetCallbackList);
299         g_mutexNetCallbackList = NULL;
300     }
301 }
302
303 static CAResult_t CACreateMutex()
304 {
305     if (!g_mutexNetCallbackList)
306     {
307         g_mutexNetCallbackList = oc_mutex_new();
308         if (!g_mutexNetCallbackList)
309         {
310             return CA_STATUS_FAILED;
311         }
312     }
313
314     return CA_STATUS_OK;
315 }
316
317 void CAInitializeAdapters(ca_thread_pool_t handle, CATransportAdapter_t transportType)
318 {
319     OIC_LOG_V(DEBUG, TAG, "initialize adapters %d", transportType);
320
321     if (CA_STATUS_OK != CACreateMutex())
322     {
323         OIC_LOG(ERROR, TAG, "Failed to create mutex!");
324     }
325
326     // Initialize ssl adapter.
327 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
328     if (CA_STATUS_OK != CAinitSslAdapter())
329     {
330         OIC_LOG(ERROR, TAG, "Failed to init SSL adapter");
331     }
332 #endif
333
334     // Initialize adapters and register callback.
335 #ifdef IP_ADAPTER
336     if ((transportType & CA_ADAPTER_IP) || (CA_DEFAULT_ADAPTER == transportType)
337             || (transportType == CA_ALL_ADAPTERS))
338     {
339         CAInitializeIP(CARegisterCallback, (CANetworkPacketReceivedCallback)CAReceivedPacketCallback, CAAdapterChangedCallback,
340                        (CAErrorHandleCallback)CAAdapterErrorHandleCallback, handle);
341     }
342 #endif /* IP_ADAPTER */
343
344 #ifdef EDR_ADAPTER
345     if ((transportType & CA_ADAPTER_RFCOMM_BTEDR) || (CA_DEFAULT_ADAPTER == transportType)
346             || (transportType == CA_ALL_ADAPTERS))
347     {
348         CAInitializeEDR(CARegisterCallback, CAReceivedPacketCallback, CAAdapterChangedCallback,
349                         CAConnectionChangedCallback, CAAdapterErrorHandleCallback, handle);
350     }
351 #endif /* EDR_ADAPTER */
352
353 #ifdef LE_ADAPTER
354     if ((transportType & CA_ADAPTER_GATT_BTLE) || (CA_DEFAULT_ADAPTER == transportType)
355             || (transportType == CA_ALL_ADAPTERS))
356     {
357         CAInitializeLE(CARegisterCallback, (CANetworkPacketReceivedCallback)CAReceivedPacketCallback, CAAdapterChangedCallback,
358                        CAConnectionChangedCallback, (CAErrorHandleCallback)CAAdapterErrorHandleCallback, handle);
359     }
360 #endif /* LE_ADAPTER */
361
362 #ifdef RA_ADAPTER
363     if ((transportType & CA_ADAPTER_REMOTE_ACCESS) || (CA_DEFAULT_ADAPTER == transportType)
364             || (transportType == CA_ALL_ADAPTERS))
365     {
366         CAInitializeRA(CARegisterCallback, CAReceivedPacketCallback, CAAdapterChangedCallback,
367                        handle);
368     }
369 #endif /* RA_ADAPTER */
370
371 #ifdef TCP_ADAPTER
372     if ((transportType & CA_ADAPTER_TCP) || (CA_DEFAULT_ADAPTER == transportType)
373             || (transportType == CA_ALL_ADAPTERS))
374     {
375         CAInitializeTCP(CARegisterCallback, CAReceivedPacketCallback, CAAdapterChangedCallback,
376                         CAConnectionChangedCallback, CAAdapterErrorHandleCallback, handle);
377     }
378 #endif /* TCP_ADAPTER */
379
380 #ifdef NFC_ADAPTER
381     if ((transportType & CA_ADAPTER_NFC) || (CA_DEFAULT_ADAPTER == transportType)
382             || (transportType == CA_ALL_ADAPTERS))
383     {
384         CAInitializeNFC(CARegisterCallback, CAReceivedPacketCallback, CAAdapterChangedCallback,
385                         CAAdapterErrorHandleCallback, handle);
386     }
387 #endif /* NFC_ADAPTER */
388 }
389
390 void CASetPacketReceivedCallback(CANetworkPacketReceivedCallback callback)
391 {
392     OIC_LOG(DEBUG, TAG, "Set Receiver handle callback");
393
394     g_networkPacketReceivedCallback = callback;
395 }
396
397 void CASetNetworkMonitorCallbacks(CAAdapterStateChangedCB adapterCB,
398                                   CAConnectionStateChangedCB connCB)
399 {
400     OIC_LOG(DEBUG, TAG, "Set network monitoring callback");
401     CAResult_t res = AddNetworkStateChangedCallback(adapterCB, connCB);
402     if (CA_STATUS_OK != res)
403     {
404         OIC_LOG(ERROR, TAG, "AddNetworkStateChangedCallback has failed");
405     }
406 }
407
408 CAResult_t CAUnsetNetworkMonitorCallbacks(CAAdapterStateChangedCB adapterCB,
409                                           CAConnectionStateChangedCB connCB)
410 {
411     OIC_LOG(DEBUG, TAG, "Unset network monitoring callback");
412     CAResult_t res = RemoveNetworkStateChangedCallback(adapterCB, connCB);
413     if (CA_STATUS_OK != res)
414     {
415         OIC_LOG(ERROR, TAG, "RemoveNetworkStateChangedCallback has failed");
416     }
417     return res;
418 }
419
420 void CASetErrorHandleCallback(CAErrorHandleCallback errorCallback)
421 {
422     OIC_LOG(DEBUG, TAG, "Set error handle callback");
423     g_errorHandleCallback = errorCallback;
424 }
425
426 CAResult_t CAStartAdapter(CATransportAdapter_t transportType)
427 {
428     OIC_LOG_V(DEBUG, TAG, "Start the adapter of CAConnectivityType[%d]", transportType);
429
430     int index = CAGetAdapterIndex(transportType);
431     if (0 > index)
432     {
433         OIC_LOG(ERROR, TAG, "unknown connectivity type!");
434         return CA_STATUS_FAILED;
435     }
436
437     CAResult_t res = CA_STATUS_FAILED;
438     if (g_adapterHandler[index].startAdapter != NULL)
439     {
440         res = g_adapterHandler[index].startAdapter();
441     }
442
443     return res;
444 }
445
446 void CAStopAdapter(CATransportAdapter_t transportType)
447 {
448     OIC_LOG_V(DEBUG, TAG, "Stop the adapter of CATransportType[%d]", transportType);
449
450     int index = CAGetAdapterIndex(transportType);
451     if (0 > index)
452     {
453         OIC_LOG(ERROR, TAG, "unknown transport type!");
454         return;
455     }
456
457     if (g_adapterHandler[index].stopAdapter != NULL)
458     {
459         g_adapterHandler[index].stopAdapter();
460     }
461 }
462
463 CAResult_t CAGetNetworkInfo(CAEndpoint_t **info, uint32_t *size)
464 {
465     if (info == NULL || size == NULL)
466     {
467         return CA_STATUS_INVALID_PARAM;
468     }
469
470     CAEndpoint_t **tempInfo = (CAEndpoint_t**) OICCalloc(g_numberOfAdapters, sizeof(*tempInfo));
471     if (!tempInfo)
472     {
473         OIC_LOG(ERROR, TAG, "Out of memory!");
474         return CA_MEMORY_ALLOC_FAILED;
475     }
476     uint32_t *tempSize =(uint32_t*) OICCalloc(g_numberOfAdapters, sizeof(*tempSize));
477     if (!tempSize)
478     {
479         OIC_LOG(ERROR, TAG, "Out of memory!");
480         OICFree(tempInfo);
481         return CA_MEMORY_ALLOC_FAILED;
482     }
483
484     CAResult_t res = CA_STATUS_FAILED;
485     size_t resSize = 0;
486     for (uint32_t index = 0; index < g_numberOfAdapters; index++)
487     {
488         if (g_adapterHandler[index].GetnetInfo != NULL)
489         {
490             // #1. get information for each adapter
491             res = g_adapterHandler[index].GetnetInfo(&tempInfo[index],
492                                                      &tempSize[index]);
493
494             // #2. total size
495             if (res == CA_STATUS_OK)
496             {
497                 resSize += tempSize[index];
498             }
499
500 #ifndef __TIZENRT__
501             OIC_LOG_V(DEBUG,
502                       TAG,
503                       "%" PRIu32 " adapter network info size is %" PRIu32 " res:%d",
504                       index,
505                       tempSize[index],
506                       res);
507 #endif
508         }
509     }
510
511     OIC_LOG_V(DEBUG, TAG, "network info total size is %zu!", resSize);
512
513     if (resSize == 0)
514     {
515         OICFree(tempInfo);
516         OICFree(tempSize);
517         if (res == CA_ADAPTER_NOT_ENABLED || res == CA_NOT_SUPPORTED)
518         {
519             return res;
520         }
521         else
522         {
523             return CA_STATUS_FAILED;
524         }
525     }
526
527     // #3. add data into result
528     // memory allocation
529     CAEndpoint_t *resInfo = (CAEndpoint_t *) OICCalloc(resSize, sizeof (*resInfo));
530     CA_MEMORY_ALLOC_CHECK(resInfo);
531
532     // #4. save data
533     *info = resInfo;
534     *size = resSize;
535
536     for (uint32_t index = 0; index < g_numberOfAdapters; index++)
537     {
538         // check information
539         if (tempSize[index] == 0)
540         {
541             continue;
542         }
543
544         memcpy(resInfo,
545                tempInfo[index],
546                sizeof(*resInfo) * tempSize[index]);
547
548         resInfo += tempSize[index];
549
550         // free adapter data
551         OICFree(tempInfo[index]);
552         tempInfo[index] = NULL;
553     }
554     OICFree(tempInfo);
555     OICFree(tempSize);
556
557     OIC_LOG(DEBUG, TAG, "each network info save success!");
558     return CA_STATUS_OK;
559
560     // memory error label.
561 memory_error_exit:
562
563     for (uint32_t index = 0; index < g_numberOfAdapters; index++)
564     {
565         OICFree(tempInfo[index]);
566         tempInfo[index] = NULL;
567     }
568     OICFree(tempInfo);
569     OICFree(tempSize);
570
571     return CA_MEMORY_ALLOC_FAILED;
572 }
573
574 CAResult_t CASendUnicastData(const CAEndpoint_t *endpoint, const void *data, uint32_t length,
575                              CADataType_t dataType)
576 {
577     if (endpoint == NULL)
578     {
579         OIC_LOG(DEBUG, TAG, "Invalid endpoint");
580         return CA_STATUS_INVALID_PARAM;
581     }
582
583
584     u_arraylist_t *list = CAGetSelectedNetworkList();
585     if (!list)
586     {
587         OIC_LOG(ERROR, TAG, "No selected network");
588         return CA_SEND_FAILED;
589     }
590     CATransportAdapter_t requestedAdapter = endpoint->adapter ? endpoint->adapter : CA_ALL_ADAPTERS;
591
592     for (uint32_t i = 0; i < u_arraylist_length(list); i++)
593     {
594         void* ptrType = u_arraylist_get(list, i);
595
596         if (NULL == ptrType)
597         {
598             continue;
599         }
600
601         CATransportAdapter_t connType = *(CATransportAdapter_t *)ptrType;
602         if (0 == (connType & requestedAdapter))
603         {
604             continue;
605         }
606
607         int index = CAGetAdapterIndex(connType);
608
609         if (-1 == index)
610         {
611             OIC_LOG_V(ERROR, TAG, "unknown transport type[%d]", connType);
612             return CA_STATUS_INVALID_PARAM;
613         }
614
615         int32_t sentDataLen = 0;
616
617         if (NULL != g_adapterHandler[index].sendData)
618         {
619             OIC_LOG(DEBUG, TAG, "unicast message to adapter");
620             sentDataLen = g_adapterHandler[index].sendData(endpoint, data, length, dataType);
621         }
622
623         if (sentDataLen != (int32_t)length)
624         {
625             OIC_LOG(ERROR, TAG, "error in sending data. Error will be reported in adapter");
626 #ifdef SINGLE_THREAD
627             //in case of single thread, no error handler. Report error immediately
628             return CA_SEND_FAILED;
629 #endif
630         }
631
632     }
633
634     return CA_STATUS_OK;
635 }
636
637 CAResult_t CASendMulticastData(const CAEndpoint_t *endpoint, const void *data, uint32_t length,
638                                CADataType_t dataType)
639 {
640     u_arraylist_t *list = CAGetSelectedNetworkList();
641     if (!list)
642     {
643         OIC_LOG(DEBUG, TAG, "No selected network");
644         return CA_SEND_FAILED;
645     }
646
647     CATransportAdapter_t requestedAdapter = endpoint->adapter ? endpoint->adapter : CA_ALL_ADAPTERS;
648     size_t selectedLength = u_arraylist_length(list);
649     for (size_t i = 0; i < selectedLength; i++)
650     {
651         void* ptrType = u_arraylist_get(list, i);
652
653         if (NULL == ptrType)
654         {
655             continue;
656         }
657
658         CATransportAdapter_t connType = *(CATransportAdapter_t *)ptrType;
659         if (0 == (connType & requestedAdapter))
660         {
661             continue;
662         }
663
664         int index = CAGetAdapterIndex(connType);
665         if (0 > index)
666         {
667             OIC_LOG(ERROR, TAG, "unknown connectivity type!");
668             continue;
669         }
670
671         uint32_t sentDataLen = 0;
672
673         if (NULL != g_adapterHandler[index].sendDataToAll)
674         {
675             void *payload = (void *) OICMalloc(length);
676             if (!payload)
677             {
678                 OIC_LOG(ERROR, TAG, "Out of memory!");
679                 return CA_MEMORY_ALLOC_FAILED;
680             }
681             memcpy(payload, data, length);
682             sentDataLen = g_adapterHandler[index].sendDataToAll(endpoint, payload, length, dataType);
683             OICFree(payload);
684         }
685
686         if (sentDataLen != length)
687         {
688             OIC_LOG(ERROR, TAG, "sendDataToAll failed! Error will be reported from adapter");
689 #ifdef SINGLE_THREAD
690             //in case of single thread, no error handler. Report error immediately
691             return CA_SEND_FAILED;
692 #endif
693         }
694     }
695
696     return CA_STATUS_OK;
697 }
698
699 CAResult_t CAStartListeningServerAdapters()
700 {
701     CAResult_t result = CA_STATUS_FAILED;
702
703     u_arraylist_t *list = CAGetSelectedNetworkList();
704     if (!list)
705     {
706         OIC_LOG(ERROR, TAG, "No selected network");
707         return result;
708     }
709
710     size_t length = u_arraylist_length(list);
711     for (size_t i = 0; i < length; i++)
712     {
713         void* ptrType = u_arraylist_get(list, i);
714
715         if(ptrType == NULL)
716         {
717             continue;
718         }
719
720         CATransportAdapter_t connType = *(CATransportAdapter_t *)ptrType;
721
722         int index = CAGetAdapterIndex(connType);
723         if (0 > index)
724         {
725             OIC_LOG(ERROR, TAG, "unknown connectivity type!");
726             continue;
727         }
728
729         if (g_adapterHandler[index].startListenServer != NULL)
730         {
731             const CAResult_t tmp =
732                 g_adapterHandler[index].startListenServer();
733
734             // Successful listen if at least one adapter started.
735             if (CA_STATUS_OK == tmp)
736             {
737                 result = tmp;
738             }
739         }
740     }
741
742     return result;
743 }
744
745 CAResult_t CAStopListeningServerAdapters()
746 {
747     u_arraylist_t *list = CAGetSelectedNetworkList();
748     if (!list)
749     {
750         OIC_LOG(ERROR, TAG, "No selected network");
751         return CA_STATUS_FAILED;
752     }
753
754     size_t length = u_arraylist_length(list);
755     for (size_t i = 0; i < length; i++)
756     {
757         void* ptrType = u_arraylist_get(list, i);
758         if(ptrType == NULL)
759         {
760             continue;
761         }
762
763         CATransportAdapter_t connType = *(CATransportAdapter_t *)ptrType;
764
765         int index = CAGetAdapterIndex(connType);
766         if (0 > index)
767         {
768             OIC_LOG(ERROR, TAG, "unknown connectivity type!");
769             continue;
770         }
771
772         if (g_adapterHandler[index].stopListenServer != NULL)
773         {
774             g_adapterHandler[index].stopListenServer();
775         }
776     }
777
778     return CA_STATUS_OK;
779 }
780
781 CAResult_t CAStartDiscoveryServerAdapters()
782 {
783     CAResult_t result = CA_STATUS_FAILED;
784
785     u_arraylist_t *list = CAGetSelectedNetworkList();
786
787     if (!list)
788     {
789         OIC_LOG(ERROR, TAG, "No selected network");
790         return result;
791     }
792
793     size_t length = u_arraylist_length(list);
794     for (size_t i = 0; i < length; i++)
795     {
796         void* ptrType = u_arraylist_get(list, i);
797
798         if(ptrType == NULL)
799         {
800             continue;
801         }
802
803         CATransportAdapter_t connType = *(CATransportAdapter_t *)ptrType;
804
805         int index = CAGetAdapterIndex(connType);
806         if (0 > index)
807         {
808             OIC_LOG(DEBUG, TAG, "unknown connectivity type!");
809             continue;
810         }
811
812         if (g_adapterHandler[index].startDiscoveryServer != NULL)
813         {
814             const CAResult_t tmp =
815                 g_adapterHandler[index].startDiscoveryServer();
816
817             // Successful discovery if at least one adapter started.
818             if (CA_STATUS_OK == tmp)
819             {
820                 result = tmp;
821             }
822         }
823     }
824
825     return result;
826 }
827
828 void CATerminateAdapters()
829 {
830     CADestroyMutex();
831
832     for (uint32_t index = 0; index < g_numberOfAdapters; index++)
833     {
834         if (g_adapterHandler[index].terminate != NULL)
835         {
836             g_adapterHandler[index].terminate();
837         }
838     }
839
840 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
841     CAdeinitSslAdapter();
842 #endif
843
844     OICFree(g_adapterHandler);
845     g_adapterHandler = NULL;
846     g_numberOfAdapters = 0;
847 }
848
849 #ifdef SINGLE_THREAD
850 CAResult_t CAReadData()
851 {
852     u_arraylist_t *list = CAGetSelectedNetworkList();
853
854     if (!list)
855     {
856         return CA_STATUS_FAILED;
857     }
858
859     uint8_t i = 0;
860     for (i = 0; i < u_arraylist_length(list); i++)
861     {
862         void *ptrType = u_arraylist_get(list, i);
863         if (NULL == ptrType)
864         {
865             OIC_LOG(ERROR, TAG, "get list fail");
866             return CA_STATUS_FAILED;
867         }
868
869         CATransportAdapter_t connType = *(CATransportAdapter_t *) ptrType;
870
871         int index = CAGetAdapterIndex(connType);
872         if (0 > index)
873         {
874             OIC_LOG(DEBUG, TAG, "unknown connectivity type!");
875             continue;
876         }
877
878         if (g_adapterHandler[index].readData != NULL)
879         {
880             g_adapterHandler[index].readData();
881         }
882     }
883
884     return CA_STATUS_OK;
885 }
886 #endif
887
888 #ifdef IP_ADAPTER
889 CAResult_t CASetMulticastTTL(size_t ttl)
890 {
891     return CAIPSetMulticastTTL(ttl);
892 }
893
894 CAResult_t CAGetMulticastTTL(size_t *ttl)
895 {
896     return CAIPGetMulticastTTL(ttl);
897 }
898 #endif
899
900 #ifdef TCP_ADAPTER
901 CAResult_t CADisconnectSession(const CAEndpoint_t *endpoint)
902 {
903     return CATCPDisconnectSession(endpoint);
904 }
905 #endif
906
907 #ifdef LE_ADAPTER
908 void CAStartGattServer()
909 {
910         CALEStartGattServer();
911 }
912
913 void CAStopGattServer()
914 {
915         CALEStopGattServer();
916 }
917 #endif