case BLUETOOTH_EVENT_OTP_WRITE_CHAR_VAL:
case BLUETOOTH_EVENT_OTP_INDICATION:
case BLUETOOTH_EVENT_OTC_STATE_CHANGED:
+ case BLUETOOTH_EVENT_GATT_READ_CHAR:
+ case BLUETOOTH_EVENT_GATT_WRITE_CHAR:
+ case BLUETOOTH_EVENT_GATT_READ_DESC:
+ case BLUETOOTH_EVENT_GATT_WRITE_DESC:
return true;
default:
break;
bt_event_slot_container[event_index].user_data);
break;
- case BLUETOOTH_EVENT_GATT_READ_CHAR: {
- int ret;
- bt_gatt_client_request_completed_cb cb = bt_event_slot_container[event_index].callback;
- bt_gatt_client_cb_data_s *cb_data = bt_event_slot_container[event_index].user_data;
-
+ case BLUETOOTH_EVENT_GATT_READ_CHAR:
BT_INFO("BLUETOOTH_EVENT_GATT_READ_CHAR");
if (TIZEN_FEATURE_ENABLE_LEGACY_GATT_CLIENT && _bt_gatt_is_legacy_client_mode()) {
break;
}
}
- _bt_unset_cb(BT_EVENT_GATT_CLIENT_READ_CHARACTERISTIC);
- ret = param->result;
- if (ret == BT_ATT_ERROR_NONE) {
- char_val = (bt_gatt_char_value_t *)(param->param_data);
- bt_gatt_set_value(cb_data->gatt_handle,
- (char *)char_val->char_value, (int)char_val->val_len);
- }
- cb(ret, cb_data->gatt_handle, cb_data->user_data);
- g_free(cb_data);
-
+ _handle_gatt_client_read_completed_event(param->result,
+ param->param_data);
break;
- }
- case BLUETOOTH_EVENT_GATT_WRITE_CHAR: {
- int ret;
- bt_gatt_client_request_completed_cb cb = bt_event_slot_container[event_index].callback;
- bt_gatt_client_cb_data_s *cb_data = bt_event_slot_container[event_index].user_data;
-
- BT_INFO("BLUETOOTH_EVENT_GATT_WRITE_CHAR");
-
+ case BLUETOOTH_EVENT_GATT_WRITE_CHAR:
if (TIZEN_FEATURE_ENABLE_LEGACY_GATT_CLIENT && _bt_gatt_is_legacy_client_mode()) {
if (_bt_gatt_is_legacy_client_mode()) {
((bt_gatt_characteristic_write_cb)bt_event_slot_container[event_index].callback)
break;
}
}
- _bt_unset_cb(BT_EVENT_GATT_CLIENT_WRITE_CHARACTERISTIC);
-
- ret = param->result;
-
- if (ret != BT_ATT_ERROR_NONE)
- BT_ERR("BLUETOOTH_EVENT_GATT_WRITE_CHAR - ret [%d]", ret);
-
- cb(ret, cb_data->gatt_handle, cb_data->user_data);
- g_free(cb_data);
+ _handle_gatt_client_write_completed_event(param->result,
+ param->param_data);
break;
- }
- case BLUETOOTH_EVENT_GATT_READ_DESC: {
- int ret;
- bt_gatt_client_request_completed_cb cb = bt_event_slot_container[event_index].callback;
- bt_gatt_client_cb_data_s *cb_data = bt_event_slot_container[event_index].user_data;
- bt_gatt_char_property_t *desc_val = NULL;
-
+ case BLUETOOTH_EVENT_GATT_READ_DESC:
BT_INFO("BLUETOOTH_EVENT_GATT_READ_DESC");
-
- _bt_unset_cb(BT_EVENT_GATT_CLIENT_READ_DESCRIPTOR);
- ret = param->result;
- if (ret == BT_ATT_ERROR_NONE) {
- desc_val = (bt_gatt_char_property_t *)(param->param_data);
- bt_gatt_set_value(cb_data->gatt_handle,
- desc_val->description, (int)desc_val->val_len);
- }
- cb(ret, cb_data->gatt_handle, cb_data->user_data);
- g_free(cb_data);
-
+ _handle_gatt_client_read_completed_event(param->result,
+ param->param_data);
break;
- }
- case BLUETOOTH_EVENT_GATT_WRITE_DESC: {
- int ret;
- bt_gatt_client_request_completed_cb cb = bt_event_slot_container[event_index].callback;
- bt_gatt_client_cb_data_s *cb_data = bt_event_slot_container[event_index].user_data;
-
+ case BLUETOOTH_EVENT_GATT_WRITE_DESC:
BT_INFO("BLUETOOTH_EVENT_GATT_WRITE_DESC");
-
- _bt_unset_cb(BT_EVENT_GATT_CLIENT_WRITE_DESCRIPTOR);
- ret = param->result;
- cb(ret, cb_data->gatt_handle, cb_data->user_data);
- g_free(cb_data);
-
+ _handle_gatt_client_write_completed_event(param->result,
+ param->param_data);
break;
- }
case BLUETOOTH_EVENT_GATT_SERVER_READ_REQUESTED: {
bt_gatt_read_req_t *read_req = param->param_data;
bt_gatt_server_read_value_requested_cb cb;
BT_CHECK_INPUT_PARAMETER(characteristic);
BT_CHECK_INPUT_PARAMETER(callback); /* LCOV_EXCL_START */
- ret = _bt_get_error_code(bluetooth_gatt_read_characteristic_value((const char *)characteristic));
+ ret = _bt_get_error_code(bluetooth_gatt_read_characteristic_value((const char *)characteristic, NULL));
if (ret != BT_ERROR_NONE) {
BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret);
g_free(desc->path);
g_free(desc->uuid);
g_free(desc->value);
- g_free(desc);
+
+ if (!desc->read_cb && !desc->write_cb)
+ g_free(desc);
+ else
+ desc->parent = NULL;
}
static void __bt_gatt_free_characteristic(bt_gatt_h gatt_handle)
g_free(chr->path);
g_free(chr->uuid);
g_free(chr->value);
- g_free(chr);
+
+ if (!chr->read_cb && !chr->write_cb)
+ g_free(chr);
+ else
+ chr->parent = NULL;
}
static void __bt_gatt_free_service(bt_gatt_h gatt_handle)
return BT_ERROR_NONE;
}
+static int __get_write_prop(bt_gatt_write_type_e type, bt_gatt_property_e *prop)
+{
+ if (!prop)
+ return BT_ERROR_INVALID_PARAMETER;
+
+ switch (type) {
+ case BT_GATT_WRITE_TYPE_WRITE:
+ *prop = BT_GATT_PROPERTY_WRITE;
+ break;
+ case BT_GATT_WRITE_TYPE_WRITE_NO_RESPONSE:
+ *prop = BT_GATT_PROPERTY_WRITE_WITHOUT_RESPONSE;
+ break;
+/* After ACR for BT_GATT_WRITE_TYPE_SIGNED_WRITE, will enable this code */
+#if 0
+ case BT_GATT_WRITE_TYPE_SIGNED_WRITE:
+ *prop = BT_GATT_PROPERTY_AUTHENTICATED_SIGNED_WRITES;
+ break;
+#endif
+ default:
+ BT_ERR("Unknow write type : %d", type);
+ return BT_ERROR_INVALID_PARAMETER;
+ }
+
+ return BT_ERROR_NONE;
+}
+
int bt_gatt_service_destroy(bt_gatt_h gatt_handle)
{
bt_gatt_common_s *handle = (bt_gatt_common_s *)gatt_handle;
bt_gatt_write_type_e write_type)
{
bt_gatt_characteristic_s *chr = (bt_gatt_characteristic_s *)characteristic;
- int property;
+ bt_gatt_property_e property = BT_GATT_PROPERTY_WRITE;
+ int ret;
BT_CHECK_GATT_SUPPORT();
BT_CHECK_INIT_STATUS();
return BT_ERROR_INVALID_PARAMETER; /* LCOV_EXCL_LINE */
}
- switch (write_type) {
- case BT_GATT_WRITE_TYPE_WRITE:
- property = BT_GATT_PROPERTY_WRITE;
- break;
- case BT_GATT_WRITE_TYPE_WRITE_NO_RESPONSE:
- property = BT_GATT_PROPERTY_WRITE_WITHOUT_RESPONSE;
- break;
-/* After ACR for BT_GATT_WRITE_TYPE_SIGNED_WRITE, will enable this code */
-#if 0
- case BT_GATT_WRITE_TYPE_SIGNED_WRITE:
- property = BT_GATT_PROPERTY_AUTHENTICATED_SIGNED_WRITES;
- break;
-#endif
- default:
+ ret = __get_write_prop(write_type, &property);
+ if (ret != BT_ERROR_NONE)
return BT_ERROR_NOT_SUPPORTED;
- }
if (!(chr->properties & property))
return BT_ERROR_NOT_SUPPORTED;
return BT_ERROR_NONE;
}
-static bool __bt_gatt_client_is_in_progress(void)
+void _handle_gatt_client_read_completed_event(int result, bt_gatt_resp_data_t *resp)
{
- if (_bt_check_cb(BT_EVENT_GATT_CLIENT_WRITE_CHARACTERISTIC) ||
- _bt_check_cb(BT_EVENT_GATT_CLIENT_WRITE_DESCRIPTOR) ||
- _bt_check_cb(BT_EVENT_GATT_CLIENT_READ_CHARACTERISTIC) ||
- _bt_check_cb(BT_EVENT_GATT_CLIENT_READ_DESCRIPTOR)) {
- BT_ERR("Operation is in progress");
- return true;
+ bt_gatt_common_s *handle;
+ bt_gatt_client_request_completed_cb cb = NULL;
+ void *user_data = NULL;
+
+ if (resp == NULL) {
+ BT_ERR("GATT Client response data is NULL");
+ return;
+ }
+
+ handle = resp->user_data;
+ if (handle->type == BT_GATT_TYPE_CHARACTERISTIC) {
+ bt_gatt_characteristic_s *chr = (bt_gatt_characteristic_s *)handle;
+
+ cb = chr->read_cb;
+ user_data = chr->read_user_data;
+
+ chr->read_cb = NULL;
+ chr->read_user_data = NULL;
+
+ if (!chr->parent) {
+ BT_INFO("Already destroyed handle : %p", chr);
+ if (!chr->write_cb)
+ g_free(chr);
+ return;
+ }
+ } else if (handle->type == BT_GATT_TYPE_DESCRIPTOR) {
+ bt_gatt_descriptor_s *desc = (bt_gatt_descriptor_s *)handle;
+
+ cb = desc->read_cb;
+ user_data = desc->read_user_data;
+
+ desc->read_cb = NULL;
+ desc->read_user_data = NULL;
+
+ if (!desc->parent) {
+ BT_INFO("Already destroyed handle : %p", desc);
+ if (!desc->write_cb)
+ g_free(desc);
+ return;
+ }
+ }
+
+ if (result == BLUETOOTH_ATT_ERROR_NONE) {
+ bt_gatt_set_value(handle,
+ (char *)resp->value, (int)resp->len);
+ }
+
+ if (cb)
+ cb(result, handle, user_data);
+
+ return;
+}
+
+void _handle_gatt_client_write_completed_event(int result, bt_gatt_resp_data_t *resp)
+{
+ bt_gatt_common_s *handle;
+ bt_gatt_client_request_completed_cb cb = NULL;
+ void *user_data = NULL;
+
+ if (resp == NULL) {
+ BT_ERR("GATT Client response data is NULL");
+ return;
+ }
+
+ handle = resp->user_data;
+ if (handle->type == BT_GATT_TYPE_CHARACTERISTIC) {
+ bt_gatt_characteristic_s *chr = (bt_gatt_characteristic_s *)handle;
+
+ cb = chr->write_cb;
+ user_data = chr->write_user_data;
+
+ chr->write_cb = NULL;
+ chr->write_user_data = NULL;
+
+ if (!chr->parent) {
+ BT_INFO("Already destroyed handle : %p", chr);
+ if (!chr->read_cb)
+ g_free(chr);
+ return;
+ }
+ } else if (handle->type == BT_GATT_TYPE_DESCRIPTOR) {
+ bt_gatt_descriptor_s *desc = (bt_gatt_descriptor_s *)handle;
+
+ cb = desc->write_cb;
+ user_data = desc->write_user_data;
+
+ desc->write_cb = NULL;
+ desc->write_user_data = NULL;
+
+ if (!desc->parent) {
+ BT_INFO("Already destroyed handle : %p", desc);
+ if (!desc->read_cb)
+ g_free(desc);
+ return;
+ }
}
- return false; /* LCOV_EXCL_STOP */
+ if (cb)
+ cb(result, handle, user_data);
+
+ return; /* LCOV_EXCL_STOP */
}
int bt_gatt_client_read_value(bt_gatt_h gatt_handle,
{
int ret = BT_ERROR_NONE;
bt_gatt_common_s *c = (bt_gatt_common_s *)gatt_handle;
- bt_gatt_client_cb_data_s *cb_data;
BT_CHECK_GATT_SUPPORT();
BT_CHECK_INIT_STATUS();
BT_CHECK_INPUT_PARAMETER(gatt_handle);
BT_CHECK_INPUT_PARAMETER(callback); /* LCOV_EXCL_START */
- if (__bt_gatt_client_is_in_progress()) {
- BT_ERR("Operation is in progress");
- return BT_ERROR_NOW_IN_PROGRESS;
- }
-
- cb_data = malloc(sizeof(bt_gatt_client_cb_data_s));
- if (cb_data == NULL) {
- BT_ERR("Cannot alloc cb_data");
- return BT_ERROR_OPERATION_FAILED;
- }
-
- cb_data->gatt_handle = gatt_handle;
- cb_data->user_data = user_data;
-
if (c->type == BT_GATT_TYPE_CHARACTERISTIC) {
bt_gatt_characteristic_s *chr = (bt_gatt_characteristic_s *)gatt_handle;
+ if (chr->read_cb) {
+ BT_ERR("read request is now in progress");
+ return BT_ERROR_NOW_IN_PROGRESS;
+ }
+
ret = _bt_get_error_code(
- bluetooth_gatt_read_characteristic_value(chr->path));
- if (ret != BT_ERROR_NONE) {
- g_free(cb_data);
- BT_ERR("%s(0x%08x)",
- _bt_convert_error_to_string(ret), ret);
+ bluetooth_gatt_read_characteristic_value(chr->path, gatt_handle));
+ if (ret == BT_ERROR_NONE) {
+ chr->read_cb = callback;
+ chr->read_user_data = user_data;
} else {
- _bt_set_cb(BT_EVENT_GATT_CLIENT_READ_CHARACTERISTIC,
- callback, cb_data);
+ BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret);
}
} else if (c->type == BT_GATT_TYPE_DESCRIPTOR) {
bt_gatt_descriptor_s *desc = (bt_gatt_descriptor_s *)gatt_handle;
+ if (desc->read_cb) {
+ BT_ERR("read request is now in progress");
+ return BT_ERROR_NOW_IN_PROGRESS;
+ }
+
ret = _bt_get_error_code(
- bluetooth_gatt_read_descriptor_value(desc->path));
- if (ret != BT_ERROR_NONE) {
- g_free(cb_data);
- BT_ERR("%s(0x%08x)",
- _bt_convert_error_to_string(ret), ret);
+ bluetooth_gatt_read_descriptor_value(desc->path, gatt_handle));
+ if (ret == BT_ERROR_NONE) {
+ desc->read_cb = callback;
+ desc->read_user_data = user_data;
} else {
- _bt_set_cb(BT_EVENT_GATT_CLIENT_READ_DESCRIPTOR,
- callback, cb_data);
+ BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret);
}
} else {
+ ret = BT_ERROR_INVALID_PARAMETER;
BT_ERR("Invalid handle type for read ");
- g_free(cb_data);
}
return ret; /* LCOV_EXCL_STOP */
int bt_gatt_client_write_value(bt_gatt_h gatt_handle,
bt_gatt_client_request_completed_cb callback, void *user_data)
{
- int ret = BT_ERROR_NONE;
bt_gatt_common_s *c = (bt_gatt_common_s *)gatt_handle;
- bt_gatt_client_cb_data_s *cb_data;
+ bt_gatt_property_e write_prop = BT_GATT_PROPERTY_WRITE;
+ int ret = BT_ERROR_NONE;
BT_CHECK_GATT_SUPPORT();
BT_CHECK_INIT_STATUS();
- BT_CHECK_INPUT_PARAMETER(gatt_handle);
- BT_CHECK_INPUT_PARAMETER(callback); /* LCOV_EXCL_START */
-
- if (__bt_gatt_client_is_in_progress()) {
- BT_ERR("Operation is in progress");
- return BT_ERROR_NOW_IN_PROGRESS;
- }
-
- cb_data = malloc(sizeof(bt_gatt_client_cb_data_s));
- if (cb_data == NULL) {
- BT_ERR("Cannot alloc cb_data");
- return BT_ERROR_OPERATION_FAILED;
- }
-
- cb_data->gatt_handle = gatt_handle;
- cb_data->user_data = user_data;
+ BT_CHECK_INPUT_PARAMETER(gatt_handle); /* LCOV_EXCL_START */
if (c->type == BT_GATT_TYPE_CHARACTERISTIC) {
bt_gatt_characteristic_s *chr = (bt_gatt_characteristic_s *)gatt_handle;
- BT_DBG("path : %s", chr->path);
- if (chr->write_type == BT_GATT_WRITE_TYPE_WRITE)
- ret = _bt_get_error_code(bluetooth_gatt_set_characteristics_value_by_type(
- chr->path, (guint8 *)chr->value,
- chr->value_length,
- BT_GATT_PROPERTY_WRITE));
- else if (chr->write_type == BT_GATT_WRITE_TYPE_WRITE_NO_RESPONSE)
- ret = _bt_get_error_code(bluetooth_gatt_set_characteristics_value_by_type(
- chr->path, (guint8 *)chr->value,
- chr->value_length,
- BT_GATT_PROPERTY_WRITE_WITHOUT_RESPONSE));
-/* After ACR for BT_GATT_WRITE_TYPE_SIGNED_WRITE, will enable this code */
-#if 0
-
- else if (chr->write_type == BT_GATT_WRITE_TYPE_SIGNED_WRITE)
- ret = _bt_get_error_code(bluetooth_gatt_set_characteristics_value_by_type(
- chr->path, (guint8 *)chr->value, chr->value_length,
- BT_GATT_PROPERTY_AUTHENTICATED_SIGNED_WRITES));
-#endif
- else {
- BT_ERR("Unknow write type : %d", chr->write_type);
- BT_ERR("path : %s", chr->path);
- ret = BT_ERROR_OPERATION_FAILED;
+ if (chr->write_cb) {
+ BT_ERR("write request is now in progress");
+ return BT_ERROR_NOW_IN_PROGRESS;
}
- if (ret != BT_ERROR_NONE) {
- g_free(cb_data);
- BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret);
+
+ ret = __get_write_prop(chr->write_type, &write_prop);
+ if (ret != BT_ERROR_NONE)
+ return BT_ERROR_OPERATION_FAILED;
+
+ ret = _bt_get_error_code(bluetooth_gatt_set_characteristics_value_by_type(
+ chr->path, (guint8 *)chr->value,
+ chr->value_length, write_prop,
+ gatt_handle));
+ if (ret == BT_ERROR_NONE) {
+ chr->write_cb = callback;
+ chr->write_user_data = user_data;
} else {
- _bt_set_cb(BT_EVENT_GATT_CLIENT_WRITE_CHARACTERISTIC, callback, cb_data);
+ BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret);
}
} else if (c->type == BT_GATT_TYPE_DESCRIPTOR) {
bt_gatt_descriptor_s *desc = (bt_gatt_descriptor_s *)gatt_handle;
+ if (desc->write_cb) {
+ BT_ERR("write request is now in progress");
+ return BT_ERROR_NOW_IN_PROGRESS;
+ }
+
ret = _bt_get_error_code(bluetooth_gatt_write_descriptor_value(
- desc->path,
- (guint8 *)desc->value,
- desc->value_length));
- if (ret != BT_ERROR_NONE) {
- g_free(cb_data);
- BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret);
+ desc->path, (guint8 *)desc->value,
+ desc->value_length, gatt_handle));
+ if (ret == BT_ERROR_NONE) {
+ desc->write_cb = callback;
+ desc->write_user_data = user_data;
} else {
- _bt_set_cb(BT_EVENT_GATT_CLIENT_WRITE_DESCRIPTOR, callback, cb_data);
+ BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret);
}
} else {
- BT_ERR("Invalid handle type for write ");
- g_free(cb_data);
+ BT_ERR("Invalid handle type for write");
+ ret = BT_ERROR_INVALID_PARAMETER;
}
return ret;