[IOT-898] Propagate result of CA discovery/listen start call.
[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 "caremotehandler.h"
34 #include "cathreadpool.h"
35 #include "caipadapter.h"
36 #include "cainterface.h"
37
38 #ifdef RA_ADAPTER
39 #include "caraadapter.h"
40 #endif
41
42 #ifdef TCP_ADAPTER
43 #include "catcpadapter.h"
44 #endif
45
46 #define TAG "CA_INTRFC_CNTRLR"
47
48 #define CA_MEMORY_ALLOC_CHECK(arg) {if (arg == NULL) \
49     {OIC_LOG(ERROR, TAG, "memory error");goto memory_error_exit;} }
50
51 #ifdef TCP_ADAPTER
52 #define CA_TRANSPORT_TYPE_NUM   5
53 #elif RA_ADAPTER
54 #define CA_TRANSPORT_TYPE_NUM   4
55 #else
56 #define CA_TRANSPORT_TYPE_NUM   3
57 #endif
58
59 static CAConnectivityHandler_t g_adapterHandler[CA_TRANSPORT_TYPE_NUM] = {};
60
61 static CANetworkPacketReceivedCallback g_networkPacketReceivedCallback = NULL;
62
63 static CANetworkChangeCallback g_networkChangeCallback = NULL;
64
65 static CAErrorHandleCallback g_errorHandleCallback = NULL;
66
67 static int CAGetAdapterIndex(CATransportAdapter_t cType)
68 {
69     switch (cType)
70     {
71         case CA_ADAPTER_IP:
72             return 0;
73         case CA_ADAPTER_GATT_BTLE:
74             return 1;
75         case CA_ADAPTER_RFCOMM_BTEDR:
76             return 2;
77
78 #ifdef RA_ADAPTER
79         case CA_ADAPTER_REMOTE_ACCESS:
80             return 3;
81 #endif
82
83 #ifdef TCP_ADAPTER
84         case CA_ADAPTER_TCP:
85             return 4;
86 #endif
87
88         default:
89             break;
90     }
91     return -1;
92 }
93
94 static void CARegisterCallback(CAConnectivityHandler_t handler, CATransportAdapter_t cType)
95 {
96     OIC_LOG(DEBUG, TAG, "IN");
97
98     if(handler.startAdapter == NULL ||
99         handler.startListenServer == NULL ||
100         handler.stopListenServer == NULL ||
101         handler.startDiscoveryServer == NULL ||
102         handler.sendData == NULL ||
103         handler.sendDataToAll == NULL ||
104         handler.GetnetInfo == NULL ||
105         handler.readData == NULL ||
106         handler.stopAdapter == NULL ||
107         handler.terminate == NULL)
108     {
109         OIC_LOG(ERROR, TAG, "connectivity handler is not enough to be used!");
110         return;
111     }
112
113     int index = CAGetAdapterIndex(cType);
114
115     if (index == -1)
116     {
117         OIC_LOG(ERROR, TAG, "unknown connectivity type!");
118         return;
119     }
120
121     g_adapterHandler[index] = handler;
122
123     OIC_LOG_V(DEBUG, TAG, "%d type adapter, register complete!", cType);
124     OIC_LOG(DEBUG, TAG, "OUT");
125 }
126
127 #ifdef RA_ADAPTER
128 CAResult_t CASetAdapterRAInfo(const CARAInfo_t *caraInfo)
129 {
130     return CASetRAInfo(caraInfo);
131 }
132 #endif
133
134 static void CAReceivedPacketCallback(const CASecureEndpoint_t *sep,
135                                      const void *data, uint32_t dataLen)
136 {
137     OIC_LOG(DEBUG, TAG, "IN");
138
139     if (g_networkPacketReceivedCallback != NULL)
140     {
141         g_networkPacketReceivedCallback(sep, data, dataLen);
142     }
143     else
144     {
145         OIC_LOG(ERROR, TAG, "network packet received callback is NULL!");
146     }
147
148     OIC_LOG(DEBUG, TAG, "OUT");
149 }
150
151 static void CANetworkChangedCallback(const CAEndpoint_t *info, CANetworkStatus_t status)
152 {
153     OIC_LOG(DEBUG, TAG, "IN");
154
155     // Call the callback.
156     if (g_networkChangeCallback != NULL)
157     {
158         g_networkChangeCallback(info, status);
159     }
160
161     OIC_LOG(DEBUG, TAG, "OUT");
162 }
163
164 static void CAAdapterErrorHandleCallback(const CAEndpoint_t *endpoint,
165                                          const void *data, uint32_t dataLen,
166                                          CAResult_t result)
167 {
168     OIC_LOG(DEBUG, TAG, "received error from adapter in interfacecontroller");
169
170     // Call the callback.
171     if (g_errorHandleCallback != NULL)
172     {
173         g_errorHandleCallback(endpoint, data, dataLen, result);
174     }
175 }
176
177 void CAInitializeAdapters(ca_thread_pool_t handle)
178 {
179     OIC_LOG(DEBUG, TAG, "initialize adapters..");
180
181     memset(g_adapterHandler, 0, sizeof(CAConnectivityHandler_t) * CA_TRANSPORT_TYPE_NUM);
182
183     // Initialize adapters and register callback.
184 #ifdef IP_ADAPTER
185     CAInitializeIP(CARegisterCallback, CAReceivedPacketCallback, CANetworkChangedCallback,
186                    CAAdapterErrorHandleCallback, handle);
187 #endif /* IP_ADAPTER */
188
189 #ifdef EDR_ADAPTER
190     CAInitializeEDR(CARegisterCallback, CAReceivedPacketCallback, CANetworkChangedCallback,
191                     CAAdapterErrorHandleCallback, handle);
192 #endif /* EDR_ADAPTER */
193
194 #ifdef LE_ADAPTER
195     CAInitializeLE(CARegisterCallback, CAReceivedPacketCallback, CANetworkChangedCallback,
196                    CAAdapterErrorHandleCallback, handle);
197 #endif /* LE_ADAPTER */
198
199 #ifdef RA_ADAPTER
200     CAInitializeRA(CARegisterCallback, CAReceivedPacketCallback, CANetworkChangedCallback,
201                    handle);
202 #endif /* RA_ADAPTER */
203
204 #ifdef TCP_ADAPTER
205     CAInitializeTCP(CARegisterCallback, CAReceivedPacketCallback, CANetworkChangedCallback,
206                     CAAdapterErrorHandleCallback, handle);
207 #endif /* TCP_ADAPTER */
208 }
209
210 void CASetPacketReceivedCallback(CANetworkPacketReceivedCallback callback)
211 {
212     OIC_LOG(DEBUG, TAG, "IN");
213
214     g_networkPacketReceivedCallback = callback;
215
216     OIC_LOG(DEBUG, TAG, "OUT");
217 }
218
219 void CASetNetworkChangeCallback(CANetworkChangeCallback callback)
220 {
221     OIC_LOG(DEBUG, TAG, "IN");
222
223     g_networkChangeCallback = callback;
224
225     OIC_LOG(DEBUG, TAG, "OUT");
226 }
227
228 void CASetErrorHandleCallback(CAErrorHandleCallback errorCallback)
229 {
230     OIC_LOG(DEBUG, TAG, "Set error handle callback");
231     g_errorHandleCallback = errorCallback;
232 }
233
234 CAResult_t CAStartAdapter(CATransportAdapter_t transportType)
235 {
236     OIC_LOG_V(DEBUG, TAG, "Start the adapter of CAConnectivityType[%d]", transportType);
237
238     int index = CAGetAdapterIndex(transportType);
239
240     if (index == -1)
241     {
242         OIC_LOG(ERROR, TAG, "unknown connectivity type!");
243         return CA_STATUS_FAILED;
244     }
245
246     if (g_adapterHandler[index].startAdapter != NULL)
247     {
248         g_adapterHandler[index].startAdapter();
249     }
250
251     return CA_STATUS_OK;
252 }
253
254 void CAStopAdapter(CATransportAdapter_t transportType)
255 {
256     OIC_LOG_V(DEBUG, TAG, "Stop the adapter of CATransportType[%d]", transportType);
257
258     int index = CAGetAdapterIndex(transportType);
259
260     if (index == -1)
261     {
262         OIC_LOG(ERROR, TAG, "unknown transport type!");
263         return;
264     }
265
266     if (g_adapterHandler[index].stopAdapter != NULL)
267     {
268         g_adapterHandler[index].stopAdapter();
269     }
270 }
271
272 CAResult_t CAGetNetworkInfo(CAEndpoint_t **info, uint32_t *size)
273 {
274     if (info == NULL || size == NULL)
275     {
276         return CA_STATUS_INVALID_PARAM;
277     }
278
279     CAEndpoint_t *tempInfo[CA_TRANSPORT_TYPE_NUM] = { 0 };
280     uint32_t tempSize[CA_TRANSPORT_TYPE_NUM] = { 0 };
281
282     CAResult_t res = CA_STATUS_FAILED;
283     uint32_t resSize = 0;
284     for (int index = 0; index < CA_TRANSPORT_TYPE_NUM; index++)
285     {
286         if (g_adapterHandler[index].GetnetInfo != NULL)
287         {
288             // #1. get information for each adapter
289             res = g_adapterHandler[index].GetnetInfo(&tempInfo[index],
290                                                      &tempSize[index]);
291
292             // #2. total size
293             if (res == CA_STATUS_OK)
294             {
295                 resSize += tempSize[index];
296             }
297
298             OIC_LOG_V(DEBUG,
299                       TAG,
300                       "%d adapter network info size is %" PRIu32 " res:%d",
301                       index,
302                       tempSize[index],
303                       res);
304         }
305     }
306
307     OIC_LOG_V(DEBUG, TAG, "network info total size is %d!", resSize);
308
309     if (resSize == 0)
310     {
311         if (res == CA_ADAPTER_NOT_ENABLED || res == CA_NOT_SUPPORTED)
312         {
313             return res;
314         }
315         return CA_STATUS_FAILED;
316     }
317
318     // #3. add data into result
319     // memory allocation
320     CAEndpoint_t *resInfo = (CAEndpoint_t *) OICCalloc(resSize, sizeof (*resInfo));
321     CA_MEMORY_ALLOC_CHECK(resInfo);
322
323     // #4. save data
324     *info = resInfo;
325     *size = resSize;
326
327     for (int index = 0; index < CA_TRANSPORT_TYPE_NUM; index++)
328     {
329         // check information
330         if (tempSize[index] == 0)
331         {
332             continue;
333         }
334
335         memcpy(resInfo,
336                tempInfo[index],
337                sizeof(*resInfo) * tempSize[index]);
338
339         resInfo += tempSize[index];
340
341         // free adapter data
342         OICFree(tempInfo[index]);
343         tempInfo[index] = NULL;
344     }
345
346     OIC_LOG(DEBUG, TAG, "each network info save success!");
347     return CA_STATUS_OK;
348
349     // memory error label.
350 memory_error_exit:
351
352     for (int index = 0; index < CA_TRANSPORT_TYPE_NUM; index++)
353     {
354
355         OICFree(tempInfo[index]);
356         tempInfo[index] = NULL;
357     }
358
359     return CA_MEMORY_ALLOC_FAILED;
360 }
361
362 CAResult_t CASendUnicastData(const CAEndpoint_t *endpoint, const void *data, uint32_t length)
363 {
364     OIC_LOG(DEBUG, TAG, "IN");
365
366     if (endpoint == NULL)
367     {
368         OIC_LOG(DEBUG, TAG, "Invalid endpoint");
369         return CA_STATUS_INVALID_PARAM;
370     }
371
372     CATransportAdapter_t type = endpoint->adapter;
373
374     int index = CAGetAdapterIndex(type);
375
376     if (index == -1)
377     {
378         OIC_LOG(ERROR, TAG, "unknown transport type!");
379         return CA_STATUS_INVALID_PARAM;
380     }
381
382     int32_t sentDataLen = 0;
383
384     if (g_adapterHandler[index].sendData != NULL)
385     {
386         sentDataLen = g_adapterHandler[index].sendData(endpoint, data, length);
387     }
388
389     if (sentDataLen != (int)length)
390     {
391         OIC_LOG(ERROR, TAG, "error in sending data. Error will be reported in adapter");
392 #ifdef SINGLE_THREAD
393         //in case of single thread, no error handler. Report error immediately
394         return CA_SEND_FAILED;
395 #endif
396     }
397
398     OIC_LOG(DEBUG, TAG, "OUT");
399     return CA_STATUS_OK;
400 }
401
402 CAResult_t CASendMulticastData(const CAEndpoint_t *endpoint, const void *data, uint32_t length)
403 {
404     OIC_LOG(DEBUG, TAG, "IN");
405
406     u_arraylist_t *list = CAGetSelectedNetworkList();
407     if (!list)
408     {
409         OIC_LOG(DEBUG, TAG, "No selected network");
410         return CA_SEND_FAILED;
411     }
412
413     CATransportFlags_t requestedAdapter = endpoint->adapter ? endpoint->adapter : CA_ALL_ADAPTERS;
414
415     for (uint32_t i = 0; i < u_arraylist_length(list); i++)
416     {
417         void* ptrType = u_arraylist_get(list, i);
418
419         if(ptrType == NULL)
420         {
421             continue;
422         }
423
424         CATransportAdapter_t connType = *(CATransportAdapter_t *)ptrType;
425         if ((connType & requestedAdapter) == 0)
426         {
427             continue;
428         }
429
430         int index = CAGetAdapterIndex(connType);
431
432         if (index == -1)
433         {
434             OIC_LOG(DEBUG, TAG, "unknown connectivity type!");
435             continue;
436         }
437
438         uint32_t sentDataLen = 0;
439
440         if (g_adapterHandler[index].sendDataToAll != NULL)
441         {
442             void *payload = (void *) OICMalloc(length);
443             if (!payload)
444             {
445                 OIC_LOG(ERROR, TAG, "Out of memory!");
446                 return CA_MEMORY_ALLOC_FAILED;
447             }
448             memcpy(payload, data, length);
449             sentDataLen = g_adapterHandler[index].sendDataToAll(endpoint, payload, length);
450             OICFree(payload);
451         }
452
453         if (sentDataLen != length)
454         {
455             OIC_LOG(ERROR, TAG, "sendDataToAll failed! Error will be reported from adapter");
456 #ifdef SINGLE_THREAD
457             //in case of single thread, no error handler. Report error immediately
458             return CA_SEND_FAILED;
459 #endif
460         }
461     }
462
463     OIC_LOG(DEBUG, TAG, "OUT");
464
465     return CA_STATUS_OK;
466 }
467
468 CAResult_t CAStartListeningServerAdapters()
469 {
470     OIC_LOG(DEBUG, TAG, "IN");
471
472     CAResult_t result = CA_STATUS_FAILED;
473
474     u_arraylist_t *list = CAGetSelectedNetworkList();
475     if (!list)
476     {
477         OIC_LOG(ERROR, TAG, "No selected network");
478         return result;
479     }
480
481     for (uint32_t i = 0; i < u_arraylist_length(list); i++)
482     {
483         void* ptrType = u_arraylist_get(list, i);
484
485         if(ptrType == NULL)
486         {
487             continue;
488         }
489
490         CATransportAdapter_t connType = *(CATransportAdapter_t *)ptrType;
491
492         int index = CAGetAdapterIndex(connType);
493         if (index == -1)
494         {
495             OIC_LOG(ERROR, TAG, "unknown connectivity type!");
496             continue;
497         }
498
499         if (g_adapterHandler[index].startListenServer != NULL)
500         {
501             const CAResult_t tmp =
502                 g_adapterHandler[index].startListenServer();
503
504             // Successful listen if at least one adapter started.
505             if (CA_STATUS_OK == tmp)
506             {
507                 result = tmp;
508             }
509         }
510     }
511
512     OIC_LOG(DEBUG, TAG, "OUT");
513     return result;
514 }
515
516 CAResult_t CAStopListeningServerAdapters()
517 {
518     OIC_LOG(DEBUG, TAG, "IN");
519
520     u_arraylist_t *list = CAGetSelectedNetworkList();
521     if (!list)
522     {
523         OIC_LOG(ERROR, TAG, "No selected network");
524         return CA_STATUS_FAILED;
525     }
526
527     for (uint32_t i = 0; i < u_arraylist_length(list); i++)
528     {
529         void* ptrType = u_arraylist_get(list, i);
530         if(ptrType == NULL)
531         {
532             continue;
533         }
534
535         CATransportAdapter_t connType = *(CATransportAdapter_t *)ptrType;
536
537         int index = CAGetAdapterIndex(connType);
538         if (index == -1)
539         {
540             OIC_LOG(ERROR, TAG, "unknown connectivity type!");
541             continue;
542         }
543
544         if (g_adapterHandler[index].stopListenServer != NULL)
545         {
546             g_adapterHandler[index].stopListenServer();
547         }
548     }
549
550     OIC_LOG(DEBUG, TAG, "OUT");
551     return CA_STATUS_OK;
552 }
553
554 CAResult_t CAStartDiscoveryServerAdapters()
555 {
556     OIC_LOG(DEBUG, TAG, "IN");
557
558     CAResult_t result = CA_STATUS_FAILED;
559
560     u_arraylist_t *list = CAGetSelectedNetworkList();
561
562     if (!list)
563     {
564         OIC_LOG(ERROR, TAG, "No selected network");
565         return result;
566     }
567
568     for (uint32_t i = 0; i < u_arraylist_length(list); i++)
569     {
570         void* ptrType = u_arraylist_get(list, i);
571
572         if(ptrType == NULL)
573         {
574             continue;
575         }
576
577         CATransportAdapter_t connType = *(CATransportAdapter_t *)ptrType;
578
579         int index = CAGetAdapterIndex(connType);
580
581         if (index == -1)
582         {
583             OIC_LOG(DEBUG, TAG, "unknown connectivity type!");
584             continue;
585         }
586
587         if (g_adapterHandler[index].startDiscoveryServer != NULL)
588         {
589             const CAResult_t tmp =
590                 g_adapterHandler[index].startDiscoveryServer();
591
592             // Successful discovery if at least one adapter started.
593             if (CA_STATUS_OK == tmp)
594             {
595                 result = tmp;
596             }
597         }
598     }
599
600     OIC_LOG(DEBUG, TAG, "OUT");
601     return result;
602 }
603
604 void CATerminateAdapters()
605 {
606     OIC_LOG(DEBUG, TAG, "IN");
607
608     uint32_t index;
609     for (index = 0; index < CA_TRANSPORT_TYPE_NUM; index++)
610     {
611         if (g_adapterHandler[index].terminate != NULL)
612         {
613             g_adapterHandler[index].terminate();
614         }
615     }
616
617     OIC_LOG(DEBUG, TAG, "OUT");
618 }
619
620 #ifdef SINGLE_THREAD
621 CAResult_t CAReadData()
622 {
623     OIC_LOG(DEBUG, TAG, "IN");
624     u_arraylist_t *list = CAGetSelectedNetworkList();
625
626     if (!list)
627     {
628         return CA_STATUS_FAILED;
629     }
630
631     uint8_t i = 0;
632     for (i = 0; i < u_arraylist_length(list); i++)
633     {
634         void *ptrType = u_arraylist_get(list, i);
635         if (NULL == ptrType)
636         {
637             OIC_LOG(ERROR, TAG, "get list fail");
638             return CA_STATUS_FAILED;
639         }
640
641         CATransportAdapter_t connType = *(CATransportAdapter_t *) ptrType;
642
643         int index = CAGetAdapterIndex(connType);
644
645         if (-1 == index)
646         {
647             OIC_LOG(DEBUG, TAG, "unknown connectivity type!");
648             continue;
649         }
650
651         if (g_adapterHandler[index].readData != NULL)
652         {
653             g_adapterHandler[index].readData();
654         }
655     }
656
657     OIC_LOG(DEBUG, TAG, "OUT");
658     return CA_STATUS_OK;
659 }
660 #endif
661