Implementation of connectivity abstraction feature release v0.2
[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 int32_t 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.startNotifyServer = CAStartLENotifyServer;
107     connHandler.sendNotification = CASendLENotification;
108     connHandler.GetnetInfo = CAGetLEInterfaceInformation;
109     connHandler.readData = CAReadLEData;
110     connHandler.terminate = CATerminateLE;
111     registerCallback(connHandler, CA_LE);
112
113     OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
114
115     return CA_STATUS_OK;
116 }
117
118 void CATerminateLE()
119 {
120     OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
121
122     CASetBLEReqRespServerCallback(NULL);
123     CASetBLEReqRespClientCallback(NULL);
124     CALERegisterNetworkNotifications(NULL);
125
126     u_mutex_lock(gBleIsServerMutex);
127     if (CA_TRUE == gIsServer)
128     {
129         CAStopBleGattServer();
130     }
131     else
132     {
133         CAStopBLEGattClient();
134     }
135     u_mutex_unlock(gBleIsServerMutex);
136
137     OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
138     return;
139 }
140
141 CAResult_t CAStartLEListeningServer()
142 {
143     OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
144
145     CAStartBleGattServer();
146
147     OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
148     u_mutex_lock(gBleIsServerMutex);
149     gIsServer = CA_TRUE;
150     u_mutex_unlock(gBleIsServerMutex);
151     return CA_STATUS_OK;
152 }
153
154 CAResult_t CAStartLEDiscoveryServer()
155 {
156     OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
157
158     CAStartBLEGattClient();
159
160     OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
161     u_mutex_lock(gBleIsServerMutex);
162     gIsServer = CA_FALSE;
163     u_mutex_unlock(gBleIsServerMutex);
164     return CA_STATUS_OK;
165 }
166
167 CAResult_t CAStartLENotifyServer()
168 {
169     OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
170
171     OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
172
173     return CA_STATUS_OK;
174 }
175
176 uint32_t CASendLENotification(const CARemoteEndpoint_t *endpoint, void *data, uint32_t dataLen)
177 {
178     OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
179
180     OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
181
182     return CA_STATUS_OK;
183 }
184
185 CAResult_t CAReadLEData()
186 {
187     OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
188
189     OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
190
191     return CA_STATUS_OK;
192 }
193
194 uint32_t CASendLEUnicastData(const CARemoteEndpoint_t *endpoint, void *data, uint32_t dataLen)
195 {
196     OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
197
198     //Input validation
199     VERIFY_NON_NULL(endpoint, NULL, "Remote endpoint is null");
200     VERIFY_NON_NULL(data, NULL, "Data is null");
201
202     CAResult_t result = CA_STATUS_FAILED;
203
204 #ifdef __TIZEN__
205     u_mutex_lock(gBleIsServerMutex);
206     if (CA_TRUE  == gIsServer)
207     {
208         result = CABleServerSenderQueueEnqueueMessage(endpoint, data, dataLen);
209         if (CA_STATUS_OK != result)
210         {
211             OIC_LOG(ERROR, CALEADAPTER_TAG,
212                     "[SendLEUnicastData] CABleServerSenderQueueEnqueueMessage failed \n");
213             u_mutex_unlock(gBleIsServerMutex);
214             return 0;
215         }
216     }
217     else
218     {
219
220         result = CABleClientSenderQueueEnqueueMessage(endpoint, data, dataLen);
221         if (CA_STATUS_OK != result)
222         {
223             OIC_LOG(ERROR, CALEADAPTER_TAG,
224                     "[SendLEUnicastData] CABleClientSenderQueueEnqueueMessage failed \n");
225             u_mutex_unlock(gBleIsServerMutex);
226             return 0;
227         }
228     }
229     u_mutex_unlock(gBleIsServerMutex);
230 #else
231     char *tempPath = "temp_path";
232     updateCharacteristicsInGattServer(tempPath, (char *) data, dataLen);
233 #endif //#ifdef __TIZEN__
234     OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
235
236     return dataLen;
237 }
238
239 uint32_t CASendLEMulticastData(void *data, uint32_t dataLen)
240 {
241     OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
242
243     //Input validation
244     VERIFY_NON_NULL(data, NULL, "Data is null");
245
246     if (0 >= dataLen)
247     {
248         OIC_LOG(ERROR, CALEADAPTER_TAG, "Invalid Parameter");
249         return 0;
250     }
251
252     CAResult_t result = CA_STATUS_FAILED;
253 #ifdef __TIZEN__
254     u_mutex_lock(gBleIsServerMutex);
255     if (CA_TRUE  == gIsServer)
256     {
257         result = CABleServerSenderQueueEnqueueMessage(NULL, data, dataLen);
258         if (CA_STATUS_OK != result)
259         {
260             OIC_LOG(ERROR, CALEADAPTER_TAG,
261                     "[SendLEMulticastDataToAll] CABleServerSenderQueueEnqueueMessage failed" );
262             u_mutex_unlock(gBleIsServerMutex);
263             return 0;
264         }
265     }
266     else
267     {
268         result = CABleClientSenderQueueEnqueueMessage(NULL, data, dataLen);
269         if (CA_STATUS_OK != result)
270         {
271             OIC_LOG(ERROR, CALEADAPTER_TAG,
272                     "[SendLEMulticastDataToAll] CABleClientSenderQueueEnqueueMessage failed" );
273             u_mutex_unlock(gBleIsServerMutex);
274             return 0;
275         }
276     }
277     u_mutex_unlock(gBleIsServerMutex);
278 #else
279     char *tempPath = "temp_path";
280     updateCharacteristicsInGattServer(tempPath, (char *) data, dataLen);
281 #endif //#ifdef __TIZEN__
282     OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
283     return dataLen;
284 }
285
286 CAResult_t CAGetLEInterfaceInformation(CALocalConnectivity_t **info, uint32_t *size)
287 {
288     OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
289
290     VERIFY_NON_NULL(info, NULL, "CALocalConnectivity info is null");
291
292 #if __TIZEN__
293
294     char *local_address = NULL;
295
296     bt_adapter_get_address(&local_address);
297     if (NULL == local_address)
298     {
299         OIC_LOG(ERROR, CALEADAPTER_TAG, "Get local bt adapter address failed");
300         return CA_STATUS_FAILED;
301     }
302
303 #endif //#if ARDUINODUE
304     *size = 0;
305     (*info) = (CALocalConnectivity_t *) OICMalloc(sizeof(CALocalConnectivity_t));
306     if (NULL == (*info))
307     {
308         OIC_LOG(ERROR, CALEADAPTER_TAG, "Malloc failure!");
309         return CA_STATUS_FAILED;
310     }
311     memset((*info), 0x0, sizeof(CALocalConnectivity_t));
312
313     strncpy((*info)->addressInfo.BT.btMacAddress, local_address, strlen(local_address));
314     u_mutex_lock(gBleLocalAddressMutex);
315     strncpy(gLocalBLEAddress, local_address, sizeof(gLocalBLEAddress));
316     u_mutex_unlock(gBleLocalAddressMutex);
317
318     (*info)->type = CA_LE;
319     *size = 1;
320     OICFree(local_address);
321
322     OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
323     return CA_STATUS_OK;
324 }
325
326 int32_t CALERegisterNetworkNotifications(CANetworkChangeCallback netCallback)
327 {
328     OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
329
330     u_mutex_lock(gBleNetworkCbMutex);
331     gNetworkCallback = netCallback;
332     u_mutex_unlock(gBleNetworkCbMutex);
333     int32_t ret = 0;
334 #ifdef __TIZEN__
335     if (netCallback)
336     {
337         ret = bt_adapter_set_state_changed_cb(CALEDeviceStateChangedCb, NULL);
338         if (ret != 0)
339         {
340             OIC_LOG(ERROR, CALEADAPTER_TAG, "bt_adapter_set_state_changed_cb failed!");
341         }
342     }
343     else
344     {
345         ret = bt_adapter_unset_state_changed_cb();
346         if (ret != 0)
347         {
348             OIC_LOG(ERROR, CALEADAPTER_TAG, "bt_adapter_set_state_changed_cb failed!");
349         }
350     }
351 #endif //#ifdef __TIZEN__
352     OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
353     return CA_STATUS_OK;
354 }
355
356 #ifdef __TIZEN__
357
358 int32_t CALEDeviceStateChangedCb(int32_t result, bt_adapter_state_e adapter_state, void *user_data)
359 {
360     OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
361
362     bt_adapter_state_e btAdaptorState = BT_ADAPTER_DISABLED;
363     if (BT_ADAPTER_ENABLED == adapter_state)
364     {
365         btAdaptorState = BT_ADAPTER_ENABLED;
366     }
367
368     CALocalConnectivity_t localEndpoint;
369
370     u_mutex_lock(gBleLocalAddressMutex);
371     strncpy(localEndpoint.addressInfo.BT.btMacAddress, gLocalBLEAddress, strlen(gLocalBLEAddress));
372     u_mutex_unlock(gBleLocalAddressMutex);
373
374     u_mutex_lock(gBleNetworkCbMutex);
375     if (NULL != gNetworkCallback)
376     {
377         gNetworkCallback(&localEndpoint, adapter_state);
378     }
379     else
380     {
381         OIC_LOG(ERROR, CALEADAPTER_TAG, "gNetworkCallback is NULL");
382     }
383     u_mutex_unlock(gBleNetworkCbMutex);
384     OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
385     return CA_STATUS_OK;
386 }
387
388 CAResult_t CAInitBleAdapterMutex()
389 {
390     OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
391
392     u_mutex_init();
393     if (NULL == gBleIsServerMutex)
394     {
395         gBleIsServerMutex = u_mutex_new();
396         if (NULL == gBleIsServerMutex)
397         {
398             OIC_LOG(ERROR, CALEADAPTER_TAG, "u_mutex_new failed");
399             return CA_STATUS_FAILED;
400         }
401     }
402
403     if (NULL == gBleNetworkCbMutex)
404     {
405         gBleNetworkCbMutex = u_mutex_new();
406         if (NULL == gBleNetworkCbMutex)
407         {
408             OIC_LOG(ERROR, CALEADAPTER_TAG, "u_mutex_new failed");
409             return CA_STATUS_FAILED;
410         }
411     }
412
413     if (NULL == gBleLocalAddressMutex)
414     {
415         gBleLocalAddressMutex = u_mutex_new();
416         if (NULL == gBleLocalAddressMutex)
417         {
418             OIC_LOG(ERROR, CALEADAPTER_TAG, "u_mutex_new failed");
419             return CA_STATUS_FAILED;
420         }
421     }
422     OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
423     return CA_STATUS_OK;
424 }
425 CAResult_t CATermiateBleAdapterMutex()
426 {
427     OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
428     u_mutex_free(gBleIsServerMutex);
429     gBleIsServerMutex = NULL;
430     u_mutex_free(gBleNetworkCbMutex);
431     gBleNetworkCbMutex = NULL;
432     u_mutex_free(gBleLocalAddressMutex);
433     gBleLocalAddressMutex = NULL;
434     OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
435     return CA_STATUS_OK;
436 }
437 #endif //#ifdef OIC_TIZEN