xref: /btstack/src/classic/spp_server.c (revision ced70f9bfeafe291ec597a3a9cc862e39e0da3ce)
1 /*
2  * Copyright (C) 2014 BlueKitchen GmbH
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the copyright holders nor the names of
14  *    contributors may be used to endorse or promote products derived
15  *    from this software without specific prior written permission.
16  * 4. Any redistribution, use, or modification is done solely for
17  *    personal benefit and not for any commercial purpose or for
18  *    monetary gain.
19  *
20  * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN
24  * GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
27  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
30  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  *
33  * Please inquire about commercial licensing options at
34  * [email protected]
35  *
36  */
37 
38 #define BTSTACK_FILE__ "spp_server.c"
39 
40 /*
41  *  spp_server.c
42  *
43  * Create SPP SDP Records
44  */
45 
46 #include "spp_server.h"
47 
48 #include <string.h>
49 
50 #include "bluetooth.h"
51 #include "bluetooth_sdp.h"
52 #include "btstack_config.h"
53 #include "classic/core.h"
54 #include "classic/sdp_util.h"
55 
56 static const char * spp_server_default_sdp_service_name = "SPP";
57 
58 static void spp_create_sdp_record_internal(uint8_t *service, uint32_t service_record_handle, const uint8_t * service_uuid128, int rfcomm_channel, const char *name){
59 
60 	uint8_t* attribute;
61 	de_create_sequence(service);
62 
63     // 0x0000 "Service Record Handle"
64 	de_add_number(service, DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_SERVICE_RECORD_HANDLE);
65 	de_add_number(service, DE_UINT, DE_SIZE_32, service_record_handle);
66 
67 	// 0x0001 "Service Class ID List"
68 	de_add_number(service,  DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_SERVICE_CLASS_ID_LIST);
69 	attribute = de_push_sequence(service);
70 	{
71 		if (service_uuid128 == NULL){
72 			de_add_number(attribute,  DE_UUID, DE_SIZE_16, BLUETOOTH_SERVICE_CLASS_SERIAL_PORT );
73 		} else {
74 			de_add_uuid128(attribute, (uint8_t *) service_uuid128);
75 		}
76 	}
77 	de_pop_sequence(service, attribute);
78 
79 	// 0x0004 "Protocol Descriptor List"
80 	de_add_number(service,  DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_PROTOCOL_DESCRIPTOR_LIST);
81 	attribute = de_push_sequence(service);
82 	{
83 		uint8_t* l2cpProtocol = de_push_sequence(attribute);
84 		{
85 			de_add_number(l2cpProtocol,  DE_UUID, DE_SIZE_16, BLUETOOTH_PROTOCOL_L2CAP);
86 		}
87 		de_pop_sequence(attribute, l2cpProtocol);
88 
89 		uint8_t* rfcomm = de_push_sequence(attribute);
90 		{
91 			de_add_number(rfcomm,  DE_UUID, DE_SIZE_16, BLUETOOTH_PROTOCOL_RFCOMM);  // rfcomm_service
92 			de_add_number(rfcomm,  DE_UINT, DE_SIZE_8,  rfcomm_channel);  // rfcomm channel
93 		}
94 		de_pop_sequence(attribute, rfcomm);
95 	}
96 	de_pop_sequence(service, attribute);
97 
98 	// 0x0005 "Public Browse Group"
99 	de_add_number(service,  DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_BROWSE_GROUP_LIST); // public browse group
100 	attribute = de_push_sequence(service);
101 	{
102 		de_add_number(attribute,  DE_UUID, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_PUBLIC_BROWSE_ROOT );
103 	}
104 	de_pop_sequence(service, attribute);
105 
106 	// 0x0006
107 	de_add_number(service,  DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_LANGUAGE_BASE_ATTRIBUTE_ID_LIST);
108 	attribute = de_push_sequence(service);
109 	{
110 		de_add_number(attribute, DE_UINT, DE_SIZE_16, 0x656e);
111 		de_add_number(attribute, DE_UINT, DE_SIZE_16, 0x006a);
112 		de_add_number(attribute, DE_UINT, DE_SIZE_16, 0x0100);
113 	}
114 	de_pop_sequence(service, attribute);
115 
116 	// 0x0009 "Bluetooth Profile Descriptor List"
117 	de_add_number(service,  DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_BLUETOOTH_PROFILE_DESCRIPTOR_LIST);
118 	attribute = de_push_sequence(service);
119 	{
120 		uint8_t *sppProfile = de_push_sequence(attribute);
121 		{
122 			de_add_number(sppProfile,  DE_UUID, DE_SIZE_16, BLUETOOTH_SERVICE_CLASS_SERIAL_PORT);
123 			de_add_number(sppProfile,  DE_UINT, DE_SIZE_16, 0x0102);
124 		}
125 		de_pop_sequence(attribute, sppProfile);
126 	}
127 	de_pop_sequence(service, attribute);
128 
129 	// 0x0100 "ServiceName"
130     if (name == NULL){
131         name = spp_server_default_sdp_service_name;
132     }
133     if (strlen(name) > 0){
134         de_add_number(service,  DE_UINT, DE_SIZE_16, 0x0100);
135         de_add_data(service,  DE_STRING, (uint16_t) strlen(name), (uint8_t *) name);
136     }
137 }
138 
139 void spp_create_sdp_record(uint8_t *service, uint32_t service_record_handle, int rfcomm_channel, const char *name){
140 	spp_create_sdp_record_internal(service, service_record_handle, NULL, rfcomm_channel, name);
141 }
142 
143 void spp_create_custom_sdp_record(uint8_t *service, uint32_t service_record_handle, const uint8_t * service_uuid128, int rfcomm_channel, const char *name){
144 	spp_create_sdp_record_internal(service, service_record_handle, service_uuid128, rfcomm_channel, name);
145 }
146