Implementation of connectivity abstraction feature Release v0.3
[platform/upstream/iotivity.git] / resource / csdk / connectivity / src / bt_le_adapter / caleadapter.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 #include "caleadapter.h"
21
22 #ifdef __TIZEN__
23 #include <arpa/inet.h>
24 #include <sys/socket.h>
25 #include <netdb.h>
26 #include <ifaddrs.h>
27 #include <unistd.h>
28 #include <pthread.h>
29 #endif //#ifdef __TIZEN__
30 #include <stdio.h>
31 #include <stdlib.h>
32
33 #ifdef __TIZEN__
34 #include "cableserver.h"
35 #include "cableclient.h"
36 #include "cacommon.h"
37 #include "umutex.h"
38 #include "caadapterutils.h"
39 #else // __ARDUINO__
40 #include "BLEAdapterArduino.h"
41 #include "caadapterutils.h"
42 #endif //#ifdef __TIZEN__
43 #define CALEADAPTER_TAG "CA_BLE_ADAPTER"
44
45 static CANetworkChangeCallback gNetworkCallback = NULL;
46
47 static char gLocalBLEAddress[16] = { 0, };
48
49 static CABool_t gIsServer = CA_FALSE;
50
51 static u_mutex gBleIsServerMutex = NULL;
52
53 static u_mutex gBleNetworkCbMutex = NULL;
54
55 static u_mutex gBleLocalAddressMutex = NULL;
56
57 int32_t CALERegisterNetworkNotifications(CANetworkChangeCallback netCallback);
58
59 #ifdef __TIZEN__
60 void CALEDeviceStateChangedCb(int32_t result, bt_adapter_state_e adapter_state,
61                                  void *user_data);
62 CAResult_t CAInitBleAdapterMutex();
63 CAResult_t CATermiateBleAdapterMutex();
64
65 #endif //#ifdef __TIZEN__
66
67 CAResult_t CAInitializeLE(CARegisterConnectivityCallback registerCallback,
68                           CANetworkPacketReceivedCallback reqRespCallback,
69                           CANetworkChangeCallback netCallback,
70                           u_thread_pool_t handle)
71 {
72     OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
73
74     //Input validation
75     VERIFY_NON_NULL(registerCallback, NULL, "RegisterConnectivity callback is null");
76     VERIFY_NON_NULL(reqRespCallback, NULL, "PacketReceived Callback is null");
77     VERIFY_NON_NULL(netCallback, NULL, "NetworkChange Callback is null");
78
79     CAResult_t result = CAInitBleAdapterMutex();
80
81     if (CA_STATUS_OK != result)
82     {
83         OIC_LOG(ERROR, CALEADAPTER_TAG, "CAInitBleAdapterMutex failed!");
84         return CA_STATUS_FAILED;
85     }
86
87 #ifdef __TIZEN__
88
89     bt_initialize();
90
91 #endif //#ifdef __TIZEN__
92
93     CASetBleServerThreadPoolHandle(handle);
94     CASetBleClientThreadPoolHandle(handle);
95     CASetBLEReqRespServerCallback(reqRespCallback);
96     CASetBLEReqRespClientCallback(reqRespCallback);
97     CALERegisterNetworkNotifications(netCallback);
98
99     CAConnectivityHandler_t connHandler;
100     connHandler.startAdapter = NULL;
101     connHandler.stopAdapter = NULL;
102     connHandler.startListenServer = CAStartLEListeningServer;
103     connHandler.startDiscoverServer = CAStartLEDiscoveryServer;
104     connHandler.sendData = CASendLEUnicastData;
105     connHandler.sendDataToAll = CASendLEMulticastData;
106     connHandler.GetnetInfo = CAGetLEInterfaceInformation;
107     connHandler.readData = CAReadLEData;
108     connHandler.terminate = CATerminateLE;
109     registerCallback(connHandler, CA_LE);
110
111     OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
112
113     return CA_STATUS_OK;
114 }
115
116 void CATerminateLE()
117 {
118     OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
119
120     CASetBLEReqRespServerCallback(NULL);
121     CASetBLEReqRespClientCallback(NULL);
122     CALERegisterNetworkNotifications(NULL);
123
124     u_mutex_lock(gBleIsServerMutex);
125     if (CA_TRUE == gIsServer)
126     {
127         CAStopBleGattServer();
128     }
129     else
130     {
131         CAStopBLEGattClient();
132     }
133     u_mutex_unlock(gBleIsServerMutex);
134
135     OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
136     return;
137 }
138
139 CAResult_t CAStartLEListeningServer()
140 {
141     OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
142
143     CAStartBleGattServer();
144
145     OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
146     u_mutex_lock(gBleIsServerMutex);
147     gIsServer = CA_TRUE;
148     u_mutex_unlock(gBleIsServerMutex);
149     return CA_STATUS_OK;
150 }
151
152 CAResult_t CAStartLEDiscoveryServer()
153 {
154     OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
155
156     CAStartBLEGattClient();
157
158     OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
159     u_mutex_lock(gBleIsServerMutex);
160     gIsServer = CA_FALSE;
161     u_mutex_unlock(gBleIsServerMutex);
162     return CA_STATUS_OK;
163 }
164
165 CAResult_t CAStartLENotifyServer()
166 {
167     OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
168
169     OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
170
171     return CA_STATUS_OK;
172 }
173
174 uint32_t CASendLENotification(const CARemoteEndpoint_t *endpoint, void *data, uint32_t dataLen)
175 {
176     OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
177
178     OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
179
180     return CA_STATUS_OK;
181 }
182
183 CAResult_t CAReadLEData()
184 {
185     OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
186
187     OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
188
189     return CA_STATUS_OK;
190 }
191
192 uint32_t CASendLEUnicastData(const CARemoteEndpoint_t *endpoint, void *data, uint32_t dataLen)
193 {
194     OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
195
196     //Input validation
197     VERIFY_NON_NULL(endpoint, NULL, "Remote endpoint is null");
198     VERIFY_NON_NULL(data, NULL, "Data is null");
199
200     CAResult_t result = CA_STATUS_FAILED;
201
202 #ifdef __TIZEN__
203     u_mutex_lock(gBleIsServerMutex);
204     if (CA_TRUE  == gIsServer)
205     {
206         result = CABleServerSenderQueueEnqueueMessage(endpoint, data, dataLen);
207         if (CA_STATUS_OK != result)
208         {
209             OIC_LOG(ERROR, CALEADAPTER_TAG,
210                     "[SendLEUnicastData] CABleServerSenderQueueEnqueueMessage failed \n");
211             u_mutex_unlock(gBleIsServerMutex);
212             return 0;
213         }
214     }
215     else
216     {
217
218         result = CABleClientSenderQueueEnqueueMessage(endpoint, data, dataLen);
219         if (CA_STATUS_OK != result)
220         {
221             OIC_LOG(ERROR, CALEADAPTER_TAG,
222                     "[SendLEUnicastData] CABleClientSenderQueueEnqueueMessage failed \n");
223             u_mutex_unlock(gBleIsServerMutex);
224             return 0;
225         }
226     }
227     u_mutex_unlock(gBleIsServerMutex);
228 #else
229     char *tempPath = "temp_path";
230     updateCharacteristicsInGattServer(tempPath, (char *) data, dataLen);
231 #endif //#ifdef __TIZEN__
232     OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
233
234     return dataLen;
235 }
236
237 uint32_t CASendLEMulticastData(void *data, uint32_t dataLen)
238 {
239     OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
240
241     //Input validation
242     VERIFY_NON_NULL(data, NULL, "Data is null");
243
244     if (0 >= dataLen)
245     {
246         OIC_LOG(ERROR, CALEADAPTER_TAG, "Invalid Parameter");
247         return 0;
248     }
249
250     CAResult_t result = CA_STATUS_FAILED;
251 #ifdef __TIZEN__
252     u_mutex_lock(gBleIsServerMutex);
253     if (CA_TRUE  == gIsServer)
254     {
255         result = CABleServerSenderQueueEnqueueMessage(NULL, data, dataLen);
256         if (CA_STATUS_OK != result)
257         {
258             OIC_LOG(ERROR, CALEADAPTER_TAG,
259                     "[SendLEMulticastDataToAll] CABleServerSenderQueueEnqueueMessage failed" );
260             u_mutex_unlock(gBleIsServerMutex);
261             return 0;
262         }
263     }
264     else
265     {
266         result = CABleClientSenderQueueEnqueueMessage(NULL, data, dataLen);
267         if (CA_STATUS_OK != result)
268         {
269             OIC_LOG(ERROR, CALEADAPTER_TAG,
270                     "[SendLEMulticastDataToAll] CABleClientSenderQueueEnqueueMessage failed" );
271             u_mutex_unlock(gBleIsServerMutex);
272             return 0;
273         }
274     }
275     u_mutex_unlock(gBleIsServerMutex);
276 #else
277     char *tempPath = "temp_path";
278     updateCharacteristicsInGattServer(tempPath, (char *) data, dataLen);
279 #endif //#ifdef __TIZEN__
280     OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
281     return dataLen;
282 }
283
284 CAResult_t CAGetLEInterfaceInformation(CALocalConnectivity_t **info, uint32_t *size)
285 {
286     OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
287
288     VERIFY_NON_NULL(info, NULL, "CALocalConnectivity info is null");
289
290 #if __TIZEN__
291
292     char *local_address = NULL;
293
294     bt_adapter_get_address(&local_address);
295     if (NULL == local_address)
296     {
297         OIC_LOG(ERROR, CALEADAPTER_TAG, "Get local bt adapter address failed");
298         return CA_STATUS_FAILED;
299     }
300
301 #endif //#if ARDUINODUE
302     *size = 0;
303     (*info) = (CALocalConnectivity_t *) OICMalloc(sizeof(CALocalConnectivity_t));
304     if (NULL == (*info))
305     {
306         OIC_LOG(ERROR, CALEADAPTER_TAG, "Malloc failure!");
307         return CA_STATUS_FAILED;
308     }
309     memset((*info), 0x0, sizeof(CALocalConnectivity_t));
310
311     strncpy((*info)->addressInfo.BT.btMacAddress, local_address, strlen(local_address));
312     u_mutex_lock(gBleLocalAddressMutex);
313     strncpy(gLocalBLEAddress, local_address, sizeof(gLocalBLEAddress));
314     u_mutex_unlock(gBleLocalAddressMutex);
315
316     (*info)->type = CA_LE;
317     *size = 1;
318     OICFree(local_address);
319
320     OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
321     return CA_STATUS_OK;
322 }
323
324 int32_t CALERegisterNetworkNotifications(CANetworkChangeCallback netCallback)
325 {
326     OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
327
328     u_mutex_lock(gBleNetworkCbMutex);
329     gNetworkCallback = netCallback;
330     u_mutex_unlock(gBleNetworkCbMutex);
331     int32_t ret = 0;
332 #ifdef __TIZEN__
333     if (netCallback)
334     {
335         ret = bt_adapter_set_state_changed_cb(CALEDeviceStateChangedCb, NULL);
336         if (ret != 0)
337         {
338             OIC_LOG(ERROR, CALEADAPTER_TAG, "bt_adapter_set_state_changed_cb failed!");
339         }
340     }
341     else
342     {
343         ret = bt_adapter_unset_state_changed_cb();
344         if (ret != 0)
345         {
346             OIC_LOG(ERROR, CALEADAPTER_TAG, "bt_adapter_set_state_changed_cb failed!");
347         }
348     }
349 #endif //#ifdef __TIZEN__
350     OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
351     return CA_STATUS_OK;
352 }
353
354 #ifdef __TIZEN__
355
356 void CALEDeviceStateChangedCb(int32_t result, bt_adapter_state_e adapter_state, void *user_data)
357 {
358     OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
359
360     CALocalConnectivity_t localEndpoint;
361
362     u_mutex_lock(gBleLocalAddressMutex);
363     strncpy(localEndpoint.addressInfo.BT.btMacAddress, gLocalBLEAddress, strlen(gLocalBLEAddress));
364     u_mutex_unlock(gBleLocalAddressMutex);
365
366     u_mutex_lock(gBleNetworkCbMutex);
367     if (NULL != gNetworkCallback)
368     {
369         gNetworkCallback(&localEndpoint, adapter_state);
370     }
371     else
372     {
373         OIC_LOG(ERROR, CALEADAPTER_TAG, "gNetworkCallback is NULL");
374     }
375     u_mutex_unlock(gBleNetworkCbMutex);
376     OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
377 }
378
379 CAResult_t CAInitBleAdapterMutex()
380 {
381     OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
382
383     u_mutex_init();
384     if (NULL == gBleIsServerMutex)
385     {
386         gBleIsServerMutex = u_mutex_new();
387         if (NULL == gBleIsServerMutex)
388         {
389             OIC_LOG(ERROR, CALEADAPTER_TAG, "u_mutex_new failed");
390             return CA_STATUS_FAILED;
391         }
392     }
393
394     if (NULL == gBleNetworkCbMutex)
395     {
396         gBleNetworkCbMutex = u_mutex_new();
397         if (NULL == gBleNetworkCbMutex)
398         {
399             OIC_LOG(ERROR, CALEADAPTER_TAG, "u_mutex_new failed");
400             return CA_STATUS_FAILED;
401         }
402     }
403
404     if (NULL == gBleLocalAddressMutex)
405     {
406         gBleLocalAddressMutex = u_mutex_new();
407         if (NULL == gBleLocalAddressMutex)
408         {
409             OIC_LOG(ERROR, CALEADAPTER_TAG, "u_mutex_new failed");
410             return CA_STATUS_FAILED;
411         }
412     }
413     OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
414     return CA_STATUS_OK;
415 }
416 CAResult_t CATermiateBleAdapterMutex()
417 {
418     OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
419     u_mutex_free(gBleIsServerMutex);
420     gBleIsServerMutex = NULL;
421     u_mutex_free(gBleNetworkCbMutex);
422     gBleNetworkCbMutex = NULL;
423     u_mutex_free(gBleLocalAddressMutex);
424     gBleLocalAddressMutex = NULL;
425     OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
426     return CA_STATUS_OK;
427 }
428 #endif //#ifdef OIC_TIZEN