adapter_set_name(rp->name);
}
-static uint8_t set_adapter_name(uint8_t *name, uint16_t len)
+static uint8_t set_adapter_name(const uint8_t *name, uint16_t len)
{
struct mgmt_cp_set_local_name cp;
return HAL_STATUS_FAILED;
}
-static uint8_t set_discoverable_timeout(uint8_t *timeout)
+static uint8_t set_discoverable_timeout(const void *buf, uint16_t len)
{
+ const uint32_t *timeout = buf;
+
+ if (len != sizeof(*timeout)) {
+ error("Invalid set disc timeout size (%u bytes), terminating",
+ len);
+ raise(SIGTERM);
+ return HAL_STATUS_FAILED;
+ }
+
/* Android handles discoverable timeout in Settings app.
* There is no need to use kernel feature for that.
* Just need to store this value here */
return true;
}
-static bool get_property(void *buf, uint16_t len)
+static void handle_get_adapter_prop_cmd(const void *buf, uint16_t len)
{
- struct hal_cmd_get_adapter_prop *cmd = buf;
+ const struct hal_cmd_get_adapter_prop *cmd = buf;
+ uint8_t status;
switch (cmd->type) {
case HAL_PROP_ADAPTER_ADDR:
get_address();
- return true;
+ break;
case HAL_PROP_ADAPTER_NAME:
- return get_name();
+ if (!get_name()) {
+ status = HAL_STATUS_FAILED;
+ goto failed;
+ }
+ break;
case HAL_PROP_ADAPTER_UUIDS:
- return get_uuids();
+ if (!get_uuids()) {
+ status = HAL_STATUS_FAILED;
+ goto failed;
+ }
+ break;
case HAL_PROP_ADAPTER_CLASS:
- return get_class();
+ if (!get_class()) {
+ status = HAL_STATUS_FAILED;
+ goto failed;
+ }
+ break;
case HAL_PROP_ADAPTER_TYPE:
- return get_type();
+ if (!get_type()) {
+ status = HAL_STATUS_FAILED;
+ goto failed;
+ }
+ break;
case HAL_PROP_ADAPTER_SERVICE_REC:
- return get_service();
+ if (!get_service()) {
+ status = HAL_STATUS_FAILED;
+ goto failed;
+ }
+ break;
case HAL_PROP_ADAPTER_SCAN_MODE:
- return get_scan_mode();
+ if (!get_scan_mode()) {
+ status = HAL_STATUS_FAILED;
+ goto failed;
+ }
+ break;
case HAL_PROP_ADAPTER_BONDED_DEVICES:
- return get_devices();
+ if (!get_devices()) {
+ status = HAL_STATUS_FAILED;
+ goto failed;
+ }
+ break;
case HAL_PROP_ADAPTER_DISC_TIMEOUT:
- return get_discoverable_timeout();
+ if (!get_discoverable_timeout()) {
+ status = HAL_STATUS_FAILED;
+ goto failed;
+ }
+ break;
default:
- return false;
+ status = HAL_STATUS_FAILED;
+ goto failed;
}
+
+ status = HAL_STATUS_SUCCESS;
+
+failed:
+ ipc_send_rsp(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_GET_ADAPTER_PROP, status);
}
static void get_properties(void)
return false;
}
-static uint8_t set_scan_mode(void *buf, uint16_t len)
+static uint8_t set_scan_mode(const void *buf, uint16_t len)
{
- uint8_t *mode = buf;
+ const uint8_t *mode = buf;
bool conn, disc, cur_conn, cur_disc;
+ if (len != sizeof(*mode)) {
+ error("Invalid set scan mode size (%u bytes), terminating",
+ len);
+ raise(SIGTERM);
+ return HAL_STATUS_FAILED;
+ }
+
cur_conn = adapter.current_settings & MGMT_SETTING_CONNECTABLE;
cur_disc = adapter.current_settings & MGMT_SETTING_DISCOVERABLE;
return HAL_STATUS_DONE;
}
-static uint8_t set_property(void *buf, uint16_t len)
+static void handle_set_adapter_prop_cmd(const void *buf, uint16_t len)
{
- struct hal_cmd_set_adapter_prop *cmd = buf;
+ const struct hal_cmd_set_adapter_prop *cmd = buf;
+ uint8_t status;
+
+ if (len != sizeof(*cmd) + cmd->len) {
+ error("Invalid set adapter prop cmd (0x%x), terminating",
+ cmd->type);
+ raise(SIGTERM);
+ return;
+ }
switch (cmd->type) {
case HAL_PROP_ADAPTER_SCAN_MODE:
- return set_scan_mode(cmd->val, cmd->len);
+ status = set_scan_mode(cmd->val, cmd->len);
+ break;
case HAL_PROP_ADAPTER_NAME:
- return set_adapter_name(cmd->val, cmd->len);
+ status = set_adapter_name(cmd->val, cmd->len);
+ break;
case HAL_PROP_ADAPTER_DISC_TIMEOUT:
- return set_discoverable_timeout(cmd->val);
+ status = set_discoverable_timeout(cmd->val, cmd->len);
+ break;
default:
DBG("Unhandled property type 0x%x", cmd->type);
- return HAL_STATUS_FAILED;
+ status = HAL_STATUS_FAILED;
+ break;
}
+
+ ipc_send_rsp(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_SET_ADAPTER_PROP, status);
}
static void pair_device_complete(uint8_t status, uint16_t length,
HAL_BOND_STATE_NONE);
}
-static bool create_bond(void *buf, uint16_t len)
+static void handle_create_bond_cmd(const void *buf, uint16_t len)
{
- struct hal_cmd_create_bond *cmd = buf;
+ const struct hal_cmd_create_bond *cmd = buf;
+ uint8_t status;
struct mgmt_cp_pair_device cp;
cp.io_cap = DEFAULT_IO_CAPABILITY;
android2bdaddr(cmd->bdaddr, &cp.addr.bdaddr);
if (mgmt_send(mgmt_if, MGMT_OP_PAIR_DEVICE, adapter.index, sizeof(cp),
- &cp, pair_device_complete, NULL, NULL) == 0)
- return false;
+ &cp, pair_device_complete, NULL, NULL) == 0) {
+ status = HAL_STATUS_FAILED;
+ goto fail;
+ }
+
+ status = HAL_STATUS_SUCCESS;
set_device_bond_state(&cp.addr.bdaddr, HAL_STATUS_SUCCESS,
HAL_BOND_STATE_BONDING);
- return true;
+fail:
+ ipc_send_rsp(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_CREATE_BOND, status);
}
-static bool cancel_bond(void *buf, uint16_t len)
+static void handle_cancel_bond_cmd(const void *buf, uint16_t len)
{
- struct hal_cmd_cancel_bond *cmd = buf;
+ const struct hal_cmd_cancel_bond *cmd = buf;
struct mgmt_addr_info cp;
+ uint8_t status;
cp.type = BDADDR_BREDR;
android2bdaddr(cmd->bdaddr, &cp.bdaddr);
- return mgmt_reply(mgmt_if, MGMT_OP_CANCEL_PAIR_DEVICE, adapter.index,
- sizeof(cp), &cp, NULL, NULL, NULL) > 0;
+ if (mgmt_reply(mgmt_if, MGMT_OP_CANCEL_PAIR_DEVICE, adapter.index,
+ sizeof(cp), &cp, NULL, NULL, NULL) > 0)
+ status = HAL_STATUS_SUCCESS;
+ else
+ status = HAL_STATUS_FAILED;
+
+ ipc_send_rsp(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_CANCEL_BOND, status);
}
static void unpair_device_complete(uint8_t status, uint16_t length,
HAL_BOND_STATE_NONE);
}
-static bool remove_bond(void *buf, uint16_t len)
+static void handle_remove_bond_cmd(const void *buf, uint16_t len)
{
- struct hal_cmd_remove_bond *cmd = buf;
+ const struct hal_cmd_remove_bond *cmd = buf;
struct mgmt_cp_unpair_device cp;
+ uint8_t status;
cp.disconnect = 1;
cp.addr.type = BDADDR_BREDR;
android2bdaddr(cmd->bdaddr, &cp.addr.bdaddr);
- return mgmt_send(mgmt_if, MGMT_OP_UNPAIR_DEVICE, adapter.index,
+ if (mgmt_send(mgmt_if, MGMT_OP_UNPAIR_DEVICE, adapter.index,
sizeof(cp), &cp, unpair_device_complete,
- NULL, NULL) > 0;
+ NULL, NULL) > 0)
+ status = HAL_STATUS_SUCCESS;
+ else
+ status = HAL_STATUS_FAILED;
+
+ ipc_send_rsp(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_REMOVE_BOND, status);
}
-static uint8_t pin_reply(void *buf, uint16_t len)
+static void handle_pin_reply_cmd(const void *buf, uint16_t len)
{
- struct hal_cmd_pin_reply *cmd = buf;
+ const struct hal_cmd_pin_reply *cmd = buf;
+ uint8_t status;
bdaddr_t bdaddr;
char addr[18];
DBG("%s accept %u pin_len %u", addr, cmd->accept, cmd->pin_len);
- if (!cmd->accept && cmd->pin_len)
- return HAL_STATUS_INVALID;
+ if (!cmd->accept && cmd->pin_len) {
+ status = HAL_STATUS_INVALID;
+ goto failed;
+ }
if (cmd->accept) {
struct mgmt_cp_pin_code_reply rp;
memcpy(rp.pin_code, cmd->pin_code, rp.pin_len);
if (mgmt_reply(mgmt_if, MGMT_OP_PIN_CODE_REPLY, adapter.index,
- sizeof(rp), &rp, NULL, NULL, NULL) == 0)
- return HAL_STATUS_FAILED;
+ sizeof(rp), &rp, NULL, NULL, NULL) == 0) {
+ status = HAL_STATUS_FAILED;
+ goto failed;
+ }
} else {
struct mgmt_cp_pin_code_neg_reply rp;
if (mgmt_reply(mgmt_if, MGMT_OP_PIN_CODE_NEG_REPLY,
adapter.index, sizeof(rp), &rp,
- NULL, NULL, NULL) == 0)
- return HAL_STATUS_FAILED;
+ NULL, NULL, NULL) == 0) {
+ status = HAL_STATUS_FAILED;
+ goto failed;
+ }
}
- return HAL_STATUS_SUCCESS;
+ status = HAL_STATUS_SUCCESS;
+failed:
+ ipc_send_rsp(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_PIN_REPLY, status);
}
static uint8_t user_confirm_reply(const bdaddr_t *bdaddr, bool accept)
return HAL_STATUS_SUCCESS;
}
-static uint8_t ssp_reply(void *buf, uint16_t len)
+static void handle_ssp_reply_cmd(const void *buf, uint16_t len)
{
- struct hal_cmd_ssp_reply *cmd = buf;
- uint8_t status;
+ const struct hal_cmd_ssp_reply *cmd = buf;
bdaddr_t bdaddr;
+ uint8_t status;
char addr[18];
/* TODO should parameters sanity be verified here? */
break;
}
- return status;
+ ipc_send_rsp(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_SSP_REPLY, status);
}
-static uint8_t get_remote_services(void *buf, uint16_t len)
+static void handle_get_remote_services_cmd(const void *buf, uint16_t len)
{
- struct hal_cmd_get_remote_services *cmd = buf;
+ const struct hal_cmd_get_remote_services *cmd = buf;
+ uint8_t status;
bdaddr_t addr;
android2bdaddr(&cmd->bdaddr, &addr);
- return browse_remote_sdp(&addr);
+ status = browse_remote_sdp(&addr);
+
+ ipc_send_rsp(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_GET_REMOTE_SERVICES,
+ status);
}
-void bt_bluetooth_handle_cmd(int sk, uint8_t opcode, void *buf, uint16_t len)
+static void handle_enable_cmd(const void *buf, uint16_t len)
{
- uint8_t status = HAL_STATUS_FAILED;
+ uint8_t status;
- switch (opcode) {
- case HAL_OP_ENABLE:
- /* Framework expects all properties to be emitted while
- * enabling adapter */
- get_properties();
+ /* Framework expects all properties to be emitted while
+ * enabling adapter */
+ get_properties();
- if (adapter.current_settings & MGMT_SETTING_POWERED) {
- status = HAL_STATUS_DONE;
- goto error;
- }
+ if (adapter.current_settings & MGMT_SETTING_POWERED) {
+ status = HAL_STATUS_DONE;
+ goto failed;
+ }
- if (!set_mode(MGMT_OP_SET_POWERED, 0x01))
- goto error;
+ if (!set_mode(MGMT_OP_SET_POWERED, 0x01)) {
+ status = HAL_STATUS_FAILED;
+ goto failed;
+ }
- break;
- case HAL_OP_DISABLE:
- if (!(adapter.current_settings & MGMT_SETTING_POWERED)) {
- status = HAL_STATUS_DONE;
- goto error;
- }
+ status = HAL_STATUS_SUCCESS;
+failed:
+ ipc_send_rsp(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_ENABLE, status);
+}
- if (!set_mode(MGMT_OP_SET_POWERED, 0x00))
- goto error;
+static void handle_disable_cmd(const void *buf, uint16_t len)
+{
+ uint8_t status;
- break;
- case HAL_OP_GET_ADAPTER_PROPS:
- get_properties();
+ if (!(adapter.current_settings & MGMT_SETTING_POWERED)) {
+ status = HAL_STATUS_DONE;
+ goto failed;
+ }
- break;
- case HAL_OP_GET_ADAPTER_PROP:
- if (!get_property(buf, len))
- goto error;
+ if (!set_mode(MGMT_OP_SET_POWERED, 0x00)) {
+ status = HAL_STATUS_FAILED;
+ goto failed;
+ }
- break;
- case HAL_OP_SET_ADAPTER_PROP:
- status = set_property(buf, len);
- if (status != HAL_STATUS_SUCCESS && status != HAL_STATUS_DONE)
- goto error;
+ status = HAL_STATUS_SUCCESS;
+failed:
+ ipc_send_rsp(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_DISABLE, status);
+}
- break;
- case HAL_OP_CREATE_BOND:
- if (!create_bond(buf, len))
- goto error;
+static void handle_get_adapter_props_cmd(const void *buf, uint16_t len)
+{
+ get_properties();
- break;
- case HAL_OP_CANCEL_BOND:
- if (!cancel_bond(buf, len))
- goto error;
+ ipc_send_rsp(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_GET_ADAPTER_PROPS,
+ HAL_STATUS_SUCCESS);
+}
- break;
- case HAL_OP_REMOVE_BOND:
- if (!remove_bond(buf, len))
- goto error;
+static void handle_get_remote_device_props_cmd(const void *buf, uint16_t len)
+{
+ /* TODO */
- break;
- case HAL_OP_PIN_REPLY:
- status = pin_reply(buf, len);
- if (status != HAL_STATUS_SUCCESS)
- goto error;
+ ipc_send_rsp(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_GET_REMOTE_DEVICE_PROPS,
+ HAL_STATUS_FAILED);
+}
- break;
- case HAL_OP_SSP_REPLY:
- status = ssp_reply(buf, len);
- if (status != HAL_STATUS_SUCCESS)
- goto error;
- break;
- case HAL_OP_START_DISCOVERY:
- if (adapter.discovering) {
- status = HAL_STATUS_DONE;
- goto error;
- }
+static void handle_get_remote_device_prop_cmd(const void *buf, uint16_t len)
+{
+ /* TODO */
- if (!(adapter.current_settings & MGMT_SETTING_POWERED)) {
- status = HAL_STATUS_NOT_READY;
- goto error;
- }
+ ipc_send_rsp(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_GET_REMOTE_DEVICE_PROP,
+ HAL_STATUS_FAILED);
+}
+
+static void handle_set_remote_device_prop_cmd(const void *buf, uint16_t len)
+{
+ const struct hal_cmd_set_remote_device_prop *cmd = buf;
+ uint8_t status;
- if (!start_discovery())
- goto error;
+ if (len != sizeof(*cmd) + cmd->len) {
+ error("Invalid set remote device prop cmd (0x%x), terminating",
+ cmd->type);
+ raise(SIGTERM);
+ return;
+ }
+ /* TODO */
+
+ switch (cmd->type) {
+ default:
+ DBG("Unhandled property type 0x%x", cmd->type);
+ status = HAL_STATUS_FAILED;
break;
- case HAL_OP_CANCEL_DISCOVERY:
- if (!adapter.discovering) {
- status = HAL_STATUS_DONE;
- goto error;
- }
+ }
- if (!(adapter.current_settings & MGMT_SETTING_POWERED)) {
- status = HAL_STATUS_NOT_READY;
- goto error;
- }
+ ipc_send_rsp(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_SET_REMOTE_DEVICE_PROP,
+ status);
+}
- if (!stop_discovery())
- goto error;
+static void handle_get_remote_service_rec_cmd(const void *buf, uint16_t len)
+{
+ /* TODO */
- break;
- case HAL_OP_GET_REMOTE_SERVICES:
- status = get_remote_services(buf, len);
- if (status != HAL_STATUS_SUCCESS)
- goto error;
- break;
- default:
- DBG("Unhandled command, opcode 0x%x", opcode);
- goto error;
+ ipc_send_rsp(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_GET_REMOTE_SERVICE_REC,
+ HAL_STATUS_FAILED);
+}
+
+static void handle_start_discovery_cmd(const void *buf, uint16_t len)
+{
+ uint8_t status;
+
+ if (adapter.discovering) {
+ status = HAL_STATUS_DONE;
+ goto failed;
}
- ipc_send_rsp(HAL_SERVICE_ID_BLUETOOTH, opcode, HAL_STATUS_SUCCESS);
- return;
+ if (!(adapter.current_settings & MGMT_SETTING_POWERED)) {
+ status = HAL_STATUS_NOT_READY;
+ goto failed;
+ }
-error:
- error("Error handling command 0x%02x status %u", opcode, status);
+ if (!start_discovery()) {
+ status = HAL_STATUS_FAILED;
+ goto failed;
+ }
- ipc_send_rsp(HAL_SERVICE_ID_BLUETOOTH, opcode, status);
+ status = HAL_STATUS_SUCCESS;
+failed:
+ ipc_send_rsp(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_START_DISCOVERY, status);
}
+static void handle_cancel_discovery_cmd(const void *buf, uint16_t len)
+{
+ uint8_t status;
+
+ if (!adapter.discovering) {
+ status = HAL_STATUS_DONE;
+ goto failed;
+ }
+
+ if (!(adapter.current_settings & MGMT_SETTING_POWERED)) {
+ status = HAL_STATUS_NOT_READY;
+ goto failed;
+ }
+
+ if (!stop_discovery()) {
+ status = HAL_STATUS_FAILED;
+ goto failed;
+ }
+
+ status = HAL_STATUS_SUCCESS;
+
+failed:
+ ipc_send_rsp(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_CANCEL_DISCOVERY, status);
+}
+
+static const struct ipc_handler cmd_handlers[] = {
+ /* HAL_OP_ENABLE */
+ { handle_enable_cmd, false, 0 },
+ /* HAL_OP_DISABLE */
+ { handle_disable_cmd, false, 0 },
+ /* HAL_OP_GET_ADAPTER_PROPS */
+ { handle_get_adapter_props_cmd, false, 0 },
+ /* HAL_OP_GET_ADAPTER_PROP */
+ { handle_get_adapter_prop_cmd, false,
+ sizeof(struct hal_cmd_get_adapter_prop) },
+ /* HAL_OP_SET_ADAPTER_PROP */
+ { handle_set_adapter_prop_cmd, true,
+ sizeof(struct hal_cmd_set_adapter_prop) },
+ /* HAL_OP_GET_REMOTE_DEVICE_PROPS */
+ { handle_get_remote_device_props_cmd, false,
+ sizeof(struct hal_cmd_get_remote_device_props) },
+ /* HAL_OP_GET_REMOTE_DEVICE_PROP */
+ { handle_get_remote_device_prop_cmd, false,
+ sizeof(struct hal_cmd_get_remote_device_prop) },
+ /* HAL_OP_SET_REMOTE_DEVICE_PROP */
+ { handle_set_remote_device_prop_cmd, true,
+ sizeof(struct hal_cmd_set_remote_device_prop) },
+ /* HAL_OP_GET_REMOTE_SERVICE_REC */
+ { handle_get_remote_service_rec_cmd, false,
+ sizeof(struct hal_cmd_get_remote_service_rec) },
+ /* HAL_OP_GET_REMOTE_SERVICES */
+ { handle_get_remote_services_cmd, false,
+ sizeof(struct hal_cmd_get_remote_services) },
+ /* HAL_OP_START_DISCOVERY */
+ { handle_start_discovery_cmd, false, 0 },
+ /* HAL_OP_CANCEL_DISCOVERY */
+ { handle_cancel_discovery_cmd, false, 0 },
+ /* HAL_OP_CREATE_BOND */
+ { handle_create_bond_cmd, false, sizeof(struct hal_cmd_create_bond) },
+ /* HAL_OP_REMOVE_BOND */
+ { handle_remove_bond_cmd, false, sizeof(struct hal_cmd_remove_bond) },
+ /* HAL_OP_CANCEL_BOND */
+ {handle_cancel_bond_cmd, false, sizeof(struct hal_cmd_cancel_bond) },
+ /* HAL_OP_PIN_REPLY */
+ { handle_pin_reply_cmd, false, sizeof(struct hal_cmd_pin_reply) },
+ /* HAL_OP_SSP_REPLY */
+ { handle_ssp_reply_cmd, false, sizeof(struct hal_cmd_ssp_reply) },
+};
+
void bt_bluetooth_register(void)
{
DBG("");
+
+ ipc_register(HAL_SERVICE_ID_BLUETOOTH, cmd_handlers,
+ sizeof(cmd_handlers)/sizeof(cmd_handlers[0]));
}
void bt_bluetooth_unregister(void)
{
DBG("");
+
+ ipc_unregister(HAL_SERVICE_ID_CORE);
}