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