diff options
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/hciops.c | 81 | ||||
-rw-r--r-- | plugins/mgmtops.c | 77 |
2 files changed, 81 insertions, 77 deletions
diff --git a/plugins/hciops.c b/plugins/hciops.c index 4d8850fa..fec7e166 100644 --- a/plugins/hciops.c +++ b/plugins/hciops.c @@ -63,6 +63,11 @@ enum { PENDING_NAME, }; +struct uuid_info { + uuid_t uuid; + uint8_t svc_hint; +}; + static int max_dev = -1; static struct dev_info { int sk; @@ -1037,10 +1042,10 @@ static void eir_generate_uuid128(GSList *list, uint8_t *ptr, uint16_t *eir_len) uuid128 = ptr + 2; for (; list; list = list->next) { - uuid_t *uuid = list->data; - uint8_t *uuid128_data = uuid->value.uuid128.data; + struct uuid_info *uuid = list->data; + uint8_t *uuid128_data = uuid->uuid.value.uuid128.data; - if (uuid->type != SDP_UUID128) + if (uuid->uuid.type != SDP_UUID128) continue; /* Stop if not enough space to put next UUID128 */ @@ -1136,15 +1141,15 @@ static void create_ext_inquiry_response(int index, uint8_t *data) /* Group all UUID16 types */ for (l = dev->uuids; l != NULL; l = g_slist_next(l)) { - uuid_t *uuid = l->data; + struct uuid_info *uuid = l->data; - if (uuid->type != SDP_UUID16) + if (uuid->uuid.type != SDP_UUID16) continue; - if (uuid->value.uuid16 < 0x1100) + if (uuid->uuid.value.uuid16 < 0x1100) continue; - if (uuid->value.uuid16 == PNP_INFO_SVCLASS_ID) + if (uuid->uuid.value.uuid16 == PNP_INFO_SVCLASS_ID) continue; /* Stop if not enough space to put next UUID16 */ @@ -1155,13 +1160,13 @@ static void create_ext_inquiry_response(int index, uint8_t *data) /* Check for duplicates */ for (i = 0; i < uuid_count; i++) - if (uuid16[i] == uuid->value.uuid16) + if (uuid16[i] == uuid->uuid.value.uuid16) break; if (i < uuid_count) continue; - uuid16[uuid_count++] = uuid->value.uuid16; + uuid16[uuid_count++] = uuid->uuid.value.uuid16; eir_len += sizeof(uint16_t); } @@ -3021,48 +3026,6 @@ static int hciops_enable_le(int index) return 0; } -static uint8_t get_uuid_mask(uint16_t uuid16) -{ - switch (uuid16) { - case DIALUP_NET_SVCLASS_ID: - case CIP_SVCLASS_ID: - return 0x42; /* Telephony & Networking */ - case IRMC_SYNC_SVCLASS_ID: - case OBEX_OBJPUSH_SVCLASS_ID: - case OBEX_FILETRANS_SVCLASS_ID: - case IRMC_SYNC_CMD_SVCLASS_ID: - case PBAP_PSE_SVCLASS_ID: - return 0x10; /* Object Transfer */ - case HEADSET_SVCLASS_ID: - case HANDSFREE_SVCLASS_ID: - return 0x20; /* Audio */ - case CORDLESS_TELEPHONY_SVCLASS_ID: - case INTERCOM_SVCLASS_ID: - case FAX_SVCLASS_ID: - case SAP_SVCLASS_ID: - /* - * Setting the telephony bit for the handsfree audio gateway - * role is not required by the HFP specification, but the - * Nokia 616 carkit is just plain broken! It will refuse - * pairing without this bit set. - */ - case HANDSFREE_AGW_SVCLASS_ID: - return 0x40; /* Telephony */ - case AUDIO_SOURCE_SVCLASS_ID: - case VIDEO_SOURCE_SVCLASS_ID: - return 0x08; /* Capturing */ - case AUDIO_SINK_SVCLASS_ID: - case VIDEO_SINK_SVCLASS_ID: - return 0x04; /* Rendering */ - case PANU_SVCLASS_ID: - case NAP_SVCLASS_ID: - case GN_SVCLASS_ID: - return 0x02; /* Networking */ - default: - return 0; - } -} - static uint8_t generate_service_class(int index) { struct dev_info *dev = &devs[index]; @@ -3070,12 +3033,9 @@ static uint8_t generate_service_class(int index) uint8_t val = 0; for (l = dev->uuids; l != NULL; l = g_slist_next(l)) { - uuid_t *uuid = l->data; + struct uuid_info *uuid = l->data; - if (uuid->type != SDP_UUID16) - continue; - - val |= get_uuid_mask(uuid->value.uuid16); + val |= uuid->svc_hint; } return val; @@ -3117,13 +3077,18 @@ static int update_service_classes(int index) return err; } -static int hciops_add_uuid(int index, uuid_t *uuid) +static int hciops_add_uuid(int index, uuid_t *uuid, uint8_t svc_hint) { struct dev_info *dev = &devs[index]; + struct uuid_info *info; DBG("hci%d", index); - dev->uuids = g_slist_append(dev->uuids, g_memdup(uuid, sizeof(*uuid))); + info = g_new0(struct uuid_info, 1); + memcpy(&info->uuid, uuid, sizeof(*uuid)); + info->svc_hint = svc_hint; + + dev->uuids = g_slist_append(dev->uuids, info); return update_service_classes(index); } diff --git a/plugins/mgmtops.c b/plugins/mgmtops.c index 28b42bbe..e33c0496 100644 --- a/plugins/mgmtops.c +++ b/plugins/mgmtops.c @@ -410,17 +410,44 @@ static void uuid_to_uuid128(uuid_t *uuid128, const uuid_t *uuid) memcpy(uuid128, uuid, sizeof(*uuid)); } -static int mgmt_uuid_op(int index, uint16_t op, uuid_t *uuid) +static int mgmt_add_uuid(int index, uuid_t *uuid, uint8_t svc_hint) { - char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_uuid)]; + char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_add_uuid)]; struct mgmt_hdr *hdr = (void *) buf; - struct mgmt_cp_uuid *cp = (void *) &buf[sizeof(*hdr)]; + struct mgmt_cp_add_uuid *cp = (void *) &buf[sizeof(*hdr)]; uuid_t uuid128; + DBG("index %d", index); + uuid_to_uuid128(&uuid128, uuid); memset(buf, 0, sizeof(buf)); - hdr->opcode = htobs(op); + hdr->opcode = htobs(MGMT_OP_ADD_UUID); + hdr->len = htobs(sizeof(*cp)); + + cp->index = htobs(index); + memcpy(cp->uuid, uuid128.value.uuid128.data, 16); + cp->svc_hint = svc_hint; + + if (write(mgmt_sock, buf, sizeof(buf)) < 0) + return -errno; + + return 0; +} + +static int mgmt_remove_uuid(int index, uuid_t *uuid) +{ + char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_remove_uuid)]; + struct mgmt_hdr *hdr = (void *) buf; + struct mgmt_cp_remove_uuid *cp = (void *) &buf[sizeof(*hdr)]; + uuid_t uuid128; + + DBG("index %d", index); + + uuid_to_uuid128(&uuid128, uuid); + + memset(buf, 0, sizeof(buf)); + hdr->opcode = htobs(MGMT_OP_REMOVE_UUID); hdr->len = htobs(sizeof(*cp)); cp->index = htobs(index); @@ -439,7 +466,7 @@ static int clear_uuids(int index) memset(&uuid_any, 0, sizeof(uuid_any)); uuid_any.type = SDP_UUID128; - return mgmt_uuid_op(index, MGMT_OP_REMOVE_UUID, &uuid_any); + return mgmt_remove_uuid(index, &uuid_any); } static void read_index_list_complete(int sk, void *buf, size_t len) @@ -497,6 +524,8 @@ static void read_info_complete(int sk, void *buf, size_t len) return; } + mgmt_set_mode(index, MGMT_OP_SET_SERVICE_CACHE, 1); + info = &controllers[index]; info->type = rp->type; info->enabled = rp->powered; @@ -701,6 +730,12 @@ static void mgmt_cmd_complete(int sk, void *buf, size_t len) case MGMT_OP_REMOVE_UUID: DBG("remove_uuid complete"); break; + case MGMT_OP_SET_DEV_CLASS: + DBG("set_dev_class complete"); + break; + case MGMT_OP_SET_SERVICE_CACHE: + DBG("set_service_cache complete"); + break; default: error("Unknown command complete for opcode %u", opcode); break; @@ -879,8 +914,24 @@ static void mgmt_cleanup(void) static int mgmt_set_dev_class(int index, uint8_t major, uint8_t minor) { + char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_set_dev_class)]; + struct mgmt_hdr *hdr = (void *) buf; + struct mgmt_cp_set_dev_class *cp = (void *) &buf[sizeof(*hdr)]; + DBG("index %d major %u minor %u", index, major, minor); - return -ENOSYS; + + memset(buf, 0, sizeof(buf)); + hdr->opcode = htobs(MGMT_OP_SET_DEV_CLASS); + hdr->len = htobs(sizeof(*cp)); + + cp->index = htobs(index); + cp->major = major; + cp->minor = minor; + + if (write(mgmt_sock, buf, sizeof(buf)) < 0) + return -errno; + + return 0; } static int mgmt_set_limited_discoverable(int index, gboolean limited) @@ -1123,22 +1174,10 @@ static int mgmt_set_did(int index, uint16_t vendor, uint16_t product, return -ENOSYS; } -static int mgmt_add_uuid(int index, uuid_t *uuid) -{ - DBG("index %d", index); - return mgmt_uuid_op(index, MGMT_OP_ADD_UUID, uuid); -} - -static int mgmt_remove_uuid(int index, uuid_t *uuid) -{ - DBG("index %d", index); - return mgmt_uuid_op(index, MGMT_OP_REMOVE_UUID, uuid); -} - static int mgmt_disable_cod_cache(int index) { DBG("index %d", index); - return -ENOSYS; + return mgmt_set_mode(index, MGMT_OP_SET_SERVICE_CACHE, 0); } static int mgmt_restore_powered(int index) |