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