Merge "Merge Resource Directory into the master"
[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     u_arraylist_t *list = CAGetSelectedNetworkList();
473     if (!list)
474     {
475         OIC_LOG(ERROR, TAG, "No selected network");
476         return CA_STATUS_FAILED;
477     }
478
479     for (uint32_t i = 0; i < u_arraylist_length(list); i++)
480     {
481         void* ptrType = u_arraylist_get(list, i);
482
483         if(ptrType == NULL)
484         {
485             continue;
486         }
487
488         CATransportAdapter_t connType = *(CATransportAdapter_t *)ptrType;
489
490         int index = CAGetAdapterIndex(connType);
491         if (index == -1)
492         {
493             OIC_LOG(ERROR, TAG, "unknown connectivity type!");
494             continue;
495         }
496
497         if (g_adapterHandler[index].startListenServer != NULL)
498         {
499             g_adapterHandler[index].startListenServer();
500         }
501     }
502
503     OIC_LOG(DEBUG, TAG, "OUT");
504     return CA_STATUS_OK;
505 }
506
507 CAResult_t CAStopListeningServerAdapters()
508 {
509     OIC_LOG(DEBUG, TAG, "IN");
510
511     u_arraylist_t *list = CAGetSelectedNetworkList();
512     if (!list)
513     {
514         OIC_LOG(ERROR, TAG, "No selected network");
515         return CA_STATUS_FAILED;
516     }
517
518     for (uint32_t i = 0; i < u_arraylist_length(list); i++)
519     {
520         void* ptrType = u_arraylist_get(list, i);
521         if(ptrType == NULL)
522         {
523             continue;
524         }
525
526         CATransportAdapter_t connType = *(CATransportAdapter_t *)ptrType;
527
528         int index = CAGetAdapterIndex(connType);
529         if (index == -1)
530         {
531             OIC_LOG(ERROR, TAG, "unknown connectivity type!");
532             continue;
533         }
534
535         if (g_adapterHandler[index].stopListenServer != NULL)
536         {
537             g_adapterHandler[index].stopListenServer();
538         }
539     }
540
541     OIC_LOG(DEBUG, TAG, "OUT");
542     return CA_STATUS_OK;
543 }
544
545 CAResult_t CAStartDiscoveryServerAdapters()
546 {
547     OIC_LOG(DEBUG, TAG, "IN");
548
549     u_arraylist_t *list = CAGetSelectedNetworkList();
550
551     if (!list)
552     {
553         OIC_LOG(ERROR, TAG, "No selected network");
554         return CA_STATUS_FAILED;
555     }
556
557     for (uint32_t i = 0; i < u_arraylist_length(list); i++)
558     {
559         void* ptrType = u_arraylist_get(list, i);
560
561         if(ptrType == NULL)
562         {
563             continue;
564         }
565
566         CATransportAdapter_t connType = *(CATransportAdapter_t *)ptrType;
567
568         int index = CAGetAdapterIndex(connType);
569
570         if (index == -1)
571         {
572             OIC_LOG(DEBUG, TAG, "unknown connectivity type!");
573             continue;
574         }
575
576         if (g_adapterHandler[index].startDiscoveryServer != NULL)
577         {
578             g_adapterHandler[index].startDiscoveryServer();
579         }
580     }
581
582     OIC_LOG(DEBUG, TAG, "OUT");
583     return CA_STATUS_OK;
584 }
585
586 void CATerminateAdapters()
587 {
588     OIC_LOG(DEBUG, TAG, "IN");
589
590     uint32_t index;
591     for (index = 0; index < CA_TRANSPORT_TYPE_NUM; index++)
592     {
593         if (g_adapterHandler[index].terminate != NULL)
594         {
595             g_adapterHandler[index].terminate();
596         }
597     }
598
599     OIC_LOG(DEBUG, TAG, "OUT");
600 }
601
602 #ifdef SINGLE_THREAD
603 CAResult_t CAReadData()
604 {
605     OIC_LOG(DEBUG, TAG, "IN");
606     u_arraylist_t *list = CAGetSelectedNetworkList();
607
608     if (!list)
609     {
610         return CA_STATUS_FAILED;
611     }
612
613     uint8_t i = 0;
614     for (i = 0; i < u_arraylist_length(list); i++)
615     {
616         void *ptrType = u_arraylist_get(list, i);
617         if (NULL == ptrType)
618         {
619             OIC_LOG(ERROR, TAG, "get list fail");
620             return CA_STATUS_FAILED;
621         }
622
623         CATransportAdapter_t connType = *(CATransportAdapter_t *) ptrType;
624
625         int index = CAGetAdapterIndex(connType);
626
627         if (-1 == index)
628         {
629             OIC_LOG(DEBUG, TAG, "unknown connectivity type!");
630             continue;
631         }
632
633         if (g_adapterHandler[index].readData != NULL)
634         {
635             g_adapterHandler[index].readData();
636         }
637     }
638
639     OIC_LOG(DEBUG, TAG, "OUT");
640     return CA_STATUS_OK;
641 }
642 #endif
643