#include #include #include #include #include #include "a2dp_source/a2dp_masterctrl.h" #include "a2dp_source/gatt.h" #include "utility.h" #include "slog.h" #include "gatt_client.h" extern struct adapter *default_ctrl; extern GDBusProxy *ble_dev; extern GDBusProxy *default_attr; typedef struct { RK_BLE_CLIENT_STATE_CALLBACK state_cb; RK_BLE_CLIENT_RECV_CALLBACK recv_cb; RK_BLE_CLIENT_STATE state; } gatt_client_control_t; static gatt_client_control_t g_gatt_client_ctl = { NULL, NULL, RK_BLE_CLIENT_STATE_IDLE, }; void gatt_client_register_state_callback(RK_BLE_CLIENT_STATE_CALLBACK cb) { g_gatt_client_ctl.state_cb = cb; } void gatt_client_register_recv_callback(RK_BLE_CLIENT_RECV_CALLBACK cb) { g_gatt_client_ctl.recv_cb = cb; } void gatt_client_state_send(RK_BLE_CLIENT_STATE state) { char addr[18], name[256]; g_gatt_client_ctl.state = state; if(!g_gatt_client_ctl.state_cb) { pr_info("%s: ble_client_state_cb are not registered\n", __func__); return; } memset(addr, 0, 18); memset(name, 0, 256); bt_get_device_addr_by_proxy(ble_dev, addr, 18); bt_get_device_name_by_proxy(ble_dev, name, 256); g_gatt_client_ctl.state_cb(addr, name, state); } void gatt_client_recv_data_send(GDBusProxy *proxy, DBusMessageIter *iter) { DBusMessageIter array, uuid_iter; const char *uuid; uint8_t *value; int len; if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY) { pr_info("%s: Unable to get value\n", __func__); return; } dbus_message_iter_recurse(iter, &array); dbus_message_iter_get_fixed_array(&array, &value, &len); if (len < 0) { pr_info("%s: Unable to parse value\n", __func__); return; } if (g_dbus_proxy_get_property(proxy, "UUID", &uuid_iter) == FALSE) return; dbus_message_iter_get_basic(&uuid_iter, &uuid); if (g_gatt_client_ctl.recv_cb) g_gatt_client_ctl.recv_cb(uuid, value, len); } RK_BLE_CLIENT_STATE gatt_client_get_state() { return g_gatt_client_ctl.state; } void gatt_client_open() { ble_clean(); } void gatt_client_close() { pr_info("%s\n", __func__); ble_deregister_mtu_callback(); g_gatt_client_ctl.state = RK_BLE_CLIENT_STATE_IDLE; g_gatt_client_ctl.recv_cb = NULL; g_gatt_client_ctl.state_cb = NULL; } int gatt_client_get_service_info(char *address, RK_BLE_CLIENT_SERVICE_INFO *info) { GDBusProxy *proxy; if(!address || !info) { pr_err("%s: Invalid parameters\n", __func__); return -1; } proxy = find_device_by_address(address); if (!proxy) { pr_info("%s: can't find device(%s)\n", __func__, address); return -1; } memset(info, 0, sizeof(RK_BLE_CLIENT_SERVICE_INFO)); gatt_get_list_attributes(g_dbus_proxy_get_path(proxy), info); return 0; } static int gatt_client_select_attribute(char *uuid) { GDBusProxy *proxy; if (!ble_dev) { pr_info("%s: No ble client connected\n", __func__); return -1; } proxy = gatt_select_attribute(NULL, uuid); if (proxy) { set_default_attribute(proxy); return 0; } return -1; } int gatt_client_read(char *uuid, int offset) { if(!uuid) { pr_err("%s: Invalid uuid\n", __func__); return -1; } if(gatt_client_select_attribute(uuid) < 0) { pr_err("%s: select attribute failed\n", __func__); return -1; } return gatt_read_attribute(default_attr, offset); } int gatt_client_write(char *uuid, char *data, int data_len, int offset) { if(!uuid || !data) { pr_err("%s: Invalid uuid or data\n", __func__); return -1; } if(gatt_client_select_attribute(uuid) < 0) { pr_err("%s: select attribute failed\n", __func__); return -1; } return gatt_write_attribute(default_attr, data, data_len, offset); } bool gatt_client_is_notifying(const char *uuid) { if(!uuid) { pr_err("%s: Invalid uuid\n", __func__); return -1; } if(gatt_client_select_attribute(uuid) < 0) { pr_err("%s: select attribute failed\n", __func__); return -1; } return gatt_get_notifying(default_attr); } int gatt_client_notify(const char *uuid, bool enable) { if(!uuid) { pr_err("%s: Invalid uuid\n", __func__); return -1; } if(gatt_client_select_attribute(uuid) < 0) { pr_err("%s: select attribute failed\n", __func__); return -1; } return gatt_notify_attribute(default_attr, enable ? true : false); } int gatt_client_get_eir_data(char *address, char *eir_data, int eir_len) { DBusMessageIter iter; DBusMessageIter array; unsigned char *data; int len, data_len = 0; struct GDBusProxy *proxy; if(!address || (strlen(address) < 17)) { pr_err("%s: invalid address\n", __func__); return -1; } if(!eir_data || eir_len <= 0) { pr_err("%s: invalid eir_data buf, len = %d\n", __func__, len); return -1; } proxy = find_device_by_address(address); if(proxy == NULL) return -1; if (g_dbus_proxy_get_property(proxy, "EirData", &iter) == FALSE) { pr_err("%s: get broadcast data failed\n", __func__); return- 1; } if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) { pr_err("%s: iter type != DBUS_TYPE_ARRAY\n", __func__); return -1; } dbus_message_iter_recurse(&iter, &array); if (!dbus_type_is_fixed(dbus_message_iter_get_arg_type(&array))) { pr_err("%s: dbus type isn't fixed\n", __func__); return -1; } if(dbus_message_iter_get_arg_type(&array) != DBUS_TYPE_BYTE) { pr_err("%s: iter type != DBUS_TYPE_BYTE\n", __func__); return -1; } dbus_message_iter_get_fixed_array(&array, &data, &data_len); if (data_len <= 0) { pr_err("%s: get broadcast data failed, len = %d\n", __func__, data_len); return -1; } pr_err("%s: get broadcast data, data_len = %d\n", __func__, data_len); bt_shell_hexdump((void *)data, data_len * sizeof(*data)); len = data_len > eir_len ? eir_len : data_len; memset(eir_data, 0, eir_len); memcpy(eir_data, data, len); return 0; }