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