static GDBusNodeInfo *manager_node_info = NULL;
static guint manager_id;
-/* Global handles which needs to be incremented during each addition */
-#define SERVICE_HANDLE_NUM 100
-#define CHAR_HANDLE_NUM 200
-#define DESC_HANDLE_NUM 300
-static int gatt_service_handle = SERVICE_HANDLE_NUM;
-static int gatt_char_handle = CHAR_HANDLE_NUM;
-static int gatt_desc_handle = DESC_HANDLE_NUM;
+#define GATT_HANDLE_MAX_NUM 100 /* Not defined in spec, implementation dependent */
+#define SERV_HANDLE_NUM (GATT_HANDLE_MAX_NUM)
+#define CHAR_HANDLE_NUM (SERV_HANDLE_NUM + GATT_HANDLE_MAX_NUM)
+#define DESC_HANDLE_NUM (CHAR_HANDLE_NUM + GATT_HANDLE_MAX_NUM)
+typedef enum {
+ BT_GATT_TYPE_SERV,
+ BT_GATT_TYPE_CHAR,
+ BT_GATT_TYPE_DESC,
+ BT_GATT_TYPE_MAX
+} bt_gatt_type_e;
+static int assigned_handle[BT_GATT_TYPE_MAX];
+static gboolean gatt_handle_used[BT_GATT_TYPE_MAX][GATT_HANDLE_MAX_NUM];
+static int gatt_handle_base[BT_GATT_TYPE_MAX] = {SERV_HANDLE_NUM, CHAR_HANDLE_NUM, DESC_HANDLE_NUM};
struct gatt_service_info {
gchar *serv_path;
" <arg type='u' name='id' direction='in'/>"
" <arg type='q' name='offset' direction='in'/>"
" <arg type='b' name='response_needed' direction='in'/>"
+" <arg type='b' name='prep_authorize' direction='in'/>"
" <arg type='ay' name='value' direction='in'/>"
" </method>"
" <method name ='AcquireWrite'>"
" <arg type='u' name='id' direction='in'/>"
" <arg type='q' name='offset' direction='in'/>"
" <arg type='b' name='response_needed' direction='in'/>"
+" <arg type='b' name='prep_authorize' direction='in'/>"
" <arg type='ay' name='value' direction='in'/>"
" </method>"
" </interface>"
assigned_id = 0;
memset(instance_id_used, 0x00, sizeof(instance_id_used));
+ assigned_handle[BT_GATT_TYPE_SERV] = assigned_handle[BT_GATT_TYPE_CHAR] = assigned_handle[BT_GATT_TYPE_DESC] = -1;
+ memset(gatt_handle_used, 0x00, sizeof(gatt_handle_used));
+
g_slist_free_full(gatt_server_apps, (GDestroyNotify)__bt_free_gatt_server_app);
gatt_server_apps = NULL;
instance_id_used[instance_id] = FALSE;
}
+static int __bt_hal_assign_gatt_handle(bt_gatt_type_e type)
+{
+ int index;
+
+ index = assigned_handle[type] + 1;
+
+ if (index >= GATT_HANDLE_MAX_NUM)
+ index = 0;
+
+ while (gatt_handle_used[type][index] == TRUE) {
+ if (index == assigned_handle[type]) {
+ /* No available handle */
+ ERR("All handle is used");
+ return -1;
+ }
+
+ index++;
+
+ if (index >= GATT_HANDLE_MAX_NUM)
+ index = 0;
+ }
+
+ assigned_handle[type] = index;
+ gatt_handle_used[type][index] = TRUE;
+
+ return assigned_handle[type] + gatt_handle_base[type];
+}
+
+static void __bt_hal_free_gatt_handle(bt_gatt_type_e type, int handle)
+{
+ int index;
+
+ if (type >= BT_GATT_TYPE_MAX) {
+ ERR("Invalid type");
+ return;
+ }
+
+ index = handle - gatt_handle_base[type];
+ if (index < 0 || index >= GATT_HANDLE_MAX_NUM) {
+ ERR("Invalid handle: %d(type: %d)", handle, type);
+ return;
+ }
+
+ gatt_handle_used[type][index] = FALSE;
+}
+
static GSList *_bt_get_service_list_from_server(int instance)
{
GSList *l;
guint req_id = 0;
guint16 offset = 0;
gboolean response_needed = FALSE;
+ gboolean prep_authorize = FALSE;
struct hal_ev_gatt_server_write_req ev;
int desc_hdl = -1;
int len;
DBG("Application path = %s", object_path);
DBG("Sender = %s", sender);
- g_variant_get(parameters, "(&suqb@ay)",
- &addr, &req_id, &offset, &response_needed, &var);
+ g_variant_get(parameters, "(&suqbb@ay)",
+ &addr, &req_id, &offset, &response_needed, &prep_authorize, &var);
DBG("Request id = %u, Offset = %u", req_id, offset);
+ if (prep_authorize)
+ DBG("prep_authorize = true");
+
/* Check if device is already in connected list */
conn_info = __bt_find_remote_gatt_client_info(addr);
guint req_id = 0;
guint16 offset = 0;
gboolean response_needed = FALSE;
+ gboolean prep_authorize = FALSE;
struct hal_ev_gatt_server_write_req ev;
int char_hdl = -1;
int len;
DBG("WriteValue : Application path %s, sender %s", object_path, sender);
- g_variant_get(parameters, "(&suqb@ay)",
- &addr, &req_id, &offset, &response_needed, &var);
+ g_variant_get(parameters, "(&suqbb@ay)",
+ &addr, &req_id, &offset, &response_needed, &prep_authorize, &var);
DBG("Request id = %u, Offset = %u", req_id, offset);
+ if (prep_authorize)
+ DBG("prep_authorize = true");
+
svc_info = __bt_gatt_find_gatt_service_from_char(object_path, &char_hdl);
/* Check if device is already in connected list */
gboolean svc_primary = TRUE;
GError *error = NULL;
hal_gatt_service_added *user_data = NULL;
+ int service_handle = 0;
DBG("Service add to DBUS slot [%d]", slot);
- DBG("Add new GATT Service: Current GATT Service handle [%d]", gatt_service_handle);
- if (gatt_service_handle >= CHAR_HANDLE_NUM) {
- ERR("Exceeded the number of service");
+ service_handle = __bt_hal_assign_gatt_handle(BT_GATT_TYPE_SERV);
+ if (service_handle == -1) {
+ ERR("Too many gatt service handles are created");
return BT_STATUS_FAIL;
}
- path = g_strdup_printf("%s"GATT_SERV_OBJECT_PATH"%d", app_path, ++gatt_service_handle);
+
+ path = g_strdup_printf("%s"GATT_SERV_OBJECT_PATH"%d", app_path, service_handle);
DBG("gatt service path is [%s]", path);
node_info = __bt_gatt_create_method_node_info(
service_introspection_xml);
if (node_info == NULL) {
g_free(path);
+ __bt_hal_free_gatt_handle(BT_GATT_TYPE_SERV, service_handle);
return BT_STATUS_FAIL;
}
ERR("failed to register: %s", error->message);
g_error_free(error);
g_free(path);
+ __bt_hal_free_gatt_handle(BT_GATT_TYPE_SERV, service_handle);
return BT_STATUS_FAIL;
}
/* Add object_id/gatt service information; it's required at the time of
serv_info->service_uuid = __bt_hal_convert_uuid_to_string(&srvc_id->id.uuid);//g_strdup(btuuid2str(srvc_id->id.uuid.uu));
serv_info->is_svc_registered = FALSE;
serv_info->is_svc_primary = svc_primary;
- DBG("Service Handle to be added is [%d]", gatt_service_handle);
- serv_info->service_handle = gatt_service_handle;
+ DBG("Service Handle to be added is [%d]", service_handle);
+ serv_info->service_handle = service_handle;
/* Update service in GATT Server service List */
gatt_services = g_slist_append(gatt_services, serv_info);
int flag_count = 0;
hal_gatt_char_added *user_data = NULL;
int *app_id;
+ int char_handle = 0;
CHECK_BTGATT_INIT();
DBG("Add new characteristic to GATT Service handle [%d]", service_handle);
if (serv_info == NULL)
return BT_STATUS_FAIL;
- DBG("Add new GATT characteristic: Current GATT char handle [%d]", gatt_char_handle);
- if (gatt_char_handle >= DESC_HANDLE_NUM) {
- ERR("Exceeded the number of characteristic");
+ char_handle = __bt_hal_assign_gatt_handle(BT_GATT_TYPE_CHAR);
+ if (char_handle == -1) {
+ ERR("Too many gatt char handles are created");
return BT_STATUS_FAIL;
}
- path = g_strdup_printf("%s/characteristic%d", serv_info->serv_path, ++gatt_char_handle);
+
+ DBG("Add new GATT characteristic: Current GATT char handle [%d]", char_handle);
+ path = g_strdup_printf("%s/characteristic%d", serv_info->serv_path, char_handle);
DBG("gatt characteristic path is [%s]", path);
node_info = __bt_gatt_create_method_node_info(
characteristics_introspection_xml);
if (node_info == NULL) {
g_free(path);
+ __bt_hal_free_gatt_handle(BT_GATT_TYPE_CHAR, char_handle);
return BT_STATUS_FAIL;
}
g_error_free(error);
g_free(path);
g_free(app_id);
+ __bt_hal_free_gatt_handle(BT_GATT_TYPE_CHAR, char_handle);
return BT_STATUS_FAIL;
}
char_info->flags_length = flag_count;
- char_info->char_handle = gatt_char_handle;
+ char_info->char_handle = char_handle;
builder = g_variant_builder_new(G_VARIANT_TYPE("a{sa{sv}}"));
/* Send Service handle to application */
user_data = g_malloc0(sizeof(hal_gatt_char_added));
user_data->srvc_hdl = serv_info->service_handle;
- user_data->char_hdl = gatt_char_handle;
+ user_data->char_hdl = char_handle;
user_data->instance_data = slot;
memcpy(user_data->uuid.uu, uuid->uu, sizeof(uuid->uu));
g_idle_add(__bt_hal_gatt_char_added_cb, (gpointer)user_data);
int flag_count = 0;
int *app_id;
hal_gatt_desc_added *user_data = NULL;
+ int desc_handle = 0;
/* Fetch service data for the GATT server */
serv_info = __bt_gatt_find_gatt_service_info(slot, service_handle);
return BT_STATUS_FAIL;
}
- DBG("Add new Descriptor: Current GATT desc handle [%d]", gatt_desc_handle);
+ desc_handle = __bt_hal_assign_gatt_handle(BT_GATT_TYPE_DESC);
+ if (desc_handle == -1) {
+ ERR("Too many gatt desc handles are created");
+ g_free(serv_path);
+ return BT_STATUS_FAIL;
+ }
- path = g_strdup_printf("%s/descriptor%d", char_path, ++gatt_desc_handle);
+ DBG("Add new Descriptor: Current GATT desc handle [%d]", desc_handle);
+ path = g_strdup_printf("%s/descriptor%d", char_path, desc_handle);
DBG("gatt descriptor path is [%s]", path);
app_id = g_malloc0(sizeof(int));
g_strfreev(line_argv);
g_free(serv_path);
g_free(app_id);
+ __bt_hal_free_gatt_handle(BT_GATT_TYPE_DESC, desc_handle);
return BT_STATUS_FAIL;
}
desc_info->desc_flags[i] = desc_flags[i];
desc_info->flags_length = flag_count;
- desc_info->desc_handle = gatt_desc_handle;
+ desc_info->desc_handle = desc_handle;
builder = g_variant_builder_new(G_VARIANT_TYPE("a{sa{sv}}"));
/* Send descriptor handle to application */
user_data = g_malloc0(sizeof(hal_gatt_desc_added));
user_data->srvc_hdl = serv_info->service_handle;
- user_data->desc_hdl = gatt_desc_handle;
+ user_data->desc_hdl = desc_handle;
user_data->instance_data = slot;
memcpy(user_data->uuid.uu, uuid->uu, sizeof(uuid->uu));
g_idle_add(__bt_hal_gatt_desc_added_cb, (gpointer)user_data);
/* list remove & free */
char_info->desc_data = g_slist_remove(char_info->desc_data, desc_info);
+ __bt_hal_free_gatt_handle(BT_GATT_TYPE_DESC, desc_info->desc_handle);
__bt_hal_gatt_free_descriptor_info(desc_info);
}
/* list remove & free */
serv_info->char_data = g_slist_remove(serv_info->char_data, char_info);
+ __bt_hal_free_gatt_handle(BT_GATT_TYPE_CHAR, char_info->char_handle);
__bt_hal_gatt_free_characteristic_info(char_info);
}
/* Remove from global list */
gatt_services = g_slist_remove(gatt_services, serv_info);
+ __bt_hal_free_gatt_handle(BT_GATT_TYPE_SERV, serv_info->service_handle);
INFO("After removing from global list total service dount [%d]", g_slist_length(gatt_services));
/* Remove from GATT Server's list of services */