{BT_TDS_ACTIVATE_CONTROL_POINT, "BT_TDS_ACTIVATE_CONTROL_POINT"},
{BT_OTP_READ_VALUE, "BT_OTP_READ_VALUE"},
{BT_OTP_ENABLE_NOTIFICATION, "BT_OTP_ENABLE_NOTIFICATION"},
+ {BT_OTP_WRITE_VALUE, "BT_OTP_WRITE_VALUE"},
{-1, ""},
};
_bt_common_event_cb(BLUETOOTH_EVENT_OTP_NOTIFICATION_ENABLED,
result, handle,
event_info->cb, event_info->user_data);
+ } else if (strcasecmp(signal_name, BT_OTP_WRITE_CHAR_VAL) == 0) {
+ BT_DBG("OTP Control point Activation result");
+ char *handle = NULL;
+
+ /* Extract data from DBUS params */
+ g_variant_get(parameters, "(i&s)", &result, &handle);
+ BT_DBG("Handle [%s]", handle);
+ BT_DBG("Result [%d]", result);
+
+ _bt_common_event_cb(BLUETOOTH_EVENT_OTP_WRITE_CHAR_VAL,
+ result, handle,
+ event_info->cb, event_info->user_data);
+ } else if (strcasecmp(signal_name, BT_OTP_INDICATION) == 0) {
+ BT_DBG("OTP Control point Indication Response");
+ bluetooth_otp_resp_info_t *ind_res = NULL;
+ char *buffer = NULL;
+ GVariant *byte_var = NULL;
+ char *handle = NULL;
+
+ g_variant_get(parameters, "(i&s@ay)", &result, &handle, &byte_var);
+
+ ind_res = g_malloc0(sizeof(bluetooth_otp_resp_info_t));
+ ind_res->data_length = g_variant_get_size(byte_var);
+ buffer = (char *)g_variant_get_data(byte_var);
+ ind_res->data = g_memdup(buffer, ind_res->data_length);
+ ind_res->handle = g_strdup(handle);
+
+ _bt_common_event_cb(BLUETOOTH_EVENT_OTP_INDICATION,
+ result, ind_res,
+ event_info->cb, event_info->user_data);
+
+ if (ind_res->handle) {
+ g_free(ind_res->handle);
+ }
+
+ if (ind_res->data) {
+ g_free(ind_res->data);
+ g_free(ind_res);
+ }
+ if (byte_var)
+ g_variant_unref(byte_var);
}
BT_DBG("-");
BT_DBG("-");
return result;
-}
\ No newline at end of file
+}
+
+BT_EXPORT_API int bluetooth_otp_write_characteristics_value(const char *handle,
+ unsigned char *buf, int length)
+{
+ char *path;
+ int path_len = 0;
+ bt_user_info_t *user_info;
+ int result = BLUETOOTH_ERROR_INTERNAL;
+ bluetooth_otp_charc_data_t data;
+ BT_DBG("+");
+
+ BT_CHECK_PARAMETER(handle, return);
+ BT_CHECK_PARAMETER(buf, return);
+ BT_CHECK_ENABLED_LE(return);
+
+ user_info = _bt_get_user_data(BT_COMMON);
+ retv_if(user_info->cb == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+ BT_INIT_PARAMS();
+ BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+
+ memset(&data, 0x00, sizeof(bluetooth_otp_charc_data_t));
+
+ data.length = length;
+ if (length > 0)
+ memcpy(data.data, buf, length);
+
+ path = g_strdup(handle);
+ path_len = _bluetooth_handle_get_len(path);
+
+ /*Fill parameters*/
+ g_array_append_vals(in_param1, path, path_len);
+
+ g_array_append_vals(in_param2, &data, sizeof(bluetooth_otp_charc_data_t));
+
+ int i;
+ for (i = 0; i < length; i++)
+ BT_INFO("Value[%d] = %u", i, buf[i]);
+ result = _bt_send_request_async(BT_BLUEZ_SERVICE, BT_OTP_WRITE_VALUE,
+ in_param1, in_param2, in_param3, in_param4,
+ user_info->cb, user_info->user_data);
+
+ BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+
+ g_free(path);
+ BT_DBG("-");
+ return result;
+}
static int adv_handle = 0;
static gboolean OLCP_indicate = FALSE;
char *directory = NULL;
+gboolean mutiple_obj_support = false;
static const gchar otp_introspection_xml[] =
"<node name='/'>"
void _bt_otp_deinit_event_receiver(void);
void _bt_otp_unregister_interface(void);
+void update_obj_metadata_charc_value(struct object_metadata *object);
static void delete_all_objects(void)
{
if (ret != BLUETOOTH_ERROR_NONE)
goto fail;
- /* Characteristic Object ID */
- props = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_READ;
- perms = BLUETOOTH_GATT_PERMISSION_READ;
- char_uuid = _otp_convert_uuid_to_uuid128(OTP_OBJECT_ID_UUID);
- ret = add_new_characteristic(char_uuid, perms, props,
- &otp_object_id_obj_path);
- if (ret != BLUETOOTH_ERROR_NONE)
- goto fail;
+ /* Object ID is mandatory for mutiple object server */
+ if (mutiple_obj_support) {
+ /* Characteristic Object ID */
+ props = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_READ;
+ perms = BLUETOOTH_GATT_PERMISSION_READ;
+ char_uuid = _otp_convert_uuid_to_uuid128(OTP_OBJECT_ID_UUID);
+ ret = add_new_characteristic(char_uuid, perms, props,
+ &otp_object_id_obj_path);
+ if (ret != BLUETOOTH_ERROR_NONE)
+ goto fail;
+ }
/* Characteristic Object Properties */
props = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_READ;
goto fail;
}
- /* Characteristic OLCP */
- props = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITE |
- BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_INDICATE;
- perms = BLUETOOTH_GATT_PERMISSION_WRITE;
- char_uuid = _otp_convert_uuid_to_uuid128(OTP_OLCP_UUID);
- ret = add_new_characteristic(char_uuid, perms, props,
- &otp_olcp_obj_path);
- if (ret != BLUETOOTH_ERROR_NONE)
- goto fail;
+ /* OLCP Characteristics is not required
+ * for single object server
+ */
+ if (mutiple_obj_support) {
+ /* Characteristic OLCP */
+ props = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITE |
+ BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_INDICATE;
+ perms = BLUETOOTH_GATT_PERMISSION_WRITE;
+ char_uuid = _otp_convert_uuid_to_uuid128(OTP_OLCP_UUID);
+ ret = add_new_characteristic(char_uuid, perms, props,
+ &otp_olcp_obj_path);
+ if (ret != BLUETOOTH_ERROR_NONE)
+ goto fail;
- /* CCCD for OLCP */
- desc_uuid = _otp_convert_uuid_to_uuid128(OTP_CP_CCC_DESC_UUID);
- perms = BLUETOOTH_GATT_PERMISSION_READ |
- BLUETOOTH_GATT_PERMISSION_WRITE;
- ret = bluetooth_gatt_add_descriptor(otp_olcp_obj_path, desc_uuid,
- perms, &otp_olcp_desc_obj_path);
- if (ret != BLUETOOTH_ERROR_NONE) {
- BT_ERR("Failed to add new char descriptor %d", ret);
- goto fail;
+ /* CCCD for OLCP */
+ desc_uuid = _otp_convert_uuid_to_uuid128(OTP_CP_CCC_DESC_UUID);
+ perms = BLUETOOTH_GATT_PERMISSION_READ |
+ BLUETOOTH_GATT_PERMISSION_WRITE;
+ ret = bluetooth_gatt_add_descriptor(otp_olcp_obj_path, desc_uuid,
+ perms, &otp_olcp_desc_obj_path);
+ if (ret != BLUETOOTH_ERROR_NONE) {
+ BT_ERR("Failed to add new char descriptor %d", ret);
+ goto fail;
+ }
}
/* Register service */
list = g_slist_append(list, (gpointer) filename);
}
+ g_dir_close(dir);
+
if (!list) {
BT_DBG("No object found in given directory");
status = BLUETOOTH_ERROR_NO_OBJECTS_FOUND;
goto fail;
}
+ if (g_slist_length(list) > 1)
+ mutiple_obj_support = true;
+
for (l = list; l != NULL; l = l->next) {
if (!l->data) continue;
snprintf(absolute_path, sizeof(absolute_path), "%s%s", directory,
object_id++;
}
- g_dir_close(dir);
-
BT_DBG("preparing");
if (_bt_otp_prepare_ots() != BLUETOOTH_ERROR_NONE) {
BT_ERR("Fail to prepare OTP Proxy");
goto fail;
}
+ /* If single object is supported, make that as
+ * selected object and update the metadata for the same.
+ */
+ if (!mutiple_obj_support) {
+ BT_INFO("Server supports single object");
+ selected_object = (struct object_metadata *) g_slist_nth_data(otp_object_list, 0);
+ update_obj_metadata_charc_value(selected_object);
+ }
+
BT_DBG("advertsing");
if (_bt_otp_set_advertising_data() != BLUETOOTH_ERROR_NONE) {
BT_ERR("Fail to set advertising data");
_bt_otp_set_char_value(otp_object_first_created_obj_path, value, 7);
_bt_otp_set_char_value(otp_object_last_modified_obj_path, value, 7);
- convert_to_hex(object, "id", value);
- _bt_otp_set_char_value(otp_object_id_obj_path, value, 6);
+ /* Object ID is optonal for single object server */
+ if (mutiple_obj_support) {
+ convert_to_hex(object, "id", value);
+ _bt_otp_set_char_value(otp_object_id_obj_path, value, 6);
+ }
convert_to_hex(object, "props", value);
_bt_otp_set_char_value(otp_object_prop_obj_path, value, 4);
g_free(handle);
break;
}
+ case BT_OTP_WRITE_VALUE: {
+ char *handle;
+ char *data = NULL;
+ guint data_len = 0;
+ char *sender = NULL;
+ bluetooth_otp_charc_data_t otp_charc_data;
+ sender = (char *)g_dbus_method_invocation_get_sender(context);
+
+ data_len = g_variant_get_size(in_param1);
+ data = (char *)g_variant_get_data(in_param1);
+
+ handle = g_strndup(data, data_len);
+ BT_DBG("OTP Write Characteristic value [%s]", handle);
+
+ __bt_service_get_parameters(in_param2,
+ &otp_charc_data, sizeof(bluetooth_otp_charc_data_t));
+
+ int i;
+ for (i = 0; i < otp_charc_data.length; i++)
+ BT_DBG("Value[%d] = %u", i, otp_charc_data.data[i]);
+
+ result = _bt_otp_write_characteristic_value(request_id, sender, handle,
+ otp_charc_data.data, otp_charc_data.length);
+
+ if (result != BLUETOOTH_ERROR_NONE) {
+ BT_ERR("OTP Write Characteristic failed result [%d]", result);
+ g_array_append_vals(*out_param1, handle, data_len);
+ }
+ if (handle)
+ g_free(handle);
+ break;
+ }
default:
result = BLUETOOTH_ERROR_INTERNAL;
break;
case BT_OTP_SERVER_DEINIT:
case BT_OTP_READ_VALUE:
case BT_OTP_ENABLE_NOTIFICATION:
+ case BT_OTP_WRITE_VALUE:
case BT_MAP_CREATE_SESSION:
case BT_MAP_DESTROY_SESSION:
#include "bt-service-opp-client.h"
#include "bt-service-map-client.h"
#include "bt-service-tds.h"
+#include "bt-service-otp.h"
#ifdef TIZEN_FEATURE_BT_DPM
#include "bt-service-dpm.h"
if (strcasecmp(member, "GattValueChanged") == 0) {
/* Check TDS seekers waiting for Indication */
_bt_tds_check_indication(path, msg);
+#ifdef TIZEN_FEATURE_BT_OTP
+ _bt_otp_check_indication(path, msg);
+#endif
} else {
BT_INFO("Unhandled event");
}
case BLUETOOTH_EVENT_OTP_NOTIFICATION_ENABLED:
signal = BT_OTP_NOTIFICATION_ENABLED;
break;
+ case BLUETOOTH_EVENT_OTP_WRITE_CHAR_VAL:
+ signal = BT_OTP_WRITE_CHAR_VAL;
+ break;
+ case BLUETOOTH_EVENT_OTP_INDICATION:
+ signal = BT_OTP_INDICATION;
+ break;
default:
BT_ERR("Unknown event");
return BLUETOOTH_ERROR_INTERNAL;
#define GATT_CHAR_INTERFACE "org.bluez.GattCharacteristic1"
#define GATT_DEFAULT_TIMEOUT (6 * 1000) /* Dependent on supervision timeout 6 sec */
+#define BT_INDICATION_TIMEOUT_MAX 15000 /* Timeout for Indication from OTP Server in msec */
/* OTP Notification Request structure */
typedef struct {
char *handle;
char *sender;
+ unsigned int notification_timeout_id;
int req_id;
} bt_otp_notification_info;
{
GDBusConnection *conn;
bt_otp_read_req_info *info = NULL;
- GVariantBuilder *builder = NULL;
char *charc_handle = g_strdup(handle);
+ GVariantBuilder *builder = NULL;
guint16 offset = 0;
BT_CHECK_PARAMETER(handle, return);
g_free(info->handle);
if (info->sender)
g_free(info->sender);
+ if (info->notification_timeout_id > 0) {
+ g_source_remove(info->notification_timeout_id);
+ info->notification_timeout_id = 0;
+ }
g_free(info);
}
if (info)
req_info = _bt_get_request_info(info->req_id);
- /* CCCD Enable request failed */
+ /* If CCCD Enable request failed for any reason, reset timer */
if (result != BLUETOOTH_ERROR_NONE && info != NULL) {
BT_ERR("Activation Request failed");
+ /* Reset Timer */
+ if (info->notification_timeout_id > 0) {
+ g_source_remove(info->notification_timeout_id);
+ info->notification_timeout_id = 0;
+ }
+
/* Remove Indication Info */
__bt_otp_remove_notification_info(info);
} else {
BT_DBG("-");
return BLUETOOTH_ERROR_NONE;
}
+
+static void __bt_otp_write_request_cb(GObject *source_object,
+ GAsyncResult *res, gpointer user_data)
+{
+ GError *error = NULL;
+ GDBusConnection *system_gconn = NULL;
+ GVariant *value = NULL;
+ GVariant *param = NULL;
+ GVariant *out_param1 = NULL;
+ int result = BLUETOOTH_ERROR_NONE;
+ char *handle = NULL;
+ bt_otp_notification_info *info = NULL;
+ request_info_t *req_info = NULL;
+ BT_DBG("+");
+
+ system_gconn = _bt_gdbus_get_system_gconn();
+ value = g_dbus_connection_call_finish(system_gconn, res, &error);
+
+ if (error) {
+ BT_ERR("Error : %s \n", error->message);
+ /* Process error->message to narrow down the att_ecode */
+ result = BLUETOOTH_ERROR_INTERNAL;
+ }
+
+ handle = (char *)user_data;
+ info = __bt_otp_get_notification_info(handle);
+ if (info)
+ req_info = _bt_get_request_info(info->req_id);
+
+ /* Is Activation request failed for any reason, reset timer */
+ if (result != BLUETOOTH_ERROR_NONE && info != NULL) {
+ BT_ERR("Activation Request failed");
+ /* Remove Indication Info */
+ __bt_otp_remove_notification_info(info);
+ } else {
+ /* Activation Request successful */
+ if (info) {
+ param = g_variant_new("(is)", result, handle);
+ _bt_send_event_to_dest(info->sender, BT_OTP_EVENT,
+ BLUETOOTH_EVENT_OTP_WRITE_CHAR_VAL,
+ param);
+ }
+ }
+
+ if (req_info == NULL) {
+ BT_ERR("OTP Write Request is not found!!");
+ goto done;
+ }
+
+ if (req_info->context == NULL)
+ goto done;
+
+ out_param1 = g_variant_new_from_data((const GVariantType*)"ay",
+ handle, __get_handle_length(handle), TRUE, NULL, NULL);
+ g_dbus_method_invocation_return_value(req_info->context,
+ g_variant_new("(iv)", result, out_param1));
+
+ _bt_delete_request_list(req_info->req_id);
+
+done:
+ if (value)
+ g_variant_unref(value);
+ if (error)
+ g_clear_error(&error);
+ if (handle)
+ g_free(handle);
+
+ BT_DBG("-");
+ return;
+}
+
+static void __bt_otp_send_indication_event(bt_otp_notification_info *info,
+ unsigned char *buffer, int len, int result)
+{
+ GVariant *otp_data;
+ GVariant *param;
+
+ otp_data = g_variant_new_from_data((const GVariantType*)"ay",
+ buffer, len, TRUE, NULL, NULL);
+
+ BT_DBG("Send Indication event to sender");
+ param = g_variant_new("(is@ay)", result, info->handle, otp_data);
+ _bt_send_event_to_dest(info->sender, BT_OTP_EVENT,
+ BLUETOOTH_EVENT_OTP_INDICATION,
+ param);
+
+ /* Remove info from list */
+ __bt_otp_remove_notification_info(info);
+}
+
+static bool __bt_otp_indication_timeout_cb(gpointer user_data)
+{
+ char *handle = NULL;
+ handle = (char *) user_data;
+ bt_otp_notification_info *info = NULL;
+ /* Indication:Fail*/
+ info = __bt_otp_get_notification_info(handle);
+ BT_DBG("Activation timer Expired [Server] [%s]", info->handle);
+ if (info)
+ __bt_otp_send_indication_event(info, NULL, 0, BLUETOOTH_ERROR_INTERNAL);
+
+ return FALSE;
+}
+
+int _bt_otp_write_characteristic_value(int request_id, char *sender, char *handle,
+ unsigned char *param, int length)
+{
+ GVariantBuilder *builder1;
+ GVariant *val;
+ GVariant *options;
+ GVariantBuilder *builder2;
+ guint16 offset = 0;
+ bt_otp_notification_info *info = NULL;
+ GDBusConnection *conn;
+ char *charc_handle = g_strdup(handle);
+ int i;
+
+ BT_DBG("+");
+
+ BT_CHECK_PARAMETER(handle, return);
+ BT_CHECK_PARAMETER(sender, return);
+ BT_CHECK_PARAMETER(param, return);
+
+ conn = _bt_gdbus_get_system_gconn();
+ retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+ BT_DBG("OTP Write Characteristic value handle [%s] data length [%d]", handle, length);
+ /* Check if activation is ongoing for the same Remote Server */
+
+ info = __bt_otp_get_notification_info(handle);
+ if (info && info->notification_timeout_id > 0) {
+ BT_ERR("Write Request is already ongoing in remote server");
+ g_free(charc_handle);
+ return BLUETOOTH_ERROR_IN_PROGRESS;
+ }
+
+ builder1 = g_variant_builder_new(G_VARIANT_TYPE("ay"));
+
+ for (i = 0; i < length; i++) {
+ g_variant_builder_add(builder1, "y", param[i]);
+ }
+
+ val = g_variant_new("(ay)", builder1);
+ builder2 = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
+ /*offset*/
+ g_variant_builder_add(builder2, "{sv}", "offset",
+ g_variant_new_uint16(offset));
+
+ options = g_variant_new("a{sv}", builder2);
+
+ /* Activate Control Point */
+ g_dbus_connection_call(conn,
+ BT_BLUEZ_NAME,
+ handle,
+ GATT_CHAR_INTERFACE,
+ "WriteValue",
+ g_variant_new("(@ay@a{sv})",
+ val, options),
+ NULL,
+ G_DBUS_CALL_FLAGS_NONE,
+ -1, NULL,
+ (GAsyncReadyCallback)__bt_otp_write_request_cb,
+ (gpointer)charc_handle);
+
+ g_variant_builder_unref(builder1);
+ g_variant_builder_unref(builder2);
+
+ if (info == NULL) {
+ info = g_malloc0(sizeof(bt_otp_notification_info));
+ info->handle = g_strdup(handle);
+ info->sender = g_strdup(sender);
+ otp_notification_info_list = g_slist_append(otp_notification_info_list, info);
+ }
+ info->req_id = request_id;
+ info->notification_timeout_id = g_timeout_add(BT_INDICATION_TIMEOUT_MAX,
+ (GSourceFunc)__bt_otp_indication_timeout_cb, (gpointer)info->handle);
+
+ BT_DBG("-");
+ return BLUETOOTH_ERROR_NONE;
+}
+
+void _bt_otp_check_indication(const char *path, GVariant *msg)
+{
+ bt_otp_notification_info *info = NULL;
+ unsigned char *buffer = NULL;
+ int len = 0;
+ int i;
+ GVariant *value = NULL;
+ BT_DBG("+");
+
+ info = __bt_otp_get_notification_info((char *)path);
+
+ if (info) {
+ g_variant_get(msg, "(is@ay)", NULL, NULL, &value);
+ len = g_variant_get_size(value);
+ BT_DBG("Indication data from Server len[%d]", len);
+ if (len > 0) {
+ buffer = (unsigned char *)g_variant_get_data(value);
+ /* DEBUG */
+ for (i = 0; i < len; i++)
+ BT_DBG("%.2x", buffer[i]);
+ }
+
+ /* Reset Timer */
+ if (info->notification_timeout_id > 0)
+ g_source_remove(info->notification_timeout_id);
+
+ /* Send Indication & info removed internally */
+ __bt_otp_send_indication_event(info, buffer, len, BLUETOOTH_ERROR_NONE);
+
+ if (value)
+ g_variant_unref(value);
+ }
+ BT_DBG("-");
+}
int _bt_otp_enable_notification(int request_id, char *sender, char *handle);
+int _bt_otp_write_characteristic_value(int request_id, char *sender, char *handle,
+ unsigned char *param, int length);
+
+void _bt_otp_check_indication(const char *path, GVariant *msg);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
*/
#define BLUETOOTH_MAX_OTP_SERVER_DIR_NAME 100
+#define BLUETOOTH_OTP_CHARC_VAL_MAX_LENGTH 500 /**< OTP Characteristics Value Max length */
+
/**
* This is Bluetooth error code
*/
} bluetooth_tds_transport_data_info_t;
/**
+* OTP Characteristics Value
+*/
+typedef struct {
+ int length; /**< Characteristics value length */
+ guint8 data[BLUETOOTH_OTP_CHARC_VAL_MAX_LENGTH]; /**< Characteristics data */
+} bluetooth_otp_charc_data_t;
+
+/**
* Structure to hold the OTP response data from remote OTP server
*/
typedef struct {
BLUETOOTH_EVENT_OTP_SERVER_STATE_CHANGED, /* OTP Server Status **/
BLUETOOTH_EVENT_OTP_READ_CHAR_VAL, /* OTP Read Value Response */
BLUETOOTH_EVENT_OTP_NOTIFICATION_ENABLED, /* OTP Notification Enabled Response */
+ BLUETOOTH_EVENT_OTP_WRITE_CHAR_VAL, /* OTP Write Value Response */
+ BLUETOOTH_EVENT_OTP_INDICATION, /* OTP Indication */
} bluetooth_event_type_t;
/**
*/
int bluetooth_otp_server_deinit();
+/**
+ * @fn int bluetooth_otp_enable_notification(const char *handle);
+ *
+ * @brief Enable notification for remote OACP & OLCP characteristics.
+ *
+ * This function is a synchronous call.
+ *
+ * @return
+ *
+ * @exception None
+ * @param[in] None
+ * @param[out] None
+ *
+ * @remark None
+ */
int bluetooth_otp_enable_notification(const char *handle);
+/**
+ * @fn int bluetooth_otp_write_characteristics_value( const char *handle,
+ * unsigned char *buf, int length);
+ *
+ * @brief Write value on remote characteristics.
+ *
+ * This function is a synchronous call.
+ *
+ * @return
+ *
+ * @exception None
+ * @param[in] None
+ * @param[out] None
+ *
+ * @remark None
+ */
+int bluetooth_otp_write_characteristics_value( const char *handle,
+ unsigned char *buf, int length);
+
+/**
+ * @fn int bluetooth_otp_read_characteristic_value(const char *handle);
+ *
+ * @brief Read value for remote characteristics.
+ *
+ * This function is a synchronous call.
+ *
+ * @return
+ *
+ * @exception None
+ * @param[in] None
+ * @param[out] None
+ *
+ * @remark None
+ */
int bluetooth_otp_read_characteristic_value(const char *handle);
/**
BT_OTP_SERVER_DEINIT,
BT_OTP_READ_VALUE,
BT_OTP_ENABLE_NOTIFICATION,
+ BT_OTP_WRITE_VALUE,
} bt_function_t;
typedef struct {
#define BT_OTP_SERVER_STATE_CHANGED "OtpServerStateChanged"
#define BT_OTP_READ_CHAR_VAL "OtpReadCharVal"
#define BT_OTP_NOTIFICATION_ENABLED "OtpNotificationEnabled"
+#define BT_OTP_WRITE_CHAR_VAL "OtpWriteCharVal"
+#define BT_OTP_INDICATION "OtpIndication"
typedef enum {
_PROFILE_UNKNOWN = 0,