mirror of
https://git.kernel.org/pub/scm/bluetooth/bluez.git
synced 2024-11-28 22:54:14 +08:00
mgmt: Implement adapter name control
This patch adds a new set_local_name command as well as a local_name_changed event to the management interface. Instead of 248 bytes (like in the HCI spec) 249 bytes are always reserved for the name in the messages so that there's a guarantee of it being nul-terminated (this is not guaranteed on the HCI level).
This commit is contained in:
parent
1c16543345
commit
3011a312a7
5
TODO
5
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
|
||||
|
@ -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: <controller id>
|
||||
Command Parameters: Name (249 Octets)
|
||||
Return Paramters: Name (249 Octets)
|
||||
|
||||
Read Tracing Buffer Size Command
|
||||
================================
|
||||
@ -448,3 +455,10 @@ Event Code 0x0010
|
||||
Controller Index: <controller id>
|
||||
Event Parameters Address (6 Octets)
|
||||
Status (1 Octet)
|
||||
|
||||
Local Name Changed Event
|
||||
========================
|
||||
|
||||
Event Code 0x0011
|
||||
Controller Index <controller id>
|
||||
Event Parameters Name (249 Octets)
|
||||
|
10
lib/mgmt.h
10
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;
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user