Added code to handle Le data length extension feature and commands.
Change-Id: Ib5bf2ea7b80bef45078b037218ed30191e364dff
Signed-off-by: Sudha Bheemanna <b.sudha@samsung.com>
return BLUETOOTH_ERROR_NONE;
}
+
+BT_EXPORT_API int bluetooth_le_read_maximum_data_length(
+ bluetooth_le_read_maximum_data_length_t *max_le_datalength)
+{
+ BT_CHECK_ENABLED_ANY(return);
+ BT_INIT_PARAMS();
+ int result;
+ bluetooth_le_read_maximum_data_length_t *datalength = NULL;
+
+ BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+
+ result = _bt_send_request(BT_BLUEZ_SERVICE,
+ BT_LE_READ_MAXIMUM_DATA_LENGTH,
+ in_param1, in_param2, in_param3, in_param4, &out_param);
+
+ if (result == BLUETOOTH_ERROR_NONE) {
+ datalength = &g_array_index(out_param,
+ bluetooth_le_read_maximum_data_length_t, 0);
+ max_le_datalength->max_tx_octets = datalength->max_tx_octets;
+ max_le_datalength->max_tx_time = datalength->max_tx_time;
+ max_le_datalength->max_rx_octets = datalength->max_rx_octets;
+ max_le_datalength->max_rx_time = datalength->max_rx_time;
+ }
+
+ BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+
+ return result;
+}
+
+BT_EXPORT_API int bluetooth_le_write_host_suggested_default_data_length(
+ const unsigned int def_tx_Octets, const unsigned int def_tx_Time)
+{
+ BT_CHECK_ENABLED_ANY(return);
+ BT_INIT_PARAMS();
+
+ int result;
+
+ BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+
+ g_array_append_vals(in_param1, &def_tx_Octets, sizeof(guint));
+ g_array_append_vals(in_param2, &def_tx_Time, sizeof(guint));
+
+ result = _bt_send_request(BT_BLUEZ_SERVICE,
+ BT_LE_WRITE_HOST_SUGGESTED_DATA_LENGTH,
+ in_param1, in_param2, in_param3, in_param4, &out_param);
+
+ if (result != BLUETOOTH_ERROR_NONE) {
+ BT_ERR("Failed to Write the host suggested default data length values : %d", result);
+ }
+
+ BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+
+ return result;
+}
+
+BT_EXPORT_API int bluetooth_le_read_suggested_default_data_length(
+ bluetooth_le_read_host_suggested_data_length_t *le_data_length)
+{
+ BT_CHECK_ENABLED_ANY(return);
+ BT_INIT_PARAMS();
+
+ int result;
+ bluetooth_le_read_host_suggested_data_length_t *data_values = NULL;
+ BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+
+ result = _bt_send_request(BT_BLUEZ_SERVICE,
+ BT_LE_READ_HOST_SUGGESTED_DATA_LENGTH,
+ in_param1, in_param2, in_param3, in_param4, &out_param);
+
+ if (result == BLUETOOTH_ERROR_NONE) {
+ data_values = &g_array_index(out_param,
+ bluetooth_le_read_host_suggested_data_length_t, 0);
+
+ le_data_length->def_tx_octets = data_values->def_tx_octets;
+ le_data_length->def_tx_time = data_values->def_tx_time;
+ }
+
+ BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+
+ return result;
+}
+
+BT_EXPORT_API int bluetooth_le_set_data_length(bluetooth_device_address_t *address,
+ const unsigned int max_tx_octets, const unsigned int max_tx_time)
+{
+ BT_CHECK_ENABLED_ANY(return);
+ BT_INIT_PARAMS();
+
+ int result;
+
+ BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+
+ g_array_append_vals(in_param1, address, sizeof(bluetooth_device_address_t));
+ g_array_append_vals(in_param2, &max_tx_octets, sizeof(guint));
+ g_array_append_vals(in_param3, &max_tx_time, sizeof(guint));
+
+ result = _bt_send_request(BT_BLUEZ_SERVICE,
+ BT_LE_SET_DATA_LENGTH,
+ in_param1, in_param2, in_param3, in_param4, &out_param);
+
+ if (result != BLUETOOTH_ERROR_NONE) {
+ BT_ERR("Failed to Set data length values : %d", result);
+ }
+
+ BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+
+ return result;
+}
_bt_common_event_cb(BLUETOOTH_EVENT_DEVICE_UNAUTHORIZED,
result, &dev_address,
event_info->cb, event_info->user_data);
+ } else if (strcasecmp(signal_name, BT_LE_DATA_LENGTH_CHANGED) == 0) {
+ const char *address = NULL;
+ bluetooth_device_address_t dev_address = { {0} };
+ uint tx_octets = 0;
+ uint tx_time = 0;
+ uint rx_octets = 0;
+ uint rx_time = 0;
+ bt_le_data_length_params_t params;
+
+ BT_DBG("BT_LE_DATA_LENGTH_CHANGED");
+
+ g_variant_get(parameters, "(i&sqqqq)", &result, &address,
+ tx_octets, tx_time, rx_octets, rx_time);
+
+ params.max_tx_octets = tx_octets;
+ params.max_tx_time = tx_time;
+ params.max_rx_octets = rx_octets;
+ params.max_rx_time = rx_time;
+
+ _bt_convert_addr_string_to_type(dev_address.addr, address);
+
+ memcpy(¶ms.device_address,
+ &dev_address, BLUETOOTH_ADDRESS_LENGTH);
+
+ _bt_common_event_cb(BLUETOOTH_EVENT_LE_DATA_LENGTH_CHANGED,
+ result, ¶ms, event_info->cb, event_info->user_data);
}
}
((bt_audio_func_ptr)cb_data->cb)(bt_event.event,
(bt_audio_event_param_t *)&bt_event,
cb_data->user_data);
+ } else if (event_type == BT_DEVICE_EVENT) {
+ ((bluetooth_cb_func_ptr)cb_data->cb)(bt_event.event,
+ &bt_event,
+ cb_data->user_data);
} else {
BT_INFO("Not handled event type : %d", event_type);
}
case BT_GATT_DISCOVER_CHARACTERISTICS_DESCRIPTOR:
/* Just call to check the privilege */
break;
+ case BT_LE_READ_MAXIMUM_DATA_LENGTH: {
+ bluetooth_le_read_maximum_data_length_t max_le_datalength = {0};
+
+ result = _bt_le_read_maximum_data_length(&max_le_datalength);
+
+ g_array_append_vals(*out_param1, &max_le_datalength,
+ sizeof(bluetooth_le_read_maximum_data_length_t));
+ break;
+ }
+ case BT_LE_WRITE_HOST_SUGGESTED_DATA_LENGTH: {
+ unsigned int def_tx_Octects = 0;
+ unsigned int def_tx_Time = 0;
+
+ __bt_service_get_parameters(in_param1,
+ &def_tx_Octects, sizeof(int));
+ __bt_service_get_parameters(in_param2,
+ &def_tx_Time, sizeof(int));
+
+ result = _bt_le_write_host_suggested_default_data_length(
+ def_tx_Octects, def_tx_Time);
+ break;
+ }
+ case BT_LE_READ_HOST_SUGGESTED_DATA_LENGTH: {
+ bluetooth_le_read_host_suggested_data_length_t def_data_length = {0};
+
+ result = _bt_le_read_host_suggested_default_data_length(&def_data_length);
+
+ g_array_append_vals(*out_param1, &def_data_length,
+ sizeof(bluetooth_le_read_host_suggested_data_length_t));
+
+ break;
+ }
+ case BT_LE_SET_DATA_LENGTH: {
+ int max_tx_Octets = 0;
+ int max_tx_Time = 0;
+ bluetooth_device_address_t address = { {0} };
+
+ __bt_service_get_parameters(in_param1, &address,
+ sizeof(bluetooth_device_address_t));
+ __bt_service_get_parameters(in_param2,
+ &max_tx_Octets, sizeof(int));
+ __bt_service_get_parameters(in_param3,
+ &max_tx_Time, sizeof(int));
+
+ result = _bt_le_set_data_length(&address, max_tx_Octets, max_tx_Time);
+ break;
+ }
default:
result = BLUETOOTH_ERROR_INTERNAL;
break;
case BT_BOND_DEVICE_BY_TYPE:
case BT_SET_LE_PRIVACY:
case BT_LE_CONN_UPDATE:
+ case BT_LE_READ_MAXIMUM_DATA_LENGTH:
+ case BT_LE_WRITE_HOST_SUGGESTED_DATA_LENGTH:
+ case BT_LE_READ_HOST_SUGGESTED_DATA_LENGTH:
+ case BT_LE_SET_DATA_LENGTH:
ret_val = cynara_check(p_cynara, client_creds, client_session, user_creds,
BT_PRIVILEGE_PLATFORM);
return BLUETOOTH_ERROR_NONE;
}
+int _bt_le_read_maximum_data_length(
+ bluetooth_le_read_maximum_data_length_t *max_le_datalength)
+{
+ GError *error = NULL;
+ GDBusProxy *proxy;
+ GVariant *reply = NULL;
+ guint16 max_tx_octets, max_tx_time;
+ guint16 max_rx_octets, max_rx_time;
+ int err;
+
+ proxy = _bt_get_adapter_proxy();
+ retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+ reply = g_dbus_proxy_call_sync(proxy, "LEReadMaximumDataLength",
+ NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
+
+ g_object_unref(proxy);
+
+ if (reply == NULL) {
+ BT_ERR("LEReadMaximumDataLength dBUS-RPC failed");
+ if (error != NULL) {
+ BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
+ error->code, error->message);
+ g_clear_error(&error);
+ }
+ return BLUETOOTH_ERROR_INTERNAL;
+ }
+
+ g_variant_get(reply ,"(qqqqi)", &max_tx_octets, &max_tx_time,
+ &max_rx_octets, &max_rx_time, &err);
+
+ g_variant_unref(reply);
+
+ if (err) {
+ BT_DBG("error is : %d", err);
+ return BLUETOOTH_ERROR_INTERNAL;
+ }
+
+ max_le_datalength->max_tx_octets = max_tx_octets;
+ max_le_datalength->max_tx_time = max_tx_time;
+ max_le_datalength->max_rx_octets = max_rx_octets;
+ max_le_datalength->max_rx_time = max_rx_time;
+
+ return BLUETOOTH_ERROR_NONE;
+}
+int _bt_le_write_host_suggested_default_data_length(
+ const unsigned int def_tx_Octets, const unsigned int def_tx_Time)
+{
+ GError *error = NULL;
+ GDBusProxy *proxy;
+ GVariant *reply = NULL;
+
+ proxy = _bt_get_adapter_proxy();
+ retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+ reply = g_dbus_proxy_call_sync(proxy,
+ "LEWriteHostSuggestedDataLength",
+ g_variant_new("(qq)", def_tx_Octets, def_tx_Time),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ &error);
+
+ g_object_unref(proxy);
+
+ if (reply == NULL) {
+ BT_ERR("_bt_le_write_host_suggested_default_data_length dBUS-RPC failed");
+ if (error != NULL) {
+ BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
+ error->code, error->message);
+ g_clear_error(&error);
+ }
+ return BLUETOOTH_ERROR_INTERNAL;
+ }
+
+ g_variant_unref(reply);
+
+ return BLUETOOTH_ERROR_NONE;
+}
+
+int _bt_le_read_host_suggested_default_data_length(
+ bluetooth_le_read_host_suggested_data_length_t *def_data_length)
+{
+ GError *error = NULL;
+ GDBusProxy *proxy;
+ GVariant *reply = NULL;
+ guint16 def_tx_octets, def_tx_time;
+ int err;
+
+ proxy = _bt_get_adapter_proxy();
+ retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+ reply = g_dbus_proxy_call_sync(proxy, "LEReadHostSuggestedDataLength",
+ NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
+
+ if (reply == NULL) {
+ BT_ERR("LEReadHostSuggestedDataLength dBUS-RPC failed");
+ if (error != NULL) {
+ BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
+ error->code, error->message);
+ g_clear_error(&error);
+ }
+ return BLUETOOTH_ERROR_INTERNAL;
+ }
+
+ g_variant_get(reply ,"(qqi)", &def_tx_octets, &def_tx_time, &err);
+
+ g_variant_unref(reply);
+
+ if (err) {
+ BT_DBG("error is : %d", err);
+ return BLUETOOTH_ERROR_INTERNAL;
+ }
+
+ def_data_length->def_tx_octets = def_tx_octets;
+ def_data_length->def_tx_time = def_tx_time;
+
+ return BLUETOOTH_ERROR_NONE;
+}
+
+int _bt_le_set_data_length(bluetooth_device_address_t *device_address,
+ const unsigned int max_tx_Octets, const unsigned int max_tx_Time)
+{
+ GError *error = NULL;
+ guint16 txOctets = max_tx_Octets;
+ guint16 txTime = max_tx_Time;
+ char address[BT_ADDRESS_STRING_SIZE] = { 0 };
+ gchar *device_path = NULL;
+ GDBusConnection *conn;
+ GDBusProxy *device_proxy;
+
+ _bt_convert_addr_type_to_string(address, device_address->addr);
+
+ device_path = _bt_get_device_object_path(address);
+
+ BT_DBG("devic path is %s", device_path);
+
+ if (device_path == NULL) {
+ BT_DBG("Device path is null");
+ return BLUETOOTH_ERROR_INTERNAL;
+ }
+
+ conn = _bt_get_system_gconn();
+ if (conn == NULL) {
+ BT_ERR("conn == NULL");
+ g_free(device_path);
+ return BLUETOOTH_ERROR_INTERNAL;
+ }
+
+ device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
+ NULL, BT_BLUEZ_NAME,
+ device_path, BT_DEVICE_INTERFACE, NULL, NULL);
+
+ g_free(device_path);
+ retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+ g_dbus_proxy_call_sync(device_proxy,
+ "LESetDataLength",
+ g_variant_new("(qq)", txOctets, txTime),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ &error);
+
+ g_object_unref(device_proxy);
+
+ if (error) {
+ BT_ERR("LESetDataLength error: [%s]", error->message);
+ g_error_free(error);
+ return BLUETOOTH_ERROR_INTERNAL;
+ }
+
+ return BLUETOOTH_ERROR_NONE;
+}
\ No newline at end of file
_bt_disable_adapter();
}
#endif
-
if (vconf_get_int(VCONFKEY_BT_LE_STATUS, &bt_state) == 0 &&
bt_state != VCONFKEY_BT_LE_STATUS_OFF) {
_bt_set_le_disabled(BLUETOOTH_ERROR_NONE);
}
_bt_free_le_device_info(le_dev_info);
g_variant_unref(value);
+ } else if (strcasecmp(member, "LEDataLengthChanged") == 0) {
+ int tx_octets = 0;
+ int tx_time = 0;
+ int rx_octets = 0;
+ int rx_time = 0;
+
+ g_variant_get(msg, "(qqqq)",
+ tx_octets, tx_time, rx_octets, rx_time);
+
+ address = g_malloc0(BT_ADDRESS_STRING_SIZE);
+ _bt_convert_device_path_to_address(path, address);
+
+ param = g_variant_new("(isqqqq)", result, address, tx_octets, tx_time,
+ rx_octets, rx_time);
+ /* Send event to application */
+ _bt_send_event(BT_DEVICE_EVENT,
+ event, param);
+ g_free(address);
}
}
case BLUETOOTH_EVENT_GATT_CHAR_VAL_CHANGED:
signal = BT_GATT_CHAR_VAL_CHANGED;
break;
+ case BLUETOOTH_EVENT_LE_DATA_LENGTH_CHANGED:
+ signal = BT_LE_DATA_LENGTH_CHANGED;
+ break;
default:
BT_ERR("Unknown event");
return BLUETOOTH_ERROR_INTERNAL;
int _bt_clear_white_list(void);
+int _bt_le_read_maximum_data_length(bluetooth_le_read_maximum_data_length_t *max_le_datalength);
+
+int _bt_le_write_host_suggested_default_data_length(const unsigned int def_tx_Octets, const unsigned int def_tx_Time);
+
+int _bt_le_read_host_suggested_default_data_length(bluetooth_le_read_host_suggested_data_length_t *def_data_length);
+
+int _bt_le_set_data_length(bluetooth_device_address_t *device_address, const unsigned int max_tx_Octets, const unsigned int max_tx_Time);
#ifdef __cplusplus
}
#endif /* __cplusplus */
guint16 latency;
guint16 time_out;
} bluetooth_le_conn_update_t;
+/*
+ LE Read Maximum Data Length
+ */
+typedef struct {
+ guint16 max_tx_octets;
+ guint16 max_tx_time;
+ guint16 max_rx_octets;
+ guint16 max_rx_time;
+} bluetooth_le_read_maximum_data_length_t;
+
+/*
+ LE Read Host suggested default Data Length
+ */
+typedef struct {
+ guint16 def_tx_octets;
+ guint16 def_tx_time;
+} bluetooth_le_read_host_suggested_data_length_t;
/**
* Samsung XSAT Vendor dependent command
BLUETOOTH_EVENT_AVRCP_SONG_POSITION_STATUS, /**<AVRCP control play Postion status event*/
BLUETOOTH_EVENT_AVRCP_PLAY_STATUS_CHANGED, /**<AVRCP control play status event*/
BLUETOOTH_EVENT_AVRCP_TRACK_CHANGED, /**<AVRCP control song metadata event*/
+ BLUETOOTH_EVENT_LE_DATA_LENGTH_CHANGED, /** LE data length values changed */
} bluetooth_event_type_t;
/**
} bt_hf_call_list_s;
/**
+ * Structure for LE data length change params
+ */
+
+typedef struct {
+ bluetooth_device_address_t device_address;
+ guint16 max_tx_octets;
+ guint16 max_tx_time;
+ guint16 max_rx_octets;
+ guint16 max_rx_time;
+} bt_le_data_length_params_t;
+
+/**
* Callback pointer type
*/
typedef void (*bluetooth_cb_func_ptr) (int, bluetooth_event_param_t *, void *);
* @remark None
*/
int bluetooth_enable_le_privacy(gboolean enable_privacy);
+/**
+ * @fn int bluetooth_le_read_maximum_data_length()
+ * @brief reads the maximum LE data length supported in the controller.
+ *
+ * This function is a synchronous call.
+ *
+ * @return BLUETOOTH_ERROR_NONE - Success \n
+ * BLUETOOTH_ERROR_INTERNAL - Internal Error \n
+ *
+ * @exception None
+ *
+ * @remark None
+ */
+int bluetooth_le_read_maximum_data_length(
+ bluetooth_le_read_maximum_data_length_t *max_le_datalength);
+/**
+ * @fn int bluetooth_le_write_host_suggested_default_data_length()
+ * @brief writes the host suggested values for the controllers max transmitted no of payload
+ * octects to be used for new connections.
+ *
+ * This function is a synchronous call.
+ *
+ * @return BLUETOOTH_ERROR_NONE - Success \n
+ * BLUETOOTH_ERROR_INTERNAL - Internal Error \n
+ *
+ * @exception None
+ *
+ * @remark None
+ */
+int bluetooth_le_write_host_suggested_default_data_length(
+ const unsigned int def_tx_Octets, const unsigned int def_tx_Time);
+
+int bluetooth_le_read_suggested_default_data_length(
+ bluetooth_le_read_host_suggested_data_length_t *le_data_length);
+
+int bluetooth_le_set_data_length(bluetooth_device_address_t *address,
+ const unsigned int max_tx_octets, const unsigned int max_tx_time);
int bluetooth_pbap_init(void);
int bluetooth_pbap_deinit(void);
BT_IS_ADVERTISING,
BT_SET_MANUFACTURER_DATA,
BT_LE_CONN_UPDATE,
+ BT_LE_READ_MAXIMUM_DATA_LENGTH,
+ BT_LE_WRITE_HOST_SUGGESTED_DATA_LENGTH,
+ BT_LE_READ_HOST_SUGGESTED_DATA_LENGTH,
+ BT_LE_SET_DATA_LENGTH,
BT_ADD_WHITE_LIST,
BT_REMOVE_WHITE_LIST,
BT_CLEAR_WHITE_LIST,
#define BT_HF_LOCAL_TERM "HandsfreeLocalTermination"
#define BT_HID_DEVICE_CONNECTED "HIDConnected"
#define BT_HID_DEVICE_DISCONNECTED "HIDDisconnected"
+#define BT_LE_DATA_LENGTH_CHANGED "LEDataLengthChanged"
#ifdef __cplusplus
}