diff --git a/TODO b/TODO index 1c22c869e..1e3ea165c 100644 --- a/TODO +++ b/TODO @@ -226,11 +226,6 @@ Management Interface Priority: High Complexity: C3 -- Local name setting. mgmt_set_local_name & mgmt_local_name_changed - - Priority: High - Complexity: C1 - - EIR generation support Priority: High diff --git a/doc/mgmt-api.txt b/doc/mgmt-api.txt index 06c0ef507..dd179eed9 100644 --- a/doc/mgmt-api.txt +++ b/doc/mgmt-api.txt @@ -266,6 +266,13 @@ User Confirmation Negative Reply Command Return Paramters: Address (6 Octets) Status (1 Octet) +Set Local Name Command +====================== + + Command Code: 0x0017 + Controller Index: + Command Parameters: Name (249 Octets) + Return Paramters: Name (249 Octets) Read Tracing Buffer Size Command ================================ @@ -448,3 +455,10 @@ Event Code 0x0010 Controller Index: Event Parameters Address (6 Octets) Status (1 Octet) + +Local Name Changed Event +======================== + +Event Code 0x0011 +Controller Index +Event Parameters Name (249 Octets) diff --git a/lib/mgmt.h b/lib/mgmt.h index 77fffed42..bd65328c5 100644 --- a/lib/mgmt.h +++ b/lib/mgmt.h @@ -174,6 +174,11 @@ struct mgmt_rp_user_confirm_reply { #define MGMT_OP_USER_CONFIRM_NEG_REPLY 0x0016 +#define MGMT_OP_SET_LOCAL_NAME 0x0017 +struct mgmt_cp_set_local_name { + uint8_t name[249]; +} __packed; + #define MGMT_EV_CMD_COMPLETE 0x0001 struct mgmt_ev_cmd_complete { uint16_t opcode; @@ -241,3 +246,8 @@ struct mgmt_ev_auth_failed { bdaddr_t bdaddr; uint8_t status; } __packed; + +#define MGMT_EV_LOCAL_NAME_CHANGED 0x0011 +struct mgmt_ev_local_name_changed { + uint8_t name[249]; +} __packed; diff --git a/plugins/mgmtops.c b/plugins/mgmtops.c index d445558ae..562bb09f2 100644 --- a/plugins/mgmtops.c +++ b/plugins/mgmtops.c @@ -999,6 +999,36 @@ static void get_connections_complete(int sk, uint16_t index, void *buf, read_info(sk, index); } +static void set_local_name_complete(int sk, uint16_t index, void *buf, + size_t len) +{ + struct mgmt_cp_set_local_name *rp = buf; + struct controller_info *info; + struct btd_adapter *adapter; + + if (len < sizeof(*rp)) { + error("Too small pair_device complete event"); + return; + } + + DBG("hci%d name %s", index, (char *) rp->name); + + if (index > max_index) { + error("Unexpected index %u in pair_device complete", index); + return; + } + + info = &controllers[index]; + + adapter = manager_find_adapter(&info->bdaddr); + if (adapter == NULL) { + DBG("Adapter not found"); + return; + } + + adapter_update_local_name(adapter, (char *) rp->name); +} + static void mgmt_cmd_complete(int sk, uint16_t index, void *buf, size_t len) { struct mgmt_ev_cmd_complete *ev = buf; @@ -1080,6 +1110,9 @@ static void mgmt_cmd_complete(int sk, uint16_t index, void *buf, size_t len) case MGMT_OP_USER_CONFIRM_NEG_REPLY: DBG("user_confirm_net_reply complete"); break; + case MGMT_OP_SET_LOCAL_NAME: + set_local_name_complete(sk, index, ev->data, len); + break; default: error("Unknown command complete for opcode %u", opcode); break; @@ -1362,8 +1395,23 @@ static int mgmt_resolve_name(int index, bdaddr_t *bdaddr) static int mgmt_set_name(int index, const char *name) { + char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_set_local_name)]; + struct mgmt_hdr *hdr = (void *) buf; + struct mgmt_cp_set_local_name *cp = (void *) &buf[sizeof(*hdr)]; + DBG("index %d, name %s", index, name); - return -ENOSYS; + + memset(buf, 0, sizeof(buf)); + hdr->opcode = htobs(MGMT_OP_SET_LOCAL_NAME); + hdr->len = htobs(sizeof(*cp)); + hdr->index = htobs(index); + + strncpy((char *) cp->name, name, sizeof(cp->name) - 1); + + if (write(mgmt_sock, buf, sizeof(buf)) < 0) + return -errno; + + return 0; } static int mgmt_cancel_resolve_name(int index, bdaddr_t *bdaddr)