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