13deb3ec6SMatthias Ringwald /* 23deb3ec6SMatthias Ringwald * Copyright (C) 2014 BlueKitchen GmbH 33deb3ec6SMatthias Ringwald * 43deb3ec6SMatthias Ringwald * Redistribution and use in source and binary forms, with or without 53deb3ec6SMatthias Ringwald * modification, are permitted provided that the following conditions 63deb3ec6SMatthias Ringwald * are met: 73deb3ec6SMatthias Ringwald * 83deb3ec6SMatthias Ringwald * 1. Redistributions of source code must retain the above copyright 93deb3ec6SMatthias Ringwald * notice, this list of conditions and the following disclaimer. 103deb3ec6SMatthias Ringwald * 2. Redistributions in binary form must reproduce the above copyright 113deb3ec6SMatthias Ringwald * notice, this list of conditions and the following disclaimer in the 123deb3ec6SMatthias Ringwald * documentation and/or other materials provided with the distribution. 133deb3ec6SMatthias Ringwald * 3. Neither the name of the copyright holders nor the names of 143deb3ec6SMatthias Ringwald * contributors may be used to endorse or promote products derived 153deb3ec6SMatthias Ringwald * from this software without specific prior written permission. 163deb3ec6SMatthias Ringwald * 4. Any redistribution, use, or modification is done solely for 173deb3ec6SMatthias Ringwald * personal benefit and not for any commercial purpose or for 183deb3ec6SMatthias Ringwald * monetary gain. 193deb3ec6SMatthias Ringwald * 203deb3ec6SMatthias Ringwald * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS 213deb3ec6SMatthias Ringwald * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 223deb3ec6SMatthias Ringwald * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23*2fca4dadSMilanka Ringwald * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN 24*2fca4dadSMilanka Ringwald * GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 253deb3ec6SMatthias Ringwald * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 263deb3ec6SMatthias Ringwald * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 273deb3ec6SMatthias Ringwald * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 283deb3ec6SMatthias Ringwald * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 293deb3ec6SMatthias Ringwald * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 303deb3ec6SMatthias Ringwald * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 313deb3ec6SMatthias Ringwald * SUCH DAMAGE. 323deb3ec6SMatthias Ringwald * 333deb3ec6SMatthias Ringwald * Please inquire about commercial licensing options at 343deb3ec6SMatthias Ringwald * [email protected] 353deb3ec6SMatthias Ringwald * 363deb3ec6SMatthias Ringwald */ 373deb3ec6SMatthias Ringwald 38e501bae0SMatthias Ringwald #define BTSTACK_FILE__ "pan.c" 39ab2c6ae4SMatthias Ringwald 403deb3ec6SMatthias Ringwald /* 413deb3ec6SMatthias Ringwald * pan.h 423deb3ec6SMatthias Ringwald * 433deb3ec6SMatthias Ringwald * Created by Milanka Ringwald on 10/16/14. 443deb3ec6SMatthias Ringwald */ 453deb3ec6SMatthias Ringwald 463deb3ec6SMatthias Ringwald #include "pan.h" 473deb3ec6SMatthias Ringwald 483deb3ec6SMatthias Ringwald #include <string.h> 493deb3ec6SMatthias Ringwald 5084e3541eSMilanka Ringwald #include "bluetooth_psm.h" 51235946f1SMatthias Ringwald #include "bluetooth_sdp.h" 527907f069SMatthias Ringwald #include "btstack_config.h" 5359c6af15SMatthias Ringwald #include "classic/core.h" 543edc84c5SMatthias Ringwald #include "classic/sdp_util.h" 5584e3541eSMilanka Ringwald #include "l2cap.h" 563deb3ec6SMatthias Ringwald 5741fcd84fSMatthias Ringwald static const char pan_default_panu_service_name[] = "Personal Ad-hoc User Service"; 5841fcd84fSMatthias Ringwald static const char pan_default_panu_service_desc[] = "Personal Ad-hoc User Service"; 593deb3ec6SMatthias Ringwald 6041fcd84fSMatthias Ringwald static const char pan_default_nap_service_name[] = "Network Access Point Service"; 6141fcd84fSMatthias Ringwald static const char pan_default_nap_service_desc[] = "Personal Ad-hoc Network Service which provides access to a network"; 623deb3ec6SMatthias Ringwald 6341fcd84fSMatthias Ringwald static const char pan_default_gn_service_name[] = "Group Ad-hoc Network Service"; 6441fcd84fSMatthias Ringwald static const char pan_default_gn_service_desc[] = "Personal Group Ad-hoc Network Service"; 653deb3ec6SMatthias Ringwald 66106e8b67SMatthias Ringwald static void pan_create_service(uint8_t *service, uint32_t service_record_handle, 67106e8b67SMatthias Ringwald uint32_t service_uuid, uint16_t * network_packet_types, const char *name, const char *descriptor, 683deb3ec6SMatthias Ringwald security_description_t security_desc, net_access_type_t net_access_type, uint32_t max_net_access_rate, 693deb3ec6SMatthias Ringwald const char *IPv4Subnet, const char *IPv6Subnet){ 703deb3ec6SMatthias Ringwald 713deb3ec6SMatthias Ringwald uint8_t* attribute; 723deb3ec6SMatthias Ringwald de_create_sequence(service); 733deb3ec6SMatthias Ringwald 743deb3ec6SMatthias Ringwald // 0x0000 "Service Record Handle" 75235946f1SMatthias Ringwald de_add_number(service, DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_SERVICE_RECORD_HANDLE); 769b1c3b4dSMatthias Ringwald de_add_number(service, DE_UINT, DE_SIZE_32, service_record_handle); 773deb3ec6SMatthias Ringwald 783deb3ec6SMatthias Ringwald // 0x0001 "Service Class ID List" 79235946f1SMatthias Ringwald de_add_number(service, DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_SERVICE_CLASS_ID_LIST); 803deb3ec6SMatthias Ringwald attribute = de_push_sequence(service); 813deb3ec6SMatthias Ringwald { 823deb3ec6SMatthias Ringwald // "UUID for PAN Service" 833deb3ec6SMatthias Ringwald de_add_number(attribute, DE_UUID, DE_SIZE_32, service_uuid); 843deb3ec6SMatthias Ringwald } 853deb3ec6SMatthias Ringwald de_pop_sequence(service, attribute); 863deb3ec6SMatthias Ringwald 873deb3ec6SMatthias Ringwald // 0x0004 "Protocol Descriptor List" 88235946f1SMatthias Ringwald de_add_number(service, DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_PROTOCOL_DESCRIPTOR_LIST); 893deb3ec6SMatthias Ringwald attribute = de_push_sequence(service); 903deb3ec6SMatthias Ringwald { 913deb3ec6SMatthias Ringwald uint8_t* l2cpProtocol = de_push_sequence(attribute); 923deb3ec6SMatthias Ringwald { 93235946f1SMatthias Ringwald de_add_number(l2cpProtocol, DE_UUID, DE_SIZE_16, BLUETOOTH_PROTOCOL_L2CAP); 9484e3541eSMilanka Ringwald de_add_number(l2cpProtocol, DE_UINT, DE_SIZE_16, BLUETOOTH_PSM_BNEP); // l2cap psm 953deb3ec6SMatthias Ringwald } 963deb3ec6SMatthias Ringwald de_pop_sequence(attribute, l2cpProtocol); 973deb3ec6SMatthias Ringwald 983deb3ec6SMatthias Ringwald uint8_t* bnep = de_push_sequence(attribute); 993deb3ec6SMatthias Ringwald { 100235946f1SMatthias Ringwald de_add_number(bnep, DE_UUID, DE_SIZE_16, BLUETOOTH_PROTOCOL_BNEP); 1013deb3ec6SMatthias Ringwald de_add_number(bnep, DE_UINT, DE_SIZE_16, 0x0100); // version 1023deb3ec6SMatthias Ringwald 1033deb3ec6SMatthias Ringwald uint8_t * net_packet_type_list = de_push_sequence(bnep); 1043deb3ec6SMatthias Ringwald { 1053deb3ec6SMatthias Ringwald if (network_packet_types){ 1063deb3ec6SMatthias Ringwald while (*network_packet_types){ 1073deb3ec6SMatthias Ringwald de_add_number(net_packet_type_list, DE_UINT, DE_SIZE_16, *network_packet_types++); 1083deb3ec6SMatthias Ringwald } 1093deb3ec6SMatthias Ringwald } 1103deb3ec6SMatthias Ringwald } 1113deb3ec6SMatthias Ringwald de_pop_sequence(bnep, net_packet_type_list); 1123deb3ec6SMatthias Ringwald } 1133deb3ec6SMatthias Ringwald de_pop_sequence(attribute, bnep); 1143deb3ec6SMatthias Ringwald } 1153deb3ec6SMatthias Ringwald de_pop_sequence(service, attribute); 1163deb3ec6SMatthias Ringwald 1173deb3ec6SMatthias Ringwald // 0x0005 "Public Browse Group" 118235946f1SMatthias Ringwald de_add_number(service, DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_BROWSE_GROUP_LIST); // public browse group 1193deb3ec6SMatthias Ringwald attribute = de_push_sequence(service); 1203deb3ec6SMatthias Ringwald { 121235946f1SMatthias Ringwald de_add_number(attribute, DE_UUID, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_PUBLIC_BROWSE_ROOT); 1223deb3ec6SMatthias Ringwald } 1233deb3ec6SMatthias Ringwald de_pop_sequence(service, attribute); 1243deb3ec6SMatthias Ringwald 1253deb3ec6SMatthias Ringwald // 0x0006 "LanguageBaseAttributeIDList" 126235946f1SMatthias Ringwald de_add_number(service, DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_LANGUAGE_BASE_ATTRIBUTE_ID_LIST); 1273deb3ec6SMatthias Ringwald attribute = de_push_sequence(service); 1283deb3ec6SMatthias Ringwald { 1293deb3ec6SMatthias Ringwald de_add_number(attribute, DE_UINT, DE_SIZE_16, 0x656e); 1303deb3ec6SMatthias Ringwald de_add_number(attribute, DE_UINT, DE_SIZE_16, 0x006a); 1313deb3ec6SMatthias Ringwald de_add_number(attribute, DE_UINT, DE_SIZE_16, 0x0100); // Base for Service Name and Service Description 1323deb3ec6SMatthias Ringwald } 1333deb3ec6SMatthias Ringwald de_pop_sequence(service, attribute); 1343deb3ec6SMatthias Ringwald 1353deb3ec6SMatthias Ringwald // 0x0008 "Service Availability", optional 1363deb3ec6SMatthias Ringwald // de_add_number(service, DE_UINT, DE_SIZE_16, 0x0008); 1373deb3ec6SMatthias Ringwald // de_add_number(service, DE_UINT, DE_SIZE_8, service_availability); 1383deb3ec6SMatthias Ringwald 1393deb3ec6SMatthias Ringwald // 0x0009 "Bluetooth Profile Descriptor List" 140235946f1SMatthias Ringwald de_add_number(service, DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_BLUETOOTH_PROFILE_DESCRIPTOR_LIST); 1413deb3ec6SMatthias Ringwald attribute = de_push_sequence(service); 1423deb3ec6SMatthias Ringwald { 1433deb3ec6SMatthias Ringwald uint8_t *sppProfile = de_push_sequence(attribute); 1443deb3ec6SMatthias Ringwald { 1453deb3ec6SMatthias Ringwald de_add_number(sppProfile, DE_UUID, DE_SIZE_16, service_uuid); 1463deb3ec6SMatthias Ringwald de_add_number(sppProfile, DE_UINT, DE_SIZE_16, 0x0100); // Verision 1.0 1473deb3ec6SMatthias Ringwald } 1483deb3ec6SMatthias Ringwald de_pop_sequence(attribute, sppProfile); 1493deb3ec6SMatthias Ringwald } 1503deb3ec6SMatthias Ringwald de_pop_sequence(service, attribute); 1513deb3ec6SMatthias Ringwald 1523deb3ec6SMatthias Ringwald // 0x0100 "Service Name" 1533deb3ec6SMatthias Ringwald de_add_number(service, DE_UINT, DE_SIZE_16, 0x0100); 1543deb3ec6SMatthias Ringwald if (name){ 1553deb3ec6SMatthias Ringwald de_add_data(service, DE_STRING, strlen(name), (uint8_t *) name); 1563deb3ec6SMatthias Ringwald } else { 1573deb3ec6SMatthias Ringwald switch (service_uuid){ 158235946f1SMatthias Ringwald case BLUETOOTH_SERVICE_CLASS_PANU: 15941fcd84fSMatthias Ringwald de_add_data(service, DE_STRING, strlen(pan_default_panu_service_name), (uint8_t *) pan_default_panu_service_name); 1603deb3ec6SMatthias Ringwald break; 161235946f1SMatthias Ringwald case BLUETOOTH_SERVICE_CLASS_NAP: 16241fcd84fSMatthias Ringwald de_add_data(service, DE_STRING, strlen(pan_default_nap_service_name), (uint8_t *) pan_default_nap_service_name); 1633deb3ec6SMatthias Ringwald break; 164235946f1SMatthias Ringwald case BLUETOOTH_SERVICE_CLASS_GN: 16541fcd84fSMatthias Ringwald de_add_data(service, DE_STRING, strlen(pan_default_gn_service_name), (uint8_t *) pan_default_gn_service_name); 1663deb3ec6SMatthias Ringwald break; 1673deb3ec6SMatthias Ringwald default: 1683deb3ec6SMatthias Ringwald break; 1693deb3ec6SMatthias Ringwald } 1703deb3ec6SMatthias Ringwald } 1713deb3ec6SMatthias Ringwald 1723deb3ec6SMatthias Ringwald // 0x0101 "Service Description" 1733deb3ec6SMatthias Ringwald de_add_number(service, DE_UINT, DE_SIZE_16, 0x0101); 1743deb3ec6SMatthias Ringwald if (descriptor){ 1753deb3ec6SMatthias Ringwald de_add_data(service, DE_STRING, strlen(descriptor), (uint8_t *) descriptor); 1763deb3ec6SMatthias Ringwald } else { 1773deb3ec6SMatthias Ringwald switch (service_uuid){ 178235946f1SMatthias Ringwald case BLUETOOTH_SERVICE_CLASS_PANU: 17941fcd84fSMatthias Ringwald de_add_data(service, DE_STRING, strlen(pan_default_panu_service_desc), (uint8_t *) pan_default_panu_service_desc); 1803deb3ec6SMatthias Ringwald break; 181235946f1SMatthias Ringwald case BLUETOOTH_SERVICE_CLASS_NAP: 18241fcd84fSMatthias Ringwald de_add_data(service, DE_STRING, strlen(pan_default_nap_service_desc), (uint8_t *) pan_default_nap_service_desc); 1833deb3ec6SMatthias Ringwald break; 184235946f1SMatthias Ringwald case BLUETOOTH_SERVICE_CLASS_GN: 18541fcd84fSMatthias Ringwald de_add_data(service, DE_STRING, strlen(pan_default_gn_service_desc), (uint8_t *) pan_default_gn_service_desc); 1863deb3ec6SMatthias Ringwald break; 1873deb3ec6SMatthias Ringwald default: 1883deb3ec6SMatthias Ringwald break; 1893deb3ec6SMatthias Ringwald } 1903deb3ec6SMatthias Ringwald } 1913deb3ec6SMatthias Ringwald 1923deb3ec6SMatthias Ringwald // 0x030A "Security Description" 1933deb3ec6SMatthias Ringwald de_add_number(service, DE_UINT, DE_SIZE_16, 0x030A); 1943deb3ec6SMatthias Ringwald de_add_number(service, DE_UINT, DE_SIZE_16, security_desc); 1953deb3ec6SMatthias Ringwald 196235946f1SMatthias Ringwald if (service_uuid == BLUETOOTH_SERVICE_CLASS_PANU) return; 1973deb3ec6SMatthias Ringwald 1983deb3ec6SMatthias Ringwald if (IPv4Subnet){ 1993deb3ec6SMatthias Ringwald // 0x030D "IPv4Subnet", optional 2003deb3ec6SMatthias Ringwald de_add_number(service, DE_UINT, DE_SIZE_16, 0x030D); 2013deb3ec6SMatthias Ringwald de_add_data(service, DE_STRING, strlen(IPv4Subnet), (uint8_t *) IPv4Subnet); 2023deb3ec6SMatthias Ringwald } 2033deb3ec6SMatthias Ringwald 2043deb3ec6SMatthias Ringwald if (IPv6Subnet){ 2053deb3ec6SMatthias Ringwald // 0x030E "IPv6Subnet", optional 2063deb3ec6SMatthias Ringwald de_add_number(service, DE_UINT, DE_SIZE_16, 0x030E); 2073deb3ec6SMatthias Ringwald de_add_data(service, DE_STRING, strlen(IPv6Subnet), (uint8_t *) IPv6Subnet); 2083deb3ec6SMatthias Ringwald } 2093deb3ec6SMatthias Ringwald 210235946f1SMatthias Ringwald if (service_uuid == BLUETOOTH_SERVICE_CLASS_GN) return; 2113deb3ec6SMatthias Ringwald 2123deb3ec6SMatthias Ringwald // 0x030B "NetAccessType" 2133deb3ec6SMatthias Ringwald de_add_number(service, DE_UINT, DE_SIZE_16, 0x030B); 2143deb3ec6SMatthias Ringwald de_add_number(service, DE_UINT, DE_SIZE_16, net_access_type); 2153deb3ec6SMatthias Ringwald 2163deb3ec6SMatthias Ringwald // 0x030C "MaxNetAccessRate" 2173deb3ec6SMatthias Ringwald de_add_number(service, DE_UINT, DE_SIZE_16, 0x030C); 2183deb3ec6SMatthias Ringwald de_add_number(service, DE_UINT, DE_SIZE_32, max_net_access_rate); 2193deb3ec6SMatthias Ringwald 2203deb3ec6SMatthias Ringwald } 2213deb3ec6SMatthias Ringwald 2223deb3ec6SMatthias Ringwald 223a3bf6c7bSMatthias Ringwald void pan_create_nap_sdp_record(uint8_t *service, uint32_t service_record_handle, uint16_t * network_packet_types, const char *name, const char *description, security_description_t security_desc, 2243deb3ec6SMatthias Ringwald net_access_type_t net_access_type, uint32_t max_net_access_rate, const char *IPv4Subnet, const char *IPv6Subnet){ 2253deb3ec6SMatthias Ringwald 226235946f1SMatthias Ringwald pan_create_service(service, service_record_handle, BLUETOOTH_SERVICE_CLASS_NAP, network_packet_types, name, description, security_desc, net_access_type, max_net_access_rate, IPv4Subnet, IPv6Subnet); 2273deb3ec6SMatthias Ringwald } 2283deb3ec6SMatthias Ringwald 2290b91a77fSMatthias Ringwald void pan_create_gn_sdp_record(uint8_t *service, uint32_t service_record_handle, uint16_t * network_packet_types, const char *name, const char *description, security_description_t security_desc, 2303deb3ec6SMatthias Ringwald const char *IPv4Subnet, const char *IPv6Subnet){ 231235946f1SMatthias Ringwald pan_create_service(service, service_record_handle, BLUETOOTH_SERVICE_CLASS_GN, network_packet_types, name, description, security_desc, PAN_NET_ACCESS_TYPE_NONE, 0, IPv4Subnet, IPv6Subnet); 2323deb3ec6SMatthias Ringwald } 2333deb3ec6SMatthias Ringwald 234a3bf6c7bSMatthias Ringwald void pan_create_panu_sdp_record(uint8_t *service, uint32_t service_record_handle, uint16_t * network_packet_types, const char *name, const char *description, security_description_t security_desc){ 235235946f1SMatthias Ringwald pan_create_service(service, service_record_handle, BLUETOOTH_SERVICE_CLASS_PANU, network_packet_types, name, description, security_desc, PAN_NET_ACCESS_TYPE_NONE, 0, NULL, NULL); 2363deb3ec6SMatthias Ringwald } 237