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