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