2 * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 #include <bluetooth.h>
26 #define LOG_TAG "BT_CHAT_CLIENT"
31 static GMainLoop* g_mainloop = NULL;
32 static bt_adapter_state_e bt_state = BT_ADAPTER_DISABLED;
33 static int socket_fd = -1;
34 static char* bt_address = NULL;
35 static char* server_name = "chat_server";
36 static char quit_command[5] = "Quit";
37 static int bonding_state = BT_ERROR_OPERATION_FAILED;
43 gboolean timeout_func(gpointer data)
45 LOGE("[%s] Callback: Timeout.", __FUNCTION__);
46 g_main_loop_quit((GMainLoop*)data);
50 void bt_state_changed_impl(int result, bt_adapter_state_e adapter_state, void* user_data)
52 if(adapter_state == BT_ADAPTER_ENABLED)
54 if(result == BT_ERROR_NONE)
56 LOGI("[%s] Callback: BT was enabled successfully.", __FUNCTION__);
57 bt_state = BT_ADAPTER_ENABLED;
61 LOGE("[%s] Callback: Failed to enable BT.", __FUNCTION__);
67 g_main_loop_quit(g_mainloop);
71 void bt_socket_connection_state_changed_impl(int result, bt_socket_connection_state_e connection_state,
72 bt_socket_connection_s *connection, void *user_data)
74 if(result == BT_ERROR_NONE)
76 LOGI("[%s] Callback: Result is BT_ERROR_NONE.", __FUNCTION__);
80 LOGI("[%s] Callback: Result is not BT_ERROR_NONE.", __FUNCTION__);
83 if(connection_state == BT_SOCKET_CONNECTED)
85 LOGI("[%s] Callback: Connected.", __FUNCTION__);
86 if(result == BT_ERROR_NONE && connection != NULL)
88 socket_fd = connection->socket_fd;
89 LOGI("[%s] Callback: Socket of connection - %d.", __FUNCTION__, socket_fd);
90 LOGI("[%s] Callback: Role of connection - %d.", __FUNCTION__, connection->local_role);
91 LOGI("[%s] Callback: Address of connection - %s.", __FUNCTION__, connection->remote_address);
93 if(bt_socket_send_data(socket_fd, quit_command, strlen(quit_command)) == BT_ERROR_NONE)
95 LOGI("[%s] Callback: Send quit command.", __FUNCTION__);
99 LOGE("[%s] Callback: bt_socket_send_data() failed.", __FUNCTION__);
102 g_main_loop_quit(g_mainloop);
108 LOGI("[%s] Callback: Failed to connect", __FUNCTION__);
111 g_main_loop_quit(g_mainloop);
117 LOGI("[%s] Callback: Disconnected.", __FUNCTION__);
121 void bt_socket_data_received_impl(bt_socket_received_data_s *data, void *user_data)
123 if(socket_fd == data->socket_fd)
125 if(data->data_size > 0)
127 if(!strncmp(data->data, quit_command, data->data_size))
129 LOGI("[%s] Callback: Quit command.", __FUNCTION__);
132 g_main_loop_quit(g_mainloop);
138 LOGE("[%s] Callback: No data.", __FUNCTION__);
143 LOGI("[%s] Callback: Another socket - %d.", __FUNCTION__, data->socket_fd);
147 bool bt_adapter_bonded_device_impl(bt_device_info_s *device_info, void *user_data)
150 if(device_info != NULL)
152 if(device_info->remote_name != NULL && !strcmp(device_info->remote_name, (char*)user_data))
154 LOGI("[%s] Callback: chat_server is found in bonded list.", __FUNCTION__);
155 if( device_info->remote_address != NULL )
157 LOGI("[%s] Callback: Address of chat_server - %s.", __FUNCTION__, device_info->remote_address);
158 bt_address = strdup(device_info->remote_address);
159 LOGI("[%s] Callback: The number of service_count - %d.", __FUNCTION__, device_info->service_count);
160 if(device_info->service_count <= 0)
162 bonding_state = BT_ERROR_SERVICE_SEARCH_FAILED;
166 bonding_state = BT_ERROR_NONE;
167 for(i=0; i<device_info->service_count; i++)
169 LOGI("[%s] Callback: service[%d] - %s", __FUNCTION__, i+1, device_info->service_uuid[i]);
171 LOGI("[%s] Callback: is_bonded - %d.", __FUNCTION__, device_info->is_bonded);
172 LOGI("[%s] Callback: is_connected - %d.", __FUNCTION__, device_info->is_connected);
173 LOGI("[%s] Callback: is_authorized - %d.", __FUNCTION__, device_info->is_authorized);
178 LOGE("[%s] Callback: Address of chat_server is NULL.", __FUNCTION__);
188 void bt_adapter_device_discovery_state_changed_impl(int result, bt_adapter_device_discovery_state_e discovery_state,
189 bt_adapter_device_discovery_info_s *discovery_info, void *user_data)
191 if(discovery_state == BT_ADAPTER_DEVICE_DISCOVERY_FOUND)
193 if(discovery_info->remote_address != NULL && !strcmp(discovery_info->remote_name, server_name))
195 LOGI("[%s] Callback: chat_server is found.", __FUNCTION__);
196 LOGI("[%s] Callback: Address of chat_server - %s.", __FUNCTION__, discovery_info->remote_address);
197 LOGI("[%s] Callback: Device major class - %d.", __FUNCTION__, discovery_info->bt_class.major_device_class);
198 LOGI("[%s] Callback: Device minor class - %d.", __FUNCTION__, discovery_info->bt_class.minor_device_class);
199 LOGI("[%s] Callback: Service major class - %d.", __FUNCTION__, discovery_info->bt_class.major_service_class_mask);
200 bt_address = strdup(discovery_info->remote_address);
201 LOGI("[%s] Callback: is_bonded - %d.", __FUNCTION__, discovery_info->is_bonded);
202 bt_adapter_stop_device_discovery();
206 LOGE("[%s] Callback: Another device is found.", __FUNCTION__);
209 else if(discovery_state == BT_ADAPTER_DEVICE_DISCOVERY_FINISHED)
211 LOGI("[%s] Callback: device discovery finished.", __FUNCTION__);
214 g_main_loop_quit(g_mainloop);
219 void bt_device_bond_created_impl(int result, bt_device_info_s *device_info, void *user_data)
221 if(device_info != NULL && !strcmp(device_info->remote_address, bt_address))
223 bonding_state = result;
224 if(result == BT_ERROR_NONE)
226 LOGI("[%s] Callback: A bond with chat_server is created.", __FUNCTION__);
227 LOGI("[%s] Callback: The number of service - %d.", __FUNCTION__, device_info->service_count);
230 for(i=0; i<device_info->service_count; i++)
232 LOGI("[%s] Callback: service[%d] - %s", __FUNCTION__, i+1, device_info->service_uuid[i]);
234 LOGI("[%s] Callback: is_bonded - %d.", __FUNCTION__, device_info->is_bonded);
235 LOGI("[%s] Callback: is_connected - %d.", __FUNCTION__, device_info->is_connected);
239 LOGE("[%s] Callback: Creating a bond is failed.", __FUNCTION__);
244 LOGE("[%s] Callback: A bond with another device is created.", __FUNCTION__);
249 g_main_loop_quit(g_mainloop);
253 void bt_device_service_searched_impl(int result, bt_device_sdp_info_s* sdp_info, void* user_data)
255 if(sdp_info != NULL && !strcmp(sdp_info->remote_address, bt_address))
257 bonding_state = result;
258 if(result == BT_ERROR_NONE)
260 LOGI("[%s] Callback: Services of chat_service are found.", __FUNCTION__);
261 LOGI("[%s] Callback: The number of service - %d.", __FUNCTION__, sdp_info->service_count);
264 for(i = 0; i < sdp_info->service_count; i++)
266 LOGI("[%s] Callback: service[%d] - %s", __FUNCTION__, i+1, sdp_info->service_uuid[i]);
272 LOGE("[%s] Callback: Services of another device are found.", __FUNCTION__);
277 g_main_loop_quit(g_mainloop);
286 g_mainloop = g_main_loop_new(NULL, FALSE);
287 const char* my_uuid="11011101-0000-1000-8000-00805F9B34FB";
290 LOGI("[%s] Client starts.", __FUNCTION__);
292 if(bt_initialize() != BT_ERROR_NONE)
294 LOGE("[%s] bt_initialize() failed.", __FUNCTION__);
298 if(bt_adapter_get_state(&bt_state) != BT_ERROR_NONE)
300 LOGE("[%s] bt_adapter_get_state() failed.", __FUNCTION__);
305 if(bt_state == BT_ADAPTER_DISABLED)
307 if(bt_adapter_set_state_changed_cb(bt_state_changed_impl, NULL) != BT_ERROR_NONE)
309 LOGE("[%s] bt_adapter_set_state_changed_cb() failed.", __FUNCTION__);
313 if(bt_adapter_enable() == BT_ERROR_NONE)
315 LOGI("[%s] bt_adapter_state_changed_cb will be called.", __FUNCTION__);
316 timeout_id = g_timeout_add (60000, timeout_func, g_mainloop);
317 g_main_loop_run(g_mainloop);
318 g_source_remove(timeout_id);
322 LOGE("[%s] bt_adapter_enable() failed.", __FUNCTION__);
328 LOGI("[%s] BT was already enabled.", __FUNCTION__);
332 if(bt_state == BT_ADAPTER_ENABLED)
334 if(bt_adapter_foreach_bonded_device(bt_adapter_bonded_device_impl, server_name) != BT_ERROR_NONE)
336 LOGE("[%s] bt_adapter_foreach_bonded_device() failed.", __FUNCTION__);
340 if(bt_address == NULL)
342 if(bt_adapter_set_device_discovery_state_changed_cb(bt_adapter_device_discovery_state_changed_impl, NULL)
345 LOGE("[%s] bt_adapter_set_device_discovery_state_changed_cb() failed.", __FUNCTION__);
349 if(bt_adapter_start_device_discovery() == BT_ERROR_NONE)
351 LOGI("[%s] bt_adapter_device_discovery_state_changed_cb will be called.", __FUNCTION__);
352 g_main_loop_run(g_mainloop);
356 LOGE("[%s] bt_adapter_start_device_discovery() failed.", __FUNCTION__);
362 LOGI("[%s] chat_server is found in bonded device list.", __FUNCTION__);
367 LOGE("[%s] BT is not enabled.", __FUNCTION__);
371 // Create bond with a server
372 if(bonding_state == BT_ERROR_SERVICE_SEARCH_FAILED)
374 if(bt_device_set_service_searched_cb(bt_device_service_searched_impl, NULL) != BT_ERROR_NONE)
376 LOGE("[%s] bt_device_set_service_searched_cb() failed.", __FUNCTION__);
380 if(bt_device_start_service_search(bt_address) == BT_ERROR_NONE)
382 LOGI("[%s] bt_device_service_searched_cb will be called.", __FUNCTION__);
383 g_main_loop_run(g_mainloop);
387 LOGE("[%s] bt_device_start_service_search() failed.", __FUNCTION__);
391 else if(bonding_state != BT_ERROR_NONE)
393 if(bt_device_set_bond_created_cb(bt_device_bond_created_impl, NULL) != BT_ERROR_NONE)
395 LOGE("[%s] bt_device_set_bond_created_cb() failed.", __FUNCTION__);
399 if(bt_device_create_bond(bt_address) == BT_ERROR_NONE)
401 LOGI("[%s] bt_device_bond_created_cb will be called.", __FUNCTION__);
402 g_main_loop_run(g_mainloop);
406 LOGE("[%s] bt_device_create_bond() failed.", __FUNCTION__);
411 // Connecting socket as a client
412 if( bonding_state == BT_ERROR_NONE )
414 if( bt_socket_set_connection_state_changed_cb(bt_socket_connection_state_changed_impl, NULL) != BT_ERROR_NONE )
416 LOGE("[%s] bt_socket_set_connection_state_changed_cb() failed.", __FUNCTION__);
420 if( bt_socket_set_data_received_cb(bt_socket_data_received_impl, NULL) != BT_ERROR_NONE )
422 LOGE("[%s] bt_socket_set_data_received_cb() failed.", __FUNCTION__);
426 if( bt_socket_connect_rfcomm(bt_address, my_uuid) == BT_ERROR_NONE )
428 LOGI("[%s] bt_socket_connection_state_changed_cb will be called.", __FUNCTION__);
429 g_main_loop_run(g_mainloop);
433 LOGE("[%s] bt_socket_connect_rfcomm() failed.", __FUNCTION__);
437 if( bt_socket_disconnect_rfcomm(socket_fd) != BT_ERROR_NONE )
439 LOGE("[%s] bt_socket_disconnect_rfcomm() failed.", __FUNCTION__);
445 LOGE("[%s] Bond is not created.", __FUNCTION__);
451 LOGI("[%s] Client ends.", __FUNCTION__);