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