Imported Upstream version 0.9.1
[platform/upstream/iotivity.git] / service / soft-sensor-manager / SoftSensorPlugin / IndoorTrajectorySensor / src / tizen_ble_bgthread.cpp
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 <iostream>
23 #include "tizen_log.h"
24 #include <pthread.h>
25 #include <unistd.h>
26
27 #include "tizen_public_ble.h"
28 #include "tizen_ble_bgthread.h"
29 #include "tizen_CbleDevice.h"
30
31 CbleBGthread *CbleBGthread::singleton = NULL;
32 CbleBGthread::workfunc CbleBGthread::workProcess = NULL;
33 bool CbleBGthread::ble_adapter_flag = false;
34 int CbleBGthread::ble_discover_flag = PROCESS_FREE;
35 int CbleBGthread::ble_bond_flag = PROCESS_FREE;
36 bool CbleBGthread::isThreadRun = false;
37 int CbleBGthread::reg_bond_cnt = 0;
38 pthread_t CbleBGthread::Thandle = 0;
39
40 // tizen ble init function.
41 void ble_init( CbleBGthread::workfunc func )
42 {
43     DBG("Enter.");
44
45     CbleBGthread *ble = CbleBGthread::GetInstance( func );
46     if ( ble == NULL )
47     {
48         DBG("Error : function is failed.");
49         return ;
50     }
51
52     BT_ERROR_CHECK( bt_initialize() );
53
54     BT_ERROR_CHECK( bt_adapter_set_state_changed_cb(CbleBGthread::CB_adapter_state_change, NULL) );
55     sleep(1);
56
57     bt_error_e returnValue;
58     returnValue = (bt_error_e)bt_adapter_enable();
59     if (returnValue != BT_ERROR_NONE )
60     {
61         what_return_value( returnValue );
62         if ( returnValue != BT_ERROR_ALREADY_DONE)
63             return ;
64         else
65         {
66 #if __INTERNAL_DEBUG_
67             DBG("return == BT_ERROR_ALREADY_DONE");
68 #endif
69             CbleBGthread::set_adapter_state_flag();
70         }
71     }
72
73 #if __INTERNAL_DEBUG_
74     DBG("Register discovery callback func.");
75 #endif
76     static CbleDevice device;
77     BT_ERROR_CHECK( bt_adapter_set_device_discovery_state_changed_cb(
78                         CbleBGthread::CB_discover_state_change, &device) );
79 //  sleep(1);
80
81 //  DBG("Register bond create callback func.");
82 //  BT_ERROR_CHECK( bt_device_set_bond_created_cb( CbleBGthread::CB_bond_create , &device) );
83 //  sleep(1);
84
85     ble->isThreadRun = true;
86     pthread_create(&ble->Thandle, NULL, CbleBGthread::ble_thread, &device);
87
88     DBG("Exit.");
89     return ;
90
91 BT_ERROR:
92     DBG("Error Exception. Exit.");
93
94 }
95
96 //void workProcess( void )
97 //{
98 //  DBG("WorkProcess run.");
99 //}
100
101 /*********************************
102  * CbleBGthread class definition.
103  */
104 CbleBGthread::CbleBGthread(workfunc func)
105 {
106     workProcess = func;
107     ble_adapter_flag = false;
108     ble_discover_flag = PROCESS_FREE;
109     ble_bond_flag = PROCESS_FREE;
110     isThreadRun = false;
111     reg_bond_cnt = 0;
112     Thandle = 0;
113 }
114
115 CbleBGthread::~CbleBGthread()
116 {
117     if ( singleton )
118     {
119         singleton = NULL;
120     }
121 }
122
123 CbleBGthread *CbleBGthread::GetInstance( workfunc func )
124 {
125     if ( func == NULL )
126         return NULL;
127
128     if (singleton == NULL)
129         singleton = new CbleBGthread(func);
130
131     return singleton;
132 }
133
134 /*****************************
135  * BLE processing thread.
136  */
137 void *CbleBGthread::ble_thread(void *param)
138 {
139     DBG("Enter.");
140     CbleDevice *pdevice = (CbleDevice *)param;
141
142     while (isThreadRun )
143     {
144         sleep(1);
145         pdevice->time_count++;
146
147         if ( ble_adapter_flag )
148         {
149             // discovery
150             if ( ble_discover_flag == PROCESS_FREE)
151             {
152                 if ( ble_discovery() == false)
153                     goto BT_ERROR;
154
155                 ble_discover_flag = PROCESS_TRYING;
156             }
157
158             // bond create
159 //          if( ble_discover_flag == PROCESS_COMPLETE && ble_bond_flag == PROCESS_FREE )
160 //          {
161 //              if( pdevice )
162 //              {
163 //                  DBG( "Try bond referenceThing List. size=%d, cnt=%d", pdevice->size(), reg_bond_cnt );
164 //                  if( reg_bond_cnt < pdevice->size() )
165 //                  {
166 //                      BT_ERROR_CHECK(bt_device_create_bond( (pdevice->getNext(reg_bond_cnt))->remote_address ));
167 //                      ble_bond_flag = PROCESS_TRYING;
168 //                  }
169 ////                    for( int i = 0; i < pdevice->size(); i++ )
170 ////                        BT_ERROR_CHECK(bt_device_create_bond( (pdevice->getNext(i))->remote_address ));
171 //              }
172 //          }
173
174 //          if( ble_bond_flag == PROCESS_COMPLETE )
175             if ( ble_discover_flag == PROCESS_COMPLETE )
176                 break;
177
178             continue ;
179
180 BT_ERROR:
181             continue ;
182         }   // if ( ble_adapter_flag )
183     }// while(isThreadRun )
184
185
186     while (isThreadRun)
187     {
188         // working process
189         workProcess( (void *)pdevice );
190     }
191
192     DBG("Exit.");
193     return 0;
194 }
195
196
197 /******************************
198  * Callback Function definition.
199  */
200
201 // Called by adapter_enable / adapter_disable function.
202 void CbleBGthread::CB_adapter_state_change(int result, bt_adapter_state_e adapter_state,
203         void *user_data)
204 {
205     DBG("callback called.");
206
207     set_adapter_state_flag();
208 }
209
210 // Called by bt_adapter_start_device_discovery / bt_adapter_stop_device_discovery function.
211 void CbleBGthread::CB_discover_state_change(int result,
212         bt_adapter_device_discovery_state_e discovery_state, \
213         bt_adapter_device_discovery_info_s *discovery_info, void *user_data)
214 {
215     DBG("callback called.");
216 #if __INTERNAL_DEBUG_
217     DBG("result = %d", result);
218 #endif
219
220     if ( discovery_state == BT_ADAPTER_DEVICE_DISCOVERY_FOUND )
221     {
222         CbleDevice *pdevice = (CbleDevice *)user_data;
223
224         if ( discovery_info == NULL)
225             goto BT_ERROR;
226
227 #if __INTERNAL_DEBUG_
228         printf("=========== discovered device =============\n");
229         printf("= address  \t : %s \n", discovery_info->remote_address);
230         printf("= name     \t : %s \n", discovery_info->remote_name);
231         printf("= rssi     \t : %d \n", (discovery_info->rssi - 65535) );
232         printf("= is_bonded\t : %d \n", discovery_info->is_bonded);
233         printf("= svc_count\t : %d \n", discovery_info->service_count);
234         printf("= dev_type \t : %d \n", discovery_info->device_type);
235         printf("===========================================\n");
236 #endif
237
238         find_referenceThing( discovery_info , pdevice );
239
240         if ( pdevice->isTimeOut() == true )
241         {
242 #if __INTERNAL_DEBUG_
243             DBG("Stop searching device.");
244 #endif
245             BT_ERROR_CHECK( bt_adapter_stop_device_discovery() );
246         }
247     }
248     else if ( discovery_state == BT_ADAPTER_DEVICE_DISCOVERY_FINISHED )
249     {
250 #if __INTERNAL_DEBUG_
251         DBG("state == BT_ADAPTER_DEVICE_DISCOVERY_FINISHED");
252 #endif
253         reg_bond_cnt = 0;
254         ble_discover_flag = PROCESS_COMPLETE;
255     }
256
257     return ;
258
259 BT_ERROR:
260     return ;
261 }
262
263 // (*bt_device_bond_created_cb)
264 void CbleBGthread::CB_bond_create(int result, bt_device_info_s *device_info, void *user_data)
265 {
266     DBG("callback called.");
267     if ( (bt_error_e)result != BT_ERROR_NONE )
268     {
269         what_return_value( (bt_error_e)result );
270         if ( (bt_error_e)result == BT_ERROR_REMOTE_DEVICE_NOT_FOUND )
271             ble_bond_flag = PROCESS_FREE;
272
273         return ;
274     }
275
276     CbleDevice *pdevice = (CbleDevice *)user_data;
277
278     if ( pdevice )
279     {
280 #if __INTERNAL_DEBUG_
281         printf("=========== bonded device =============\n");
282         printf("= address  \t : %s \n", device_info->remote_address);
283         printf("= name     \t : %s \n", device_info->remote_name);
284         printf("= is_bonded\t : %d \n", device_info->is_bonded);
285         printf("= is_connec\t : %d \n", device_info->is_connected);
286         printf("= is_autho \t : %d \n", device_info->is_authorized);
287         printf("= svc_count\t : %d \n", device_info->service_count);
288         printf("===========================================\n");
289 #endif
290
291         if ( pdevice->find( std::string(device_info->remote_address) ) )
292         {
293             reg_bond_cnt++;
294             ble_bond_flag = PROCESS_FREE;
295 #if __INTERNAL_DEBUG_
296             DBG( "bonded_cnt = %d", reg_bond_cnt );
297 #endif
298         }
299
300         if ( reg_bond_cnt == pdevice->size() )
301         {
302 #if __INTERNAL_DEBUG_
303             DBG("bond_flag is PROCESS_COMPLETE");
304 #endif
305             reg_bond_cnt = 0;
306             ble_bond_flag = PROCESS_COMPLETE;
307         }
308     }
309
310     return ;
311 }
312
313
314
315 /********************************
316  * ETC. function definition.
317  */
318 void CbleBGthread::set_adapter_state_flag(void)
319 {
320     DBG("Enter.");
321
322     // Get adapter state.
323     bt_adapter_state_e state;
324     BT_ERROR_CHECK( bt_adapter_get_state(&state) );
325
326     if ( state == BT_ADAPTER_ENABLED)
327         ble_adapter_flag = true;
328     else
329         ble_adapter_flag = false;
330
331     return ;
332
333 BT_ERROR:
334     DBG("Error Exception. Exit.");
335 }
336
337 // return : true --> OK
338 //                  false --> ERROR
339 bool CbleBGthread::ble_discovery( void )
340 {
341     DBG("is Searching device.");
342     bool isDiscovery = false;
343     BT_ERROR_CHECK(bt_adapter_is_discovering(&isDiscovery));
344
345     if ( isDiscovery == false )
346     {
347 #if __INTERNAL_DEBUG_
348         DBG("Start searching device.");
349 #endif
350         BT_ERROR_CHECK( bt_adapter_start_device_discovery() );
351     }
352
353     return true;
354
355 BT_ERROR:
356     return false;
357 }
358
359 bool CbleBGthread::find_referenceThing( bt_adapter_device_discovery_info_s *discovery_info ,
360                                         CbleDevice *pdevice )
361 {
362     DBG("Enter.");
363
364     if ( strstr( discovery_info->remote_name, REF_NAME ) )
365     {
366 #if __INTERNAL_DEBUG_
367         DBG("Find %s device.", REF_NAME);
368         DBG("Register %s device to reference-Thing.", discovery_info->remote_name );
369 #endif
370         pdevice->insert( discovery_info );
371     }
372
373     return true;
374 }
375
376 void what_return_value( bt_error_e returnValue )
377 {
378     printf("\n");
379     DBG("returnValue=%d", returnValue);
380
381     switch (returnValue)
382     {
383         case BT_ERROR_NONE:
384             DBG("return value is BT_ERROR_NONE\n");
385             break;
386         case BT_ERROR_CANCELLED:
387             DBG("return value is BT_ERROR_CANCELLED\n");
388             break;
389         case BT_ERROR_INVALID_PARAMETER:
390             DBG("return value is BT_ERROR_INVALID_PARAMETER\n");
391             break;
392         case BT_ERROR_OUT_OF_MEMORY:
393             DBG("return value is BT_ERROR_OUT_OF_MEMORY\n");
394             break;
395         case BT_ERROR_RESOURCE_BUSY:
396             DBG("return value is BT_ERROR_RESOURCE_BUSY\n");
397             break;
398         case BT_ERROR_TIMED_OUT:
399             DBG("return value is BT_ERROR_TIMED_OUT\n");
400             break;
401         case BT_ERROR_NOW_IN_PROGRESS:
402             DBG("return value is BT_ERROR_NOW_IN_PROGRESS\n");
403             break;
404         case BT_ERROR_NOT_INITIALIZED:
405             DBG("return value is BT_ERROR_NOT_INITIALIZED\n");
406             break;
407         case BT_ERROR_NOT_ENABLED:
408             DBG("return value is BT_ERROR_NOT_ENABLED\n");
409             break;
410         case BT_ERROR_ALREADY_DONE:
411             DBG("return value is BT_ERROR_ALREADY_DONE\n");
412             break;
413         case BT_ERROR_OPERATION_FAILED:
414             DBG("return value is BT_ERROR_OPERATION_FAILED\n");
415             break;
416         case BT_ERROR_NOT_IN_PROGRESS:
417             DBG("return value is BT_ERROR_NOT_IN_PROGRESS\n");
418             break;
419         case BT_ERROR_REMOTE_DEVICE_NOT_BONDED:
420             DBG("return value is BT_ERROR_REMOTE_DEVICE_NOT_BONDED\n");
421             break;
422         case BT_ERROR_AUTH_REJECTED:
423             DBG("return value is BT_ERROR_AUTH_REJECTED\n");
424             break;
425         case BT_ERROR_AUTH_FAILED:
426             DBG("return value is BT_ERROR_AUTH_FAILED\n");
427             break;
428         case BT_ERROR_REMOTE_DEVICE_NOT_FOUND:
429             DBG("return value is BT_ERROR_REMOTE_DEVICE_NOT_FOUND\n");
430             break;
431         case BT_ERROR_SERVICE_SEARCH_FAILED:
432             DBG("return value is BT_ERROR_SERVICE_SEARCH_FAILED\n");
433             break;
434         case BT_ERROR_REMOTE_DEVICE_NOT_CONNECTED:
435             DBG("return value is BT_ERROR_REMOTE_DEVICE_NOT_CONNECTED\n");
436             break;
437         case BT_ERROR_PERMISSION_DENIED:
438             DBG("return value is BT_ERROR_PERMISSION_DENIED\n");
439             break;
440     }
441 }
442
443
444 //int bt_adapter_get_le_state  ( bt_adapter_le_state_e *  adapter_le_state )
445 //bt_adapter_le_enable()
446 // bt_adapter_get_state()
447
448 // bt_adapter_start_device_discovery().
449 //      bt_adapter_device_discovery_state_changed_cb().
450 // bt_device_connect_le().
451 //      bt_device_gatt_state_changed_cb().
452 // bt_device_read_rssi_value(const char *address);
453
454
455 //int bt_device_set_connection_state_changed_cb(bt_device_connection_state_changed_cb callback, void *user_data);
456 //typedef void (*bt_device_connection_state_changed_cb)(bool connected, const char *remote_address, void *user_data);
457
458
459 // bt_adapter_start_device_discovery().
460 //      bt_adapter_device_discovery_state_changed_cb().
461 // bt_device_create_bond()
462 //      bt_device_bond_created_cb().
463 // bt_device_set_alias(address,name)