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