diff --git a/lib/libsdp/sdp.h b/lib/libsdp/sdp.h index 8d78ae889912..acb074a7bb04 100644 --- a/lib/libsdp/sdp.h +++ b/lib/libsdp/sdp.h @@ -649,20 +649,37 @@ typedef struct sdp_sp_profile * sdp_sp_profile_p; struct sdp_nap_profile { - uint16_t security_description; /* HBO: NAP/GN */ - uint16_t net_access_type; /* HBO: NAP */ - uint32_t max_net_access_rate; /* HBO: NAP */ + uint8_t reserved; + uint8_t load_factor; + uint16_t psm; /* HBO */ + uint16_t security_description; /* HBO */ + uint16_t net_access_type; /* HBO */ + uint32_t max_net_access_rate; /* HBO */ }; typedef struct sdp_nap_profile sdp_nap_profile_t; typedef struct sdp_nap_profile * sdp_nap_profile_p; -/* Reuse struct sdp_nap_profile for GN */ -typedef struct sdp_nap_profile sdp_gn_profile_t; -typedef struct sdp_nap_profile * sdp_gn_profile_p; +struct sdp_gn_profile +{ + uint8_t reserved; + uint8_t load_factor; + uint16_t psm; /* HBO */ + uint16_t security_description; /* HBO */ + uint16_t reserved2; +}; +typedef struct sdp_gn_profile sdp_gn_profile_t; +typedef struct sdp_gn_profile * sdp_gn_profile_p; -/* Reuse struct sdp_nap_profile for PANU */ -typedef struct sdp_nap_profile sdp_panu_profile_t; -typedef struct sdp_nap_profile * sdp_panu_profile_p; +struct sdp_panu_profile +{ + uint8_t reserved; + uint8_t load_factor; + uint16_t psm; /* HBO */ + uint16_t security_description; /* HBO */ + uint16_t reserved2; +}; +typedef struct sdp_panu_profile sdp_panu_profile_t; +typedef struct sdp_panu_profile * sdp_panu_profile_p; int32_t sdp_register_service (void *xss, uint16_t uuid, bdaddr_p const bdaddr, uint8_t const *data, diff --git a/usr.sbin/bluetooth/sdpd/gn.c b/usr.sbin/bluetooth/sdpd/gn.c index 618388d45d38..d35c0eea5fda 100644 --- a/usr.sbin/bluetooth/sdpd/gn.c +++ b/usr.sbin/bluetooth/sdpd/gn.c @@ -100,8 +100,12 @@ gn_profile_create_protocol_descriptor_list( uint8_t *buf, uint8_t const * const eob, uint8_t const *data, uint32_t datalen) { + provider_p provider = (provider_p) data; + sdp_gn_profile_p gn = (sdp_gn_profile_p) provider->data; + return (bnep_profile_create_protocol_descriptor_list( - buf, eob, NULL, 0)); + buf, eob, (uint8_t const *) &gn->psm, + sizeof(gn->psm))); } static int32_t @@ -117,6 +121,26 @@ gn_profile_create_security_description( sizeof(gn->security_description))); } +static int32_t +gn_profile_create_service_availability( + uint8_t *buf, uint8_t const * const eob, + uint8_t const *data, uint32_t datalen) +{ + provider_p provider = (provider_p) data; + sdp_gn_profile_p gn = (sdp_gn_profile_p) provider->data; + + return (common_profile_create_service_availability(buf, eob, + &gn->load_factor, 1)); +} + +static int32_t +gn_profile_data_valid(uint8_t const *data, uint32_t datalen) +{ + sdp_gn_profile_p gn = (sdp_gn_profile_p) data; + + return ((gn->psm == 0)? 0 : 1); +} + static attr_t gn_profile_attrs[] = { { SDP_ATTR_SERVICE_RECORD_HANDLE, common_profile_create_service_record_handle }, @@ -126,6 +150,8 @@ static attr_t gn_profile_attrs[] = { gn_profile_create_protocol_descriptor_list }, { SDP_ATTR_LANGUAGE_BASE_ATTRIBUTE_ID_LIST, common_profile_create_language_base_attribute_id_list }, + { SDP_ATTR_SERVICE_AVAILABILITY, + gn_profile_create_service_availability }, { SDP_ATTR_BLUETOOTH_PROFILE_DESCRIPTOR_LIST, gn_profile_create_bluetooth_profile_descriptor_list }, { SDP_ATTR_PRIMARY_LANGUAGE_BASE_ID + SDP_ATTR_SERVICE_NAME_OFFSET, @@ -140,7 +166,7 @@ static attr_t gn_profile_attrs[] = { profile_t gn_profile_descriptor = { SDP_SERVICE_CLASS_GN, sizeof(sdp_gn_profile_t), - common_profile_always_valid, + gn_profile_data_valid, (attr_t const * const) &gn_profile_attrs }; diff --git a/usr.sbin/bluetooth/sdpd/lan.c b/usr.sbin/bluetooth/sdpd/lan.c index a5612eda64a7..2425a89db5a2 100644 --- a/usr.sbin/bluetooth/sdpd/lan.c +++ b/usr.sbin/bluetooth/sdpd/lan.c @@ -102,13 +102,8 @@ lan_profile_create_service_availability( provider_p provider = (provider_p) data; sdp_lan_profile_p lan = (sdp_lan_profile_p) provider->data; - if (buf + 2 > eob) - return (-1); - - SDP_PUT8(SDP_DATA_UINT8, buf); - SDP_PUT8(lan->load_factor, buf); - - return (2); + return (common_profile_create_service_availability(buf, eob, + &lan->load_factor, 1)); } static int32_t diff --git a/usr.sbin/bluetooth/sdpd/nap.c b/usr.sbin/bluetooth/sdpd/nap.c index 45c0c6dd1f25..5a857d8e91ad 100644 --- a/usr.sbin/bluetooth/sdpd/nap.c +++ b/usr.sbin/bluetooth/sdpd/nap.c @@ -99,8 +99,12 @@ nap_profile_create_protocol_descriptor_list( uint8_t *buf, uint8_t const * const eob, uint8_t const *data, uint32_t datalen) { + provider_p provider = (provider_p) data; + sdp_nap_profile_p nap = (sdp_nap_profile_p) provider->data; + return (bnep_profile_create_protocol_descriptor_list( - buf, eob, NULL, 0)); + buf, eob, (uint8_t const *) &nap->psm, + sizeof(nap->psm))); } static int32_t @@ -150,6 +154,26 @@ nap_profile_create_max_net_access_rate( return (3); } +static int32_t +nap_profile_create_service_availability( + uint8_t *buf, uint8_t const * const eob, + uint8_t const *data, uint32_t datalen) +{ + provider_p provider = (provider_p) data; + sdp_nap_profile_p nap = (sdp_nap_profile_p) provider->data; + + return (common_profile_create_service_availability(buf, eob, + &nap->load_factor, 1)); +} + +static int32_t +nap_profile_data_valid(uint8_t const *data, uint32_t datalen) +{ + sdp_nap_profile_p nap = (sdp_nap_profile_p) data; + + return ((nap->psm == 0)? 0 : 1); +} + static attr_t nap_profile_attrs[] = { { SDP_ATTR_SERVICE_RECORD_HANDLE, common_profile_create_service_record_handle }, @@ -159,6 +183,8 @@ static attr_t nap_profile_attrs[] = { nap_profile_create_protocol_descriptor_list }, { SDP_ATTR_LANGUAGE_BASE_ATTRIBUTE_ID_LIST, common_profile_create_language_base_attribute_id_list }, + { SDP_ATTR_SERVICE_AVAILABILITY, + nap_profile_create_service_availability }, { SDP_ATTR_BLUETOOTH_PROFILE_DESCRIPTOR_LIST, nap_profile_create_bluetooth_profile_descriptor_list }, { SDP_ATTR_PRIMARY_LANGUAGE_BASE_ID + SDP_ATTR_SERVICE_NAME_OFFSET, @@ -177,7 +203,7 @@ static attr_t nap_profile_attrs[] = { profile_t nap_profile_descriptor = { SDP_SERVICE_CLASS_NAP, sizeof(sdp_nap_profile_t), - common_profile_always_valid, + nap_profile_data_valid, (attr_t const * const) &nap_profile_attrs }; diff --git a/usr.sbin/bluetooth/sdpd/panu.c b/usr.sbin/bluetooth/sdpd/panu.c index 196b3693108f..e00f6503c924 100644 --- a/usr.sbin/bluetooth/sdpd/panu.c +++ b/usr.sbin/bluetooth/sdpd/panu.c @@ -100,8 +100,45 @@ panu_profile_create_protocol_descriptor_list( uint8_t *buf, uint8_t const * const eob, uint8_t const *data, uint32_t datalen) { + provider_p provider = (provider_p) data; + sdp_panu_profile_p panu = (sdp_panu_profile_p) provider->data; + return (bnep_profile_create_protocol_descriptor_list( - buf, eob, NULL, 0)); + buf, eob, (uint8_t const *) &panu->psm, + sizeof(panu->psm))); +} + +static int32_t +panu_profile_data_valid(uint8_t const *data, uint32_t datalen) +{ + sdp_panu_profile_p panu = (sdp_panu_profile_p) data; + + return ((panu->psm == 0)? 0 : 1); +} + +static int32_t +panu_profile_create_service_availability( + uint8_t *buf, uint8_t const * const eob, + uint8_t const *data, uint32_t datalen) +{ + provider_p provider = (provider_p) data; + sdp_panu_profile_p panu = (sdp_panu_profile_p) provider->data; + + return (common_profile_create_service_availability( buf, eob, + &panu->load_factor, 1)); +} + +static int32_t +panu_profile_create_security_description( + uint8_t *buf, uint8_t const * const eob, + uint8_t const *data, uint32_t datalen) +{ + provider_p provider = (provider_p) data; + sdp_panu_profile_p panu = (sdp_panu_profile_p) provider->data; + + return (bnep_profile_create_security_description(buf, eob, + (uint8_t const *) &panu->security_description, + sizeof(panu->security_description))); } static attr_t panu_profile_attrs[] = { @@ -113,19 +150,23 @@ static attr_t panu_profile_attrs[] = { panu_profile_create_protocol_descriptor_list }, { SDP_ATTR_LANGUAGE_BASE_ATTRIBUTE_ID_LIST, common_profile_create_language_base_attribute_id_list }, + { SDP_ATTR_SERVICE_AVAILABILITY, + panu_profile_create_service_availability }, { SDP_ATTR_BLUETOOTH_PROFILE_DESCRIPTOR_LIST, panu_profile_create_bluetooth_profile_descriptor_list }, { SDP_ATTR_PRIMARY_LANGUAGE_BASE_ID + SDP_ATTR_SERVICE_NAME_OFFSET, panu_profile_create_service_name }, { SDP_ATTR_PRIMARY_LANGUAGE_BASE_ID + SDP_ATTR_SERVICE_DESCRIPTION_OFFSET, panu_profile_create_service_description }, + { SDP_ATTR_SECURITY_DESCRIPTION, + panu_profile_create_security_description }, { 0, NULL } /* end entry */ }; profile_t panu_profile_descriptor = { SDP_SERVICE_CLASS_PANU, sizeof(sdp_panu_profile_t), - common_profile_always_valid, + panu_profile_data_valid, (attr_t const * const) &panu_profile_attrs }; diff --git a/usr.sbin/bluetooth/sdpd/profile.c b/usr.sbin/bluetooth/sdpd/profile.c index e388efa01fbb..f3dfaa7652a3 100644 --- a/usr.sbin/bluetooth/sdpd/profile.c +++ b/usr.sbin/bluetooth/sdpd/profile.c @@ -255,6 +255,24 @@ common_profile_create_string8( return (2 + datalen); } +/* + * Service Availability + */ + +int32_t +common_profile_create_service_availability( + uint8_t *buf, uint8_t const * const eob, + uint8_t const *data, uint32_t datalen) +{ + if (datalen != 1 || buf + 2 > eob) + return (-1); + + SDP_PUT8(SDP_DATA_UINT8, buf); + SDP_PUT8(data[0], buf); + + return (2); +} + /* * seq8 len8 - 2 bytes * seq8 len8 - 2 bytes @@ -419,13 +437,16 @@ bnep_profile_create_protocol_descriptor_list( #endif }; - uint16_t i, psm = 15, version = 0x0100, + uint16_t i, psm, version = 0x0100, nptypes = sizeof(ptype)/sizeof(ptype[0]), nptypes_size = nptypes * 3; - if (18 + nptypes_size > 255 || buf + 20 + nptypes_size > eob) + if (datalen != 2 || 18 + nptypes_size > 255 || + buf + 20 + nptypes_size > eob) return (-1); + memcpy(&psm, data, sizeof(psm)); + SDP_PUT8(SDP_DATA_SEQ8, buf); SDP_PUT8(18 + nptypes_size, buf); diff --git a/usr.sbin/bluetooth/sdpd/profile.h b/usr.sbin/bluetooth/sdpd/profile.h index e72d2c2df5be..0b0d86d8e1d1 100644 --- a/usr.sbin/bluetooth/sdpd/profile.h +++ b/usr.sbin/bluetooth/sdpd/profile.h @@ -81,6 +81,7 @@ profile_attr_create_t common_profile_create_bluetooth_profile_descriptor_list; profile_attr_create_t common_profile_create_language_base_attribute_id_list; profile_attr_create_t common_profile_create_service_provider_name; profile_attr_create_t common_profile_create_string8; +profile_attr_create_t common_profile_create_service_availability; profile_attr_create_t rfcomm_profile_create_protocol_descriptor_list; profile_attr_create_t obex_profile_create_protocol_descriptor_list; profile_attr_create_t obex_profile_create_supported_formats_list;