1*d40c9ac6SMatthias Ringwald /* 2*d40c9ac6SMatthias Ringwald * Copyright (C) 2014 BlueKitchen GmbH 3*d40c9ac6SMatthias Ringwald * 4*d40c9ac6SMatthias Ringwald * Redistribution and use in source and binary forms, with or without 5*d40c9ac6SMatthias Ringwald * modification, are permitted provided that the following conditions 6*d40c9ac6SMatthias Ringwald * are met: 7*d40c9ac6SMatthias Ringwald * 8*d40c9ac6SMatthias Ringwald * 1. Redistributions of source code must retain the above copyright 9*d40c9ac6SMatthias Ringwald * notice, this list of conditions and the following disclaimer. 10*d40c9ac6SMatthias Ringwald * 2. Redistributions in binary form must reproduce the above copyright 11*d40c9ac6SMatthias Ringwald * notice, this list of conditions and the following disclaimer in the 12*d40c9ac6SMatthias Ringwald * documentation and/or other materials provided with the distribution. 13*d40c9ac6SMatthias Ringwald * 3. Neither the name of the copyright holders nor the names of 14*d40c9ac6SMatthias Ringwald * contributors may be used to endorse or promote products derived 15*d40c9ac6SMatthias Ringwald * from this software without specific prior written permission. 16*d40c9ac6SMatthias Ringwald * 4. Any redistribution, use, or modification is done solely for 17*d40c9ac6SMatthias Ringwald * personal benefit and not for any commercial purpose or for 18*d40c9ac6SMatthias Ringwald * monetary gain. 19*d40c9ac6SMatthias Ringwald * 20*d40c9ac6SMatthias Ringwald * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS 21*d40c9ac6SMatthias Ringwald * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22*d40c9ac6SMatthias Ringwald * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23*d40c9ac6SMatthias Ringwald * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS 24*d40c9ac6SMatthias Ringwald * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25*d40c9ac6SMatthias Ringwald * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 26*d40c9ac6SMatthias Ringwald * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 27*d40c9ac6SMatthias Ringwald * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 28*d40c9ac6SMatthias Ringwald * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29*d40c9ac6SMatthias Ringwald * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 30*d40c9ac6SMatthias Ringwald * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31*d40c9ac6SMatthias Ringwald * SUCH DAMAGE. 32*d40c9ac6SMatthias Ringwald * 33*d40c9ac6SMatthias Ringwald * Please inquire about commercial licensing options at 34*d40c9ac6SMatthias Ringwald * [email protected] 35*d40c9ac6SMatthias Ringwald * 36*d40c9ac6SMatthias Ringwald */ 37*d40c9ac6SMatthias Ringwald 38*d40c9ac6SMatthias Ringwald #define __BTSTACK_FILE__ "hid_device.c" 39*d40c9ac6SMatthias Ringwald 40*d40c9ac6SMatthias Ringwald #include <string.h> 41*d40c9ac6SMatthias Ringwald 42*d40c9ac6SMatthias Ringwald #include "classic/hid_device.h" 43*d40c9ac6SMatthias Ringwald #include "classic/sdp_util.h" 44*d40c9ac6SMatthias Ringwald #include "bluetooth.h" 45*d40c9ac6SMatthias Ringwald #include "bluetooth_sdp.h" 46*d40c9ac6SMatthias Ringwald 47*d40c9ac6SMatthias Ringwald void hid_create_sdp_record( 48*d40c9ac6SMatthias Ringwald uint8_t *service, 49*d40c9ac6SMatthias Ringwald uint32_t service_record_handle, 50*d40c9ac6SMatthias Ringwald uint16_t hid_device_subclass, 51*d40c9ac6SMatthias Ringwald uint8_t hid_country_code, 52*d40c9ac6SMatthias Ringwald uint8_t hid_virtual_cable, 53*d40c9ac6SMatthias Ringwald uint8_t hid_reconnect_initiate, 54*d40c9ac6SMatthias Ringwald uint8_t hid_boot_device, 55*d40c9ac6SMatthias Ringwald const uint8_t * hid_descriptor, uint16_t hid_descriptor_size, 56*d40c9ac6SMatthias Ringwald const char *device_name){ 57*d40c9ac6SMatthias Ringwald 58*d40c9ac6SMatthias Ringwald uint8_t * attribute; 59*d40c9ac6SMatthias Ringwald de_create_sequence(service); 60*d40c9ac6SMatthias Ringwald 61*d40c9ac6SMatthias Ringwald de_add_number(service, DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_SERVICE_RECORD_HANDLE); 62*d40c9ac6SMatthias Ringwald de_add_number(service, DE_UINT, DE_SIZE_32, service_record_handle); 63*d40c9ac6SMatthias Ringwald 64*d40c9ac6SMatthias Ringwald de_add_number(service, DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_SERVICE_CLASS_ID_LIST); 65*d40c9ac6SMatthias Ringwald attribute = de_push_sequence(service); 66*d40c9ac6SMatthias Ringwald { 67*d40c9ac6SMatthias Ringwald de_add_number(attribute, DE_UUID, DE_SIZE_16, BLUETOOTH_SERVICE_CLASS_HUMAN_INTERFACE_DEVICE_SERVICE); 68*d40c9ac6SMatthias Ringwald } 69*d40c9ac6SMatthias Ringwald de_pop_sequence(service, attribute); 70*d40c9ac6SMatthias Ringwald 71*d40c9ac6SMatthias Ringwald de_add_number(service, DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_PROTOCOL_DESCRIPTOR_LIST); 72*d40c9ac6SMatthias Ringwald attribute = de_push_sequence(service); 73*d40c9ac6SMatthias Ringwald { 74*d40c9ac6SMatthias Ringwald uint8_t * l2cpProtocol = de_push_sequence(attribute); 75*d40c9ac6SMatthias Ringwald { 76*d40c9ac6SMatthias Ringwald de_add_number(l2cpProtocol, DE_UUID, DE_SIZE_16, BLUETOOTH_PROTOCOL_L2CAP); 77*d40c9ac6SMatthias Ringwald de_add_number(l2cpProtocol, DE_UINT, DE_SIZE_16, PSM_HID_CONTROL); 78*d40c9ac6SMatthias Ringwald } 79*d40c9ac6SMatthias Ringwald de_pop_sequence(attribute, l2cpProtocol); 80*d40c9ac6SMatthias Ringwald 81*d40c9ac6SMatthias Ringwald uint8_t * hidProtocol = de_push_sequence(attribute); 82*d40c9ac6SMatthias Ringwald { 83*d40c9ac6SMatthias Ringwald de_add_number(hidProtocol, DE_UUID, DE_SIZE_16, BLUETOOTH_PROTOCOL_HIDP); 84*d40c9ac6SMatthias Ringwald } 85*d40c9ac6SMatthias Ringwald de_pop_sequence(attribute, hidProtocol); 86*d40c9ac6SMatthias Ringwald } 87*d40c9ac6SMatthias Ringwald de_pop_sequence(service, attribute); 88*d40c9ac6SMatthias Ringwald 89*d40c9ac6SMatthias Ringwald // TODO? 90*d40c9ac6SMatthias Ringwald de_add_number(service, DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_LANGUAGE_BASE_ATTRIBUTE_ID_LIST); 91*d40c9ac6SMatthias Ringwald attribute = de_push_sequence(service); 92*d40c9ac6SMatthias Ringwald { 93*d40c9ac6SMatthias Ringwald de_add_number(attribute, DE_UINT, DE_SIZE_16, 0x656e); 94*d40c9ac6SMatthias Ringwald de_add_number(attribute, DE_UINT, DE_SIZE_16, 0x006a); 95*d40c9ac6SMatthias Ringwald de_add_number(attribute, DE_UINT, DE_SIZE_16, 0x0100); 96*d40c9ac6SMatthias Ringwald } 97*d40c9ac6SMatthias Ringwald de_pop_sequence(service, attribute); 98*d40c9ac6SMatthias Ringwald 99*d40c9ac6SMatthias Ringwald de_add_number(service, DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_ADDITIONAL_PROTOCOL_DESCRIPTOR_LISTS); 100*d40c9ac6SMatthias Ringwald attribute = de_push_sequence(service); 101*d40c9ac6SMatthias Ringwald { 102*d40c9ac6SMatthias Ringwald uint8_t * additionalDescriptorAttribute = de_push_sequence(attribute); 103*d40c9ac6SMatthias Ringwald { 104*d40c9ac6SMatthias Ringwald uint8_t * l2cpProtocol = de_push_sequence(additionalDescriptorAttribute); 105*d40c9ac6SMatthias Ringwald { 106*d40c9ac6SMatthias Ringwald de_add_number(l2cpProtocol, DE_UUID, DE_SIZE_16, BLUETOOTH_PROTOCOL_L2CAP); 107*d40c9ac6SMatthias Ringwald de_add_number(l2cpProtocol, DE_UINT, DE_SIZE_16, PSM_HID_INTERRUPT); 108*d40c9ac6SMatthias Ringwald } 109*d40c9ac6SMatthias Ringwald de_pop_sequence(additionalDescriptorAttribute, l2cpProtocol); 110*d40c9ac6SMatthias Ringwald 111*d40c9ac6SMatthias Ringwald uint8_t * hidProtocol = de_push_sequence(attribute); 112*d40c9ac6SMatthias Ringwald { 113*d40c9ac6SMatthias Ringwald de_add_number(hidProtocol, DE_UUID, DE_SIZE_16, BLUETOOTH_PROTOCOL_HIDP); 114*d40c9ac6SMatthias Ringwald } 115*d40c9ac6SMatthias Ringwald de_pop_sequence(attribute, hidProtocol); 116*d40c9ac6SMatthias Ringwald } 117*d40c9ac6SMatthias Ringwald de_pop_sequence(attribute, additionalDescriptorAttribute); 118*d40c9ac6SMatthias Ringwald } 119*d40c9ac6SMatthias Ringwald de_pop_sequence(service, attribute); 120*d40c9ac6SMatthias Ringwald 121*d40c9ac6SMatthias Ringwald // 0x0100 "ServiceName" 122*d40c9ac6SMatthias Ringwald de_add_number(service, DE_UINT, DE_SIZE_16, 0x0100); 123*d40c9ac6SMatthias Ringwald de_add_data(service, DE_STRING, strlen(device_name), (uint8_t *) device_name); 124*d40c9ac6SMatthias Ringwald 125*d40c9ac6SMatthias Ringwald de_add_number(service, DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_BLUETOOTH_PROFILE_DESCRIPTOR_LIST); 126*d40c9ac6SMatthias Ringwald attribute = de_push_sequence(service); 127*d40c9ac6SMatthias Ringwald { 128*d40c9ac6SMatthias Ringwald uint8_t * hidProfile = de_push_sequence(attribute); 129*d40c9ac6SMatthias Ringwald { 130*d40c9ac6SMatthias Ringwald de_add_number(hidProfile, DE_UUID, DE_SIZE_16, BLUETOOTH_SERVICE_CLASS_HUMAN_INTERFACE_DEVICE_SERVICE); 131*d40c9ac6SMatthias Ringwald de_add_number(hidProfile, DE_UINT, DE_SIZE_16, 0x0101); // Version 1.1 132*d40c9ac6SMatthias Ringwald } 133*d40c9ac6SMatthias Ringwald de_pop_sequence(attribute, hidProfile); 134*d40c9ac6SMatthias Ringwald } 135*d40c9ac6SMatthias Ringwald de_pop_sequence(service, attribute); 136*d40c9ac6SMatthias Ringwald 137*d40c9ac6SMatthias Ringwald // Deprecated in v1.1.1 138*d40c9ac6SMatthias Ringwald // de_add_number(service, DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_HID_DEVICE_RELEASE_NUMBER); 139*d40c9ac6SMatthias Ringwald // de_add_number(service, DE_UINT, DE_SIZE_16, 0x0101); 140*d40c9ac6SMatthias Ringwald 141*d40c9ac6SMatthias Ringwald de_add_number(service, DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_HID_PARSER_VERSION); 142*d40c9ac6SMatthias Ringwald de_add_number(service, DE_UINT, DE_SIZE_16, 0x0111); // v1.1.1 143*d40c9ac6SMatthias Ringwald 144*d40c9ac6SMatthias Ringwald de_add_number(service, DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_HID_DEVICE_SUBCLASS); 145*d40c9ac6SMatthias Ringwald de_add_number(service, DE_UINT, DE_SIZE_16, hid_device_subclass); 146*d40c9ac6SMatthias Ringwald 147*d40c9ac6SMatthias Ringwald de_add_number(service, DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_HID_COUNTRY_CODE); 148*d40c9ac6SMatthias Ringwald de_add_number(service, DE_UINT, DE_SIZE_16, hid_country_code); 149*d40c9ac6SMatthias Ringwald 150*d40c9ac6SMatthias Ringwald de_add_number(service, DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_HID_VIRTUAL_CABLE); 151*d40c9ac6SMatthias Ringwald de_add_number(service, DE_BOOL, DE_SIZE_8, hid_virtual_cable); 152*d40c9ac6SMatthias Ringwald 153*d40c9ac6SMatthias Ringwald de_add_number(service, DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_HID_RECONNECT_INITIATE); 154*d40c9ac6SMatthias Ringwald de_add_number(service, DE_BOOL, DE_SIZE_8, hid_reconnect_initiate); 155*d40c9ac6SMatthias Ringwald 156*d40c9ac6SMatthias Ringwald de_add_number(service, DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_HID_DESCRIPTOR_LIST); 157*d40c9ac6SMatthias Ringwald attribute = de_push_sequence(service); 158*d40c9ac6SMatthias Ringwald { 159*d40c9ac6SMatthias Ringwald uint8_t* hidDescriptor = de_push_sequence(attribute); 160*d40c9ac6SMatthias Ringwald { 161*d40c9ac6SMatthias Ringwald de_add_number(hidDescriptor, DE_UINT, DE_SIZE_8, 0x22); // Report Descriptor 162*d40c9ac6SMatthias Ringwald de_add_data(hidDescriptor, DE_STRING, hid_descriptor_size, (uint8_t *) hid_descriptor); 163*d40c9ac6SMatthias Ringwald } 164*d40c9ac6SMatthias Ringwald de_pop_sequence(attribute, hidDescriptor); 165*d40c9ac6SMatthias Ringwald } 166*d40c9ac6SMatthias Ringwald de_pop_sequence(service, attribute); 167*d40c9ac6SMatthias Ringwald 168*d40c9ac6SMatthias Ringwald de_add_number(service, DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_HID_BOOT_DEVICE); 169*d40c9ac6SMatthias Ringwald de_add_number(service, DE_BOOL, DE_SIZE_8, hid_boot_device); 170*d40c9ac6SMatthias Ringwald } 171