--- /dev/null
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include <bluetooth.h>
+#include <bluetooth_internal.h>
+#include <dlog.h>
+#include <glib.h>
+#include <stdio.h>
+#include <string.h>
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "BLE_MOUSE"
+
+/**
+ * Variables
+ **/
+static GMainLoop *g_mainloop = NULL;
+static bt_adapter_state_e bt_state = BT_ADAPTER_DISABLED;
+static bt_gatt_server_h server = NULL;
+static bt_advertiser_h advertiser = NULL;
+
+#define PRT(format, args...) printf("%s:%d() "format, __FUNCTION__, __LINE__, ##args)
+#define BLE_PRT(format, args...) PRT(format"\n", ##args)
+
+static const char *__bt_get_error_message(bt_error_e err)
+{
+ const char *err_str = NULL;
+
+ switch (err) {
+ case BT_ERROR_NONE:
+ err_str = "BT_ERROR_NONE";
+ break;
+ case BT_ERROR_CANCELLED:
+ err_str = "BT_ERROR_CANCELLED";
+ break;
+ case BT_ERROR_INVALID_PARAMETER:
+ err_str = "BT_ERROR_INVALID_PARAMETER";
+ break;
+ case BT_ERROR_OUT_OF_MEMORY:
+ err_str = "BT_ERROR_OUT_OF_MEMORY";
+ break;
+ case BT_ERROR_RESOURCE_BUSY:
+ err_str = "BT_ERROR_RESOURCE_BUSY";
+ break;
+ case BT_ERROR_TIMED_OUT:
+ err_str = "BT_ERROR_TIMED_OUT";
+ break;
+ case BT_ERROR_NOW_IN_PROGRESS:
+ err_str = "BT_ERROR_NOW_IN_PROGRESS";
+ break;
+ case BT_ERROR_NOT_INITIALIZED:
+ err_str = "BT_ERROR_NOT_INITIALIZED";
+ break;
+ case BT_ERROR_NOT_ENABLED:
+ err_str = "BT_ERROR_NOT_ENABLED";
+ break;
+ case BT_ERROR_ALREADY_DONE:
+ err_str = "BT_ERROR_ALREADY_DONE";
+ break;
+ case BT_ERROR_OPERATION_FAILED:
+ err_str = "BT_ERROR_OPERATION_FAILED";
+ break;
+ case BT_ERROR_NOT_IN_PROGRESS:
+ err_str = "BT_ERROR_NOT_IN_PROGRESS";
+ break;
+ case BT_ERROR_REMOTE_DEVICE_NOT_BONDED:
+ err_str = "BT_ERROR_REMOTE_DEVICE_NOT_BONDED";
+ break;
+ case BT_ERROR_AUTH_REJECTED:
+ err_str = "BT_ERROR_AUTH_REJECTED";
+ break;
+ case BT_ERROR_AUTH_FAILED:
+ err_str = "BT_ERROR_AUTH_FAILED";
+ break;
+ case BT_ERROR_REMOTE_DEVICE_NOT_FOUND:
+ err_str = "BT_ERROR_REMOTE_DEVICE_NOT_FOUND";
+ break;
+ case BT_ERROR_SERVICE_SEARCH_FAILED:
+ err_str = "BT_ERROR_SERVICE_SEARCH_FAILED";
+ break;
+ case BT_ERROR_REMOTE_DEVICE_NOT_CONNECTED:
+ err_str = "BT_ERROR_REMOTE_DEVICE_NOT_CONNECTED";
+ break;
+ case BT_ERROR_PERMISSION_DENIED:
+ err_str = "BT_ERROR_PERMISSION_DENIED";
+ break;
+ case BT_ERROR_SERVICE_NOT_FOUND:
+ err_str = "BT_ERROR_SERVICE_NOT_FOUND";
+ break;
+ case BT_ERROR_NO_DATA:
+ err_str = "BT_ERROR_NO_DATA";
+ break;
+ case BT_ERROR_NOT_SUPPORTED:
+ err_str = "BT_ERROR_NOT_SUPPORTED";
+ break;
+ case BT_ERROR_DEVICE_POLICY_RESTRICTION:
+ err_str = "DEVICE_POLICY_RESTRICTION";
+ break;
+ default:
+ err_str = "NOT Defined";
+ break;
+ }
+
+ return err_str;
+}
+
+/**
+ * Callback functions
+ **/
+static gboolean __timeout_func(gpointer data)
+{
+ BLE_PRT("Timeout.");
+ if (g_mainloop)
+ g_main_loop_quit((GMainLoop *)data);
+
+ return FALSE;
+}
+
+static void __bt_state_changed_impl(int result,
+ bt_adapter_state_e adapter_state,
+ void *user_data)
+{
+ if (adapter_state == BT_ADAPTER_ENABLED) {
+ if (result == BT_ERROR_NONE) {
+ BLE_PRT("Callback: BT was enabled successfully.");
+ bt_state = BT_ADAPTER_ENABLED;
+ } else {
+ BLE_PRT("Callback: Failed to enable BT.");
+ }
+ }
+
+ if (g_mainloop)
+ g_main_loop_quit(g_mainloop);
+}
+
+static void __bt_gatt_read_value1_req_cb(
+ const char *remote_address, int request_id,
+ bt_gatt_server_h server, bt_gatt_h gatt_handle,
+ int offset, void *user_data)
+{
+ char char_value[4] = {10, 20, 30, 40};
+
+ int resp_status = BT_ATT_ERROR_NONE;
+
+ BLE_PRT("[%s] req_id %d, offset %d", remote_address, request_id, offset);
+
+ /* Get the attribute new values here */
+ bt_gatt_server_send_response(request_id,
+ BT_GATT_REQUEST_TYPE_READ, offset,
+ resp_status, char_value, 1 - offset);
+}
+
+static void __bt_gatt_read_value_req_cb(
+ const char *remote_address, int request_id,
+ bt_gatt_server_h server, bt_gatt_h gatt_handle,
+ int offset, void *user_data)
+{
+ char char_value[1] = { 80 }; /* 80% */
+
+ int resp_status = BT_ATT_ERROR_NONE;
+
+ BLE_PRT("[%s] req_id %d, offset %d", remote_address, request_id, offset);
+
+ /* Get the attribute new values here */
+ bt_gatt_server_send_response(request_id,
+ BT_GATT_REQUEST_TYPE_READ, offset,
+ resp_status, char_value, 1 - offset);
+}
+
+static void __bt_gatt_write_value_req_cb(const char *remote_address,
+ int request_id, bt_gatt_server_h server,
+ bt_gatt_h gatt_handle, bool response_needed, int offset,
+ const char *value, int len, void *user_data)
+{
+ int i, resp_status = BT_ATT_ERROR_NONE;
+
+ BLE_PRT("[%s] req_id %d, response_needed %d, offset %d, len %d",
+ remote_address, request_id, response_needed, offset, len);
+
+ for (i = 0; i < len; i++)
+ BLE_PRT("%d ", value[i]);
+
+ if (len > 4) {
+ bt_gatt_server_send_response(request_id,
+ BT_GATT_REQUEST_TYPE_WRITE, offset,
+ BT_ATT_ERROR_OUT_OF_RANGE, NULL, 0);
+
+ BLE_PRT("Invalid Len");
+ return;
+ }
+
+ bt_gatt_server_send_response(request_id,
+ BT_GATT_REQUEST_TYPE_WRITE, offset,
+ resp_status, NULL, 0);
+}
+
+static void __bt_gatt_write_value_desc_req_cb(const char *remote_address,
+ int request_id, bt_gatt_server_h server,
+ bt_gatt_h gatt_handle, bool response_needed, int offset,
+ const char *value, int len, void *user_data)
+{
+ int i, resp_status = BT_ATT_ERROR_NONE;
+
+ BLE_PRT("[%s] req_id %d, response_needed %d, offset %d, len %d",
+ remote_address, request_id, response_needed, offset, len);
+
+ for (i = 0; i < len; i++)
+ BLE_PRT("%d ", value[i]);
+
+ if (len > 2) {
+ bt_gatt_server_send_response(request_id,
+ BT_GATT_REQUEST_TYPE_WRITE, offset,
+ BT_ATT_ERROR_OUT_OF_RANGE, NULL, 0);
+
+ BLE_PRT("Invalid Len");
+ return;
+ }
+
+ bt_gatt_server_send_response(request_id,
+ BT_GATT_REQUEST_TYPE_WRITE, offset,
+ resp_status, NULL, 0);
+}
+
+
+static void __bt_gatt_notification_state_change_cb(bool notify,
+ bt_gatt_server_h server, bt_gatt_h gatt_handle,
+ void *user_data)
+{
+ BLE_PRT("Notification %s [%d]", notify ? "enabled" : "disabled", notify);
+ BLE_PRT("server %s\n", (char *)server);
+}
+
+
+static int __bt_register_hogp_service(void)
+{
+ int ret = BT_ERROR_NONE;
+ bt_gatt_h service1 = NULL; /* Human Interface Device */
+ bt_gatt_h service2 = NULL; /* Battery Service */
+ bt_gatt_h characteristic1_1 = NULL; /* HID Information */
+ bt_gatt_h characteristic1_2 = NULL; /* Report Map */
+ bt_gatt_h characteristic1_3 = NULL; /* Boot Mouse input Report */
+ bt_gatt_h characteristic1_4 = NULL; /* Report */
+ bt_gatt_h characteristic1_5 = NULL; /* Report */
+ bt_gatt_h characteristic1_6 = NULL; /* HID Control Point */
+ bt_gatt_h characteristic1_7 = NULL; /* Protocal Mode */
+ bt_gatt_h characteristic2_1 = NULL; /* Battery Level */
+ bt_gatt_h characteristic2_2 = NULL; /* Custom read / write */
+ bt_gatt_h descriptor1_3 = NULL; /* CCCD */
+ bt_gatt_h descriptor1_4_1 = NULL; /* CCCD */
+ bt_gatt_h descriptor1_4_2 = NULL; /* Report Reference */
+ bt_gatt_h descriptor1_5_1 = NULL; /* Report Reference */
+ bt_gatt_h descriptor1_5_2 = NULL; /* CCCD */
+ bt_gatt_h descriptor2 = NULL; /* CCCD */
+ char *service_uuid1 = "1812"; /* HID Service */
+ char *service_uuid2 = "180f"; /* Battery Service */
+ char *char_uuid1_1 = "2a4a"; /* HID information */
+ char *char_uuid1_2 = "2a4b";
+ char *char_uuid1_3 = "2a33";
+ char *char_uuid1_4 = "2a4d";
+ char *char_uuid1_5 = "2a4d";
+ char *char_uuid1_6 = "2a4c";
+ char *char_uuid1_7 = "2a4e";
+ char *desc_uuid1_3 = "2902"; /* Client Characteristic Configuration */
+ char *desc_uuid1_4_1 = "2902"; /* Client Characteristic Configuration */
+ char *desc_uuid1_4_2 = "2908"; /* Report Reference */
+ char *desc_uuid1_5_1 = "2908"; /* Report Reference */
+ char *desc_uuid1_5_2 = "2901"; /* Characteristic User Description */
+ char *char_uuid2_1 = "2a19"; /* Battery Level */
+ char *char_uuid2_2 = "2af8"; /* Custom UUID */
+ char *desc_uuid2 = "2902"; /* Client Characteristic Configuration */
+ int permissions = BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE;
+ int properties_read = BT_GATT_PROPERTY_READ;
+ int properties_read_write = BT_GATT_PROPERTY_READ | BT_GATT_PROPERTY_WRITE;
+ int properties_notify_read = BT_GATT_PROPERTY_NOTIFY | BT_GATT_PROPERTY_READ;
+ int properties_write_no_response = BT_GATT_PROPERTY_WRITE_WITHOUT_RESPONSE;
+ int properties_read_write_no_response = BT_GATT_PROPERTY_READ | BT_GATT_PROPERTY_WRITE_WITHOUT_RESPONSE;
+
+ char char_value[1] = { 80 }; /* 80% */
+ char char_value_unknown[4] = {10, 20, 30, 40};
+ char desc_value_configration[2] = {0, 0}; /* Notification & Indication */
+
+ ret = bt_gatt_server_initialize();
+ BLE_PRT("bt_gatt_server_initialize : %s", __bt_get_error_message(ret));
+
+ ret = bt_gatt_server_create(&server);
+ BLE_PRT("bt_gatt_server_create : %s", __bt_get_error_message(ret));
+
+ /* HID Service */
+ ret = bt_gatt_service_create(service_uuid1, BT_GATT_SERVICE_TYPE_PRIMARY, &service1);
+ BLE_PRT("bt_gatt_service_create : %s", __bt_get_error_message(ret));
+
+ ret = bt_gatt_characteristic_create(char_uuid1_1, permissions,
+ properties_read, char_value_unknown,
+ 4, &characteristic1_1);
+ BLE_PRT("bt_gatt_characteristic_create : %s", __bt_get_error_message(ret));
+
+ ret = bt_gatt_server_set_read_value_requested_cb(characteristic1_1,
+ __bt_gatt_read_value1_req_cb, NULL);
+
+ ret = bt_gatt_service_add_characteristic(service1, characteristic1_1);
+ BLE_PRT("bt_gatt_service_add_characteristic : %s", __bt_get_error_message(ret));
+
+ ret = bt_gatt_characteristic_create(char_uuid1_2, permissions,
+ properties_read, char_value_unknown,
+ 4, &characteristic1_2);
+ BLE_PRT("bt_gatt_characteristic_create : %s", __bt_get_error_message(ret));
+
+ ret = bt_gatt_server_set_read_value_requested_cb(characteristic1_2,
+ __bt_gatt_read_value1_req_cb, NULL);
+
+ ret = bt_gatt_service_add_characteristic(service1, characteristic1_2);
+ BLE_PRT("bt_gatt_service_add_characteristic : %s", __bt_get_error_message(ret));
+
+ ret = bt_gatt_characteristic_create(char_uuid1_3, permissions,
+ properties_notify_read, char_value_unknown,
+ 4, &characteristic1_3);
+ BLE_PRT("bt_gatt_characteristic_create : %s", __bt_get_error_message(ret));
+
+ ret = bt_gatt_server_set_read_value_requested_cb(characteristic1_3,
+ __bt_gatt_read_value1_req_cb, NULL);
+
+ ret = bt_gatt_server_set_characteristic_notification_state_change_cb(characteristic1_3,
+ __bt_gatt_notification_state_change_cb, NULL);
+
+ ret = bt_gatt_service_add_characteristic(service1, characteristic1_3);
+ BLE_PRT("bt_gatt_service_add_characteristic : %s", __bt_get_error_message(ret));
+
+ ret = bt_gatt_descriptor_create(desc_uuid1_3, permissions,
+ desc_value_configration, 2, &descriptor1_3);
+ BLE_PRT("bt_gatt_descriptor_create : %s", __bt_get_error_message(ret));
+
+ ret = bt_gatt_server_set_write_value_requested_cb(descriptor1_3,
+ __bt_gatt_write_value_desc_req_cb, NULL);
+
+ ret = bt_gatt_characteristic_add_descriptor(characteristic1_3, descriptor1_3);
+ BLE_PRT("bt_gatt_characteristic_add_descriptor : %s", __bt_get_error_message(ret));
+
+ ret = bt_gatt_characteristic_create(char_uuid1_4, permissions,
+ properties_notify_read, char_value_unknown,
+ 4, &characteristic1_4);
+ BLE_PRT("bt_gatt_characteristic_create : %s", __bt_get_error_message(ret));
+
+ ret = bt_gatt_server_set_read_value_requested_cb(characteristic1_4,
+ __bt_gatt_read_value1_req_cb, NULL);
+
+ ret = bt_gatt_server_set_characteristic_notification_state_change_cb(characteristic1_4,
+ __bt_gatt_notification_state_change_cb, NULL);
+
+ ret = bt_gatt_service_add_characteristic(service1, characteristic1_4);
+ BLE_PRT("bt_gatt_service_add_characteristic : %s", __bt_get_error_message(ret));
+
+ ret = bt_gatt_descriptor_create(desc_uuid1_4_1, permissions,
+ desc_value_configration, 2, &descriptor1_4_1);
+ BLE_PRT("bt_gatt_descriptor_create : %s", __bt_get_error_message(ret));
+
+ ret = bt_gatt_server_set_write_value_requested_cb(descriptor1_4_1,
+ __bt_gatt_write_value_desc_req_cb, NULL);
+
+ ret = bt_gatt_characteristic_add_descriptor(characteristic1_4, descriptor1_4_1);
+ BLE_PRT("bt_gatt_characteristic_add_descriptor : %s", __bt_get_error_message(ret));
+
+ ret = bt_gatt_descriptor_create(desc_uuid1_4_2, permissions,
+ desc_value_configration, 2, &descriptor1_4_2);
+ BLE_PRT("bt_gatt_descriptor_create : %s", __bt_get_error_message(ret));
+
+ ret = bt_gatt_server_set_write_value_requested_cb(descriptor1_4_2,
+ __bt_gatt_write_value_desc_req_cb, NULL);
+
+ ret = bt_gatt_characteristic_add_descriptor(characteristic1_4, descriptor1_4_2);
+ BLE_PRT("bt_gatt_characteristic_add_descriptor : %s", __bt_get_error_message(ret));
+
+ ret = bt_gatt_characteristic_create(char_uuid1_5, permissions,
+ properties_read_write, char_value_unknown,
+ 4, &characteristic1_5);
+ BLE_PRT("bt_gatt_characteristic_create : %s", __bt_get_error_message(ret));
+
+ ret = bt_gatt_server_set_read_value_requested_cb(characteristic1_5,
+ __bt_gatt_read_value1_req_cb, NULL);
+
+ ret = bt_gatt_server_set_write_value_requested_cb(characteristic1_5,
+ __bt_gatt_write_value_req_cb, NULL);
+
+ ret = bt_gatt_service_add_characteristic(service1, characteristic1_5);
+ BLE_PRT("bt_gatt_service_add_characteristic : %s", __bt_get_error_message(ret));
+
+ ret = bt_gatt_descriptor_create(desc_uuid1_5_1, permissions,
+ desc_value_configration, 2, &descriptor1_5_1);
+ BLE_PRT("bt_gatt_descriptor_create : %s", __bt_get_error_message(ret));
+
+ ret = bt_gatt_server_set_write_value_requested_cb(descriptor1_5_1,
+ __bt_gatt_write_value_desc_req_cb, NULL);
+
+ ret = bt_gatt_characteristic_add_descriptor(characteristic1_5, descriptor1_5_1);
+ BLE_PRT("bt_gatt_characteristic_add_descriptor : %s", __bt_get_error_message(ret));
+
+ ret = bt_gatt_descriptor_create(desc_uuid1_5_2, permissions,
+ desc_value_configration, 2, &descriptor1_5_2);
+ BLE_PRT("bt_gatt_descriptor_create : %s", __bt_get_error_message(ret));
+
+ ret = bt_gatt_characteristic_add_descriptor(characteristic1_5, descriptor1_5_2);
+ BLE_PRT("bt_gatt_characteristic_add_descriptor : %s", __bt_get_error_message(ret));
+
+ ret = bt_gatt_characteristic_create(char_uuid1_6, permissions,
+ properties_write_no_response, char_value_unknown,
+ 4, &characteristic1_6);
+ BLE_PRT("bt_gatt_characteristic_create : %s", __bt_get_error_message(ret));
+
+ ret = bt_gatt_service_add_characteristic(service1, characteristic1_6);
+ BLE_PRT("bt_gatt_service_add_characteristic : %s", __bt_get_error_message(ret));
+
+ ret = bt_gatt_characteristic_create(char_uuid1_7, permissions,
+ properties_read_write_no_response, char_value_unknown,
+ 4, &characteristic1_7);
+ BLE_PRT("bt_gatt_characteristic_create : %s", __bt_get_error_message(ret));
+
+ ret = bt_gatt_server_set_read_value_requested_cb(characteristic1_7,
+ __bt_gatt_read_value1_req_cb, NULL);
+
+ ret = bt_gatt_service_add_characteristic(service1, characteristic1_7);
+ BLE_PRT("bt_gatt_service_add_characteristic : %s", __bt_get_error_message(ret));
+
+ ret = bt_gatt_server_register_service(server, service1);
+ BLE_PRT("bt_gatt_server_register_service : %s", __bt_get_error_message(ret));
+
+ /* Battery Service */
+ ret = bt_gatt_service_create(service_uuid2, BT_GATT_SERVICE_TYPE_PRIMARY, &service2);
+ BLE_PRT("bt_gatt_service_create : %s ", __bt_get_error_message(ret));
+
+ ret = bt_gatt_characteristic_create(char_uuid2_1, permissions,
+ properties_notify_read, char_value,
+ 1, &characteristic2_1);
+ BLE_PRT("bt_gatt_characteristic_create : %s", __bt_get_error_message(ret));
+
+ ret = bt_gatt_server_set_read_value_requested_cb(characteristic2_1,
+ __bt_gatt_read_value_req_cb, NULL);
+
+ ret = bt_gatt_server_set_characteristic_notification_state_change_cb(characteristic2_1,
+ __bt_gatt_notification_state_change_cb, NULL);
+
+ ret = bt_gatt_service_add_characteristic(service2, characteristic2_1);
+ BLE_PRT("bt_gatt_service_add_characteristic : %s", __bt_get_error_message(ret));
+
+ ret = bt_gatt_descriptor_create(desc_uuid2, permissions,
+ desc_value_configration, 2, &descriptor2);
+ BLE_PRT("bt_gatt_descriptor_create : %s", __bt_get_error_message(ret));
+
+ ret = bt_gatt_characteristic_add_descriptor(characteristic2_1, descriptor2);
+ BLE_PRT("bt_gatt_characteristic_add_descriptor : %s", __bt_get_error_message(ret));
+
+ ret = bt_gatt_characteristic_create(char_uuid2_2, permissions,
+ properties_read_write, char_value_unknown,
+ 4, &characteristic2_2);
+ BLE_PRT("bt_gatt_characteristic_create : %s", __bt_get_error_message(ret));
+
+ ret = bt_gatt_server_set_read_value_requested_cb(characteristic2_2,
+ __bt_gatt_read_value_req_cb, NULL);
+
+ ret = bt_gatt_server_set_write_value_requested_cb(characteristic2_2,
+ __bt_gatt_write_value_req_cb, NULL);
+
+ ret = bt_gatt_service_add_characteristic(service2, characteristic2_2);
+ BLE_PRT("bt_gatt_service_add_characteristic : %s", __bt_get_error_message(ret));
+
+ ret = bt_gatt_server_register_service(server, service2);
+ BLE_PRT("bt_gatt_server_register_service : %s", __bt_get_error_message(ret));
+
+ /* Scan Parameters */
+
+ /* Device INformation */
+
+ ret = bt_gatt_server_start();
+ BLE_PRT("bt_gatt_server_start : %s\n", __bt_get_error_message(ret));
+
+ return ret;
+}
+
+static int __bt_unregister_hogp_service(void)
+{
+ int ret = BT_ERROR_NONE;
+
+ ret = bt_gatt_server_unregister_all_services(server);
+ BLE_PRT("returns %s", __bt_get_error_message(ret));
+
+ ret = bt_gatt_server_deinitialize();
+ BLE_PRT("returns %s\n", __bt_get_error_message(ret));
+
+ server = NULL;
+
+ return ret;
+}
+
+static void __bt_advertising_state_changed_cb(int result,
+ bt_advertiser_h advertiser, bt_adapter_le_advertising_state_e adv_state,
+ void *user_data)
+{
+ BLE_PRT("Result : %d", result);
+ BLE_PRT("Advertiser : %p", advertiser);
+ BLE_PRT("Advertising %s [%d]",
+ adv_state == BT_ADAPTER_LE_ADVERTISING_STARTED ?
+ "started" : "stopped", adv_state);
+}
+
+static int __bt_start_advertisement(void)
+{
+ int ret = BT_ERROR_NONE;
+
+ const char *battery_svc_uuid_16 = "180f";
+ const char *hid_svc_uuid_16 = "1812";
+ const char *gatt_svc_uuid_16 = "1801";
+ int appearance = 192; /* 192 is generic watch */
+
+ ret = bt_adapter_le_create_advertiser(&advertiser);
+ BLE_PRT("created le advertiser(%d)", ret);
+
+ ret = bt_adapter_le_add_advertising_service_uuid(advertiser,
+ BT_ADAPTER_LE_PACKET_ADVERTISING, battery_svc_uuid_16);
+ BLE_PRT("add service_uuid [0x%04x]", ret);
+
+ ret = bt_adapter_le_add_advertising_service_uuid(advertiser,
+ BT_ADAPTER_LE_PACKET_ADVERTISING, hid_svc_uuid_16);
+ BLE_PRT("add service_uuid [0x%04x]", ret);
+
+ ret = bt_adapter_le_add_advertising_service_uuid(advertiser,
+ BT_ADAPTER_LE_PACKET_ADVERTISING, gatt_svc_uuid_16);
+ BLE_PRT("add service_uuid [0x%04x]", ret);
+
+ ret = bt_adapter_le_set_advertising_appearance(advertiser,
+ BT_ADAPTER_LE_PACKET_ADVERTISING, appearance);
+ BLE_PRT("add appearance data [0x%04x]", ret);
+
+ ret = bt_adapter_le_set_advertising_tx_power_level(advertiser,
+ BT_ADAPTER_LE_PACKET_ADVERTISING, true);
+ BLE_PRT("add tx_power_level [0x%04x]", ret);
+
+ /* Default scsn response data */
+ ret = bt_adapter_le_set_advertising_device_name(advertiser,
+ BT_ADAPTER_LE_PACKET_SCAN_RESPONSE, true);
+ BLE_PRT("set device name [0x%04x]", ret);
+
+ ret = bt_adapter_le_set_advertising_connectable(advertiser, true);
+ BLE_PRT("add scan response data [0x%04x]", ret);
+
+ ret = bt_adapter_le_start_advertising_new(advertiser, __bt_advertising_state_changed_cb, NULL);
+ BLE_PRT("bt_adapter_le_start_advertising_new [0x%04x]\n", ret);
+
+ return ret;
+}
+
+static int __bt_stop_advertisement(void)
+{
+ int ret = BT_ERROR_NONE;
+
+ ret = bt_adapter_le_stop_advertising(advertiser);
+ BLE_PRT("bt_adapter_le_stop_advertising [0x%04x]\n", ret);
+
+ advertiser = NULL;
+
+ return ret;
+}
+
+static gboolean __bt_start_service(gpointer user_data)
+{
+ if (__bt_register_hogp_service() != BT_ERROR_NONE) {
+ BLE_PRT("__bt_register_hogp_service() failed.");
+ g_main_loop_quit(g_mainloop);
+ return FALSE;
+ }
+
+ if (__bt_start_advertisement() != BT_ERROR_NONE) {
+ BLE_PRT("__bt_start_advertisement() failed.");
+ g_main_loop_quit(g_mainloop);
+ return FALSE;
+ }
+
+ return FALSE;
+}
+
+void __bt_gatt_connection_state_changed_cb(int result,
+ bool connected, const char *remote_address, void *user_data)
+{
+ if (connected) {
+ BLE_PRT("GATT connected [%s]", remote_address);
+
+ if (__bt_stop_advertisement() != BT_ERROR_NONE)
+ BLE_PRT("__bt_stop_advertisement() failed.");
+ } else {
+ BLE_PRT("GATT Disconnected [%s]", remote_address);
+
+ __bt_unregister_hogp_service();
+
+ usleep(50000);
+
+ __bt_register_hogp_service();
+
+ if (__bt_start_advertisement() != BT_ERROR_NONE)
+ BLE_PRT("__bt_start_advertisement() failed.");
+ }
+}
+
+int main()
+{
+ int timeout_id = -1;
+ int ret = BT_ERROR_NONE;
+
+ g_mainloop = g_main_loop_new(NULL, FALSE);
+
+ BLE_PRT("BLE Mouse starts");
+
+ if (bt_initialize() != BT_ERROR_NONE) {
+ BLE_PRT("bt_initialize() failed.");
+ return -1;
+ }
+
+ if (bt_adapter_get_state(&bt_state) != BT_ERROR_NONE) {
+ BLE_PRT("bt_adapter_get_state() failed.");
+ return -1;
+ }
+
+ /* Enable BT */
+ if (bt_state == BT_ADAPTER_DISABLED) {
+ if (bt_adapter_set_state_changed_cb(
+ __bt_state_changed_impl, NULL) != BT_ERROR_NONE) {
+ BLE_PRT("bt_adapter_set_state_changed_cb() failed.");
+ return -1;
+ }
+
+ if (bt_adapter_enable() == BT_ERROR_NONE) {
+ BLE_PRT("bt_adapter_state_changed_cb will be called.");
+ timeout_id = g_timeout_add(60000,
+ __timeout_func, g_mainloop);
+ g_main_loop_run(g_mainloop);
+ g_source_remove(timeout_id);
+ } else {
+ BLE_PRT("bt_adapter_enable() failed.");
+ return -1;
+ }
+ } else {
+ BLE_PRT("BT was already enabled.");
+ }
+
+ /* Set name as "chat_server" */
+ if (bt_state != BT_ADAPTER_ENABLED) {
+ BLE_PRT("BT is not enabled.");
+ return -1;
+ }
+
+ ret = bt_gatt_set_connection_state_changed_cb(
+ __bt_gatt_connection_state_changed_cb, NULL);
+ if (ret != BT_ERROR_NONE)
+ BLE_PRT("returns %s\n", __bt_get_error_message(ret));
+
+ g_idle_add(__bt_start_service, NULL);
+
+ g_main_loop_run(g_mainloop);
+
+ bt_deinitialize();
+
+ BLE_PRT("BLE Mouse ends.");
+ return 0;
+}