IP adapter error handling
[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,
151                    CAAdapterErrorHandleCallback, handle);
152 #endif /* IP_ADAPTER */
153
154 #ifdef EDR_ADAPTER
155     CAInitializeEDR(CARegisterCallback, CAReceivedPacketCallback, CANetworkChangedCallback,
156                     CAAdapterErrorHandleCallback, handle);
157 #endif /* EDR_ADAPTER */
158
159 #ifdef LE_ADAPTER
160     CAInitializeLE(CARegisterCallback, CAReceivedPacketCallback, CANetworkChangedCallback,
161                    CAAdapterErrorHandleCallback, handle);
162 #endif /* LE_ADAPTER */
163
164 }
165
166 void CASetPacketReceivedCallback(CANetworkPacketReceivedCallback callback)
167 {
168     OIC_LOG(DEBUG, TAG, "Set packet received callback");
169
170     g_networkPacketReceivedCallback = callback;
171 }
172
173 void CASetNetworkChangeCallback(CANetworkChangeCallback callback)
174 {
175     OIC_LOG(DEBUG, TAG, "Set network change callback");
176
177     g_networkChangeCallback = callback;
178 }
179
180 void CASetErrorHandleCallback(CAErrorHandleCallback errorCallback)
181 {
182     OIC_LOG(DEBUG, TAG, "Set error handle callback");
183     g_errorHandleCallback = errorCallback;
184 }
185
186 CAResult_t CAStartAdapter(CATransportAdapter_t transportType)
187 {
188     OIC_LOG_V(DEBUG, TAG, "Start the adapter of CAConnectivityType[%d]", transportType);
189
190     int index = CAGetAdapterIndex(transportType);
191
192     if (index == -1)
193     {
194         OIC_LOG(ERROR, TAG, "unknown connectivity type!");
195         return CA_STATUS_FAILED;
196     }
197
198     if (g_adapterHandler[index].startAdapter != NULL)
199     {
200         g_adapterHandler[index].startAdapter();
201     }
202
203     return CA_STATUS_OK;
204 }
205
206 void CAStopAdapter(CATransportAdapter_t transportType)
207 {
208     OIC_LOG_V(DEBUG, TAG, "Stop the adapter of CATransportType[%d]", transportType);
209
210     int index = CAGetAdapterIndex(transportType);
211
212     if (index == -1)
213     {
214         OIC_LOG(ERROR, TAG, "unknown transport type!");
215         return;
216     }
217
218     if (g_adapterHandler[index].stopAdapter != NULL)
219     {
220         g_adapterHandler[index].stopAdapter();
221     }
222 }
223
224 CAResult_t CAGetNetworkInfo(CAEndpoint_t **info, uint32_t *size)
225 {
226     if (info == NULL || size == NULL)
227     {
228         return CA_STATUS_INVALID_PARAM;
229     }
230
231     CAEndpoint_t *tempInfo[CA_TRANSPORT_TYPE_NUM] = { 0 };
232     uint32_t tempSize[CA_TRANSPORT_TYPE_NUM] = { 0 };
233
234     CAResult_t res = CA_STATUS_FAILED;
235     uint32_t resSize = 0;
236     for (int index = 0; index < CA_TRANSPORT_TYPE_NUM; index++)
237     {
238         if (g_adapterHandler[index].GetnetInfo != NULL)
239         {
240             // #1. get information for each adapter
241             res = g_adapterHandler[index].GetnetInfo(&tempInfo[index],
242                                                      &tempSize[index]);
243
244             // #2. total size
245             if (res == CA_STATUS_OK)
246             {
247                 resSize += tempSize[index];
248             }
249
250             OIC_LOG_V(DEBUG,
251                       TAG,
252                       "%d adapter network info size is %" PRIu32 " res:%d",
253                       index,
254                       tempSize[index],
255                       res);
256         }
257     }
258
259     OIC_LOG_V(DEBUG, TAG, "network info total size is %d!", resSize);
260
261     if (resSize == 0)
262     {
263         if (res == CA_ADAPTER_NOT_ENABLED || res == CA_NOT_SUPPORTED)
264         {
265             return res;
266         }
267         return CA_STATUS_FAILED;
268     }
269
270     // #3. add data into result
271     // memory allocation
272     CAEndpoint_t *resInfo = (CAEndpoint_t *) OICCalloc(resSize, sizeof (*resInfo));
273     CA_MEMORY_ALLOC_CHECK(resInfo);
274
275     // #4. save data
276     *info = resInfo;
277     *size = resSize;
278
279     for (int index = 0; index < CA_TRANSPORT_TYPE_NUM; index++)
280     {
281         // check information
282         if (tempSize[index] == 0)
283         {
284             continue;
285         }
286
287         memcpy(resInfo,
288                tempInfo[index],
289                sizeof(*resInfo) * tempSize[index]);
290
291         resInfo += tempSize[index];
292
293         // free adapter data
294         OICFree(tempInfo[index]);
295         tempInfo[index] = NULL;
296     }
297
298     OIC_LOG(DEBUG, TAG, "each network info save success!");
299     return CA_STATUS_OK;
300
301     // memory error label.
302 memory_error_exit:
303
304     for (int index = 0; index < CA_TRANSPORT_TYPE_NUM; index++)
305     {
306
307         OICFree(tempInfo[index]);
308         tempInfo[index] = NULL;
309     }
310
311     return CA_MEMORY_ALLOC_FAILED;
312 }
313
314 CAResult_t CASendUnicastData(const CAEndpoint_t *endpoint, const void *data, uint32_t length)
315 {
316     OIC_LOG(DEBUG, TAG, "Send unicast data to enabled interface..");
317
318     CAResult_t res = CA_STATUS_FAILED;
319
320     if (endpoint == NULL)
321     {
322         OIC_LOG(DEBUG, TAG, "Invalid endpoint");
323         return CA_STATUS_INVALID_PARAM;
324     }
325
326     CATransportAdapter_t type = endpoint->adapter;
327
328     int index = CAGetAdapterIndex(type);
329
330     if (index == -1)
331     {
332         OIC_LOG(ERROR, TAG, "unknown transport type!");
333         return CA_STATUS_INVALID_PARAM;
334     }
335
336     uint32_t sentDataLen = 0;
337
338     if (g_adapterHandler[index].sendData != NULL)
339     {
340         sentDataLen = g_adapterHandler[index].sendData(endpoint, data, length);
341     }
342
343     if (sentDataLen != -1)
344     {
345         res = CA_STATUS_OK;
346     }
347     return res;
348 }
349
350 CAResult_t CASendMulticastData(const CAEndpoint_t *endpoint, const void *data, uint32_t length)
351 {
352     OIC_LOG(DEBUG, TAG, "Send multicast data to enabled interface..");
353
354     CAResult_t res = CA_SEND_FAILED;
355     u_arraylist_t *list = CAGetSelectedNetworkList();
356
357     if (!list)
358     {
359         OIC_LOG(DEBUG, TAG, "No selected network");
360         return CA_SEND_FAILED;
361     }
362
363     int i = 0;
364     for (i = 0; i < u_arraylist_length(list); i++)
365     {
366         void* ptrType = u_arraylist_get(list, i);
367
368         if(ptrType == NULL)
369         {
370             continue;
371         }
372
373         CATransportAdapter_t connType = *(CATransportAdapter_t *)ptrType;
374
375         int index = CAGetAdapterIndex(connType);
376
377         if (index == -1)
378         {
379             OIC_LOG(DEBUG, TAG, "unknown connectivity type!");
380             continue;
381         }
382
383         uint32_t sentDataLen = 0;
384
385         if (g_adapterHandler[index].sendDataToAll != NULL)
386         {
387             void *payload = (void *) OICMalloc(length);
388             if (!payload)
389             {
390                 OIC_LOG(ERROR, TAG, "Out of memory!");
391                 return CA_MEMORY_ALLOC_FAILED;
392             }
393             memcpy(payload, data, length);
394             sentDataLen = g_adapterHandler[index].sendDataToAll(endpoint, payload, length);
395             OICFree(payload);
396         }
397
398         if (sentDataLen == length)
399         {
400            res = CA_STATUS_OK;
401         }
402         else
403         {
404             OIC_LOG(ERROR, TAG, "sendDataToAll failed!");
405         }
406     }
407
408     return res;
409 }
410
411 CAResult_t CAStartListeningServerAdapters()
412 {
413     OIC_LOG(DEBUG, TAG, "Start listening server from adapters..");
414
415     u_arraylist_t *list = CAGetSelectedNetworkList();
416     if (!list)
417     {
418         OIC_LOG(ERROR, TAG, "No selected network");
419         return CA_STATUS_FAILED;
420     }
421
422     int i = 0;
423     for (i = 0; i < u_arraylist_length(list); i++)
424     {
425         void* ptrType = u_arraylist_get(list, i);
426
427         if(ptrType == NULL)
428         {
429             continue;
430         }
431
432         CATransportAdapter_t connType = *(CATransportAdapter_t *)ptrType;
433
434         int index = CAGetAdapterIndex(connType);
435         if (index == -1)
436         {
437             OIC_LOG(ERROR, TAG, "unknown connectivity type!");
438             continue;
439         }
440
441         if (g_adapterHandler[index].startListenServer != NULL)
442         {
443             g_adapterHandler[index].startListenServer();
444         }
445     }
446
447     return CA_STATUS_OK;
448 }
449
450 CAResult_t CAStartDiscoveryServerAdapters()
451 {
452     OIC_LOG(DEBUG, TAG, "Start discovery server from adapters..");
453
454     u_arraylist_t *list = CAGetSelectedNetworkList();
455
456     if (!list)
457     {
458         OIC_LOG(ERROR, TAG, "No selected network");
459         return CA_STATUS_FAILED;
460     }
461
462     int i = 0;
463     for (i = 0; i < u_arraylist_length(list); i++)
464     {
465         void* ptrType = u_arraylist_get(list, i);
466
467         if(ptrType == NULL)
468         {
469             continue;
470         }
471
472         CATransportAdapter_t connType = *(CATransportAdapter_t *)ptrType;
473
474         int index = CAGetAdapterIndex(connType);
475
476         if (index == -1)
477         {
478             OIC_LOG(DEBUG, TAG, "unknown connectivity type!");
479             continue;
480         }
481
482         if (g_adapterHandler[index].startDiscoveryServer != NULL)
483         {
484             g_adapterHandler[index].startDiscoveryServer();
485         }
486     }
487
488     return CA_STATUS_OK;
489 }
490
491 void CATerminateAdapters()
492 {
493     OIC_LOG(DEBUG, TAG, "terminate all adapters..");
494
495     uint32_t index;
496     for (index = 0; index < CA_TRANSPORT_TYPE_NUM; index++)
497     {
498         if (g_adapterHandler[index].terminate != NULL)
499         {
500             g_adapterHandler[index].terminate();
501         }
502     }
503 }