xref: /btstack/src/classic/pan.c (revision 293fd5fb21e86fbb29e9789cc0a2c06dafbbf1b3)
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 MATTHIAS
24  * RINGWALD 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__ "pan.c"
39 
40 /*
41  *  pan.h
42  *
43  *  Created by Milanka Ringwald on 10/16/14.
44  */
45 
46 #include "pan.h"
47 
48 #include <stdio.h>
49 #include <string.h>
50 
51 #include "bluetooth_psm.h"
52 #include "bluetooth_sdp.h"
53 #include "btstack_config.h"
54 #include "classic/core.h"
55 #include "classic/sdp_util.h"
56 #include "l2cap.h"
57 
58 static const char default_panu_service_name[] = "Personal Ad-hoc User Service";
59 static const char default_panu_service_desc[] = "Personal Ad-hoc User Service";
60 
61 static const char default_nap_service_name[] = "Network Access Point Service";
62 static const char default_nap_service_desc[] = "Personal Ad-hoc Network Service which provides access to a network";
63 
64 static const char default_gn_service_name[] = "Group Ad-hoc Network Service";
65 static const char default_gn_service_desc[] = "Personal Group Ad-hoc Network Service";
66 
67 static void pan_create_service(uint8_t *service, uint32_t service_record_handle,
68 	 uint32_t service_uuid, uint16_t * network_packet_types, const char *name, const char *descriptor,
69 	 security_description_t security_desc, net_access_type_t net_access_type, uint32_t max_net_access_rate,
70 	 const char *IPv4Subnet, const char *IPv6Subnet){
71 
72 	uint8_t* attribute;
73 	de_create_sequence(service);
74 
75 	// 0x0000 "Service Record Handle"
76 	de_add_number(service, DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_SERVICE_RECORD_HANDLE);
77 	de_add_number(service, DE_UINT, DE_SIZE_32, service_record_handle);
78 
79 	// 0x0001 "Service Class ID List"
80 	de_add_number(service,  DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_SERVICE_CLASS_ID_LIST);
81 	attribute = de_push_sequence(service);
82 	{
83 		//  "UUID for PAN Service"
84 		de_add_number(attribute, DE_UUID, DE_SIZE_32, service_uuid);
85 	}
86 	de_pop_sequence(service, attribute);
87 
88 	// 0x0004 "Protocol Descriptor List"
89 	de_add_number(service,  DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_PROTOCOL_DESCRIPTOR_LIST);
90 	attribute = de_push_sequence(service);
91 	{
92 		uint8_t* l2cpProtocol = de_push_sequence(attribute);
93 		{
94 			de_add_number(l2cpProtocol,  DE_UUID, DE_SIZE_16, BLUETOOTH_PROTOCOL_L2CAP);
95 			de_add_number(l2cpProtocol,  DE_UINT, DE_SIZE_16, BLUETOOTH_PSM_BNEP);  // l2cap psm
96 		}
97 		de_pop_sequence(attribute, l2cpProtocol);
98 
99 		uint8_t* bnep = de_push_sequence(attribute);
100 		{
101 			de_add_number(bnep,  DE_UUID, DE_SIZE_16, BLUETOOTH_PROTOCOL_BNEP);
102 			de_add_number(bnep,  DE_UINT, DE_SIZE_16, 0x0100);  // version
103 
104 			uint8_t * net_packet_type_list = de_push_sequence(bnep);
105 			{
106 				if (network_packet_types){
107 					while (*network_packet_types){
108 						de_add_number(net_packet_type_list,  DE_UINT, DE_SIZE_16, *network_packet_types++);
109 					}
110 				}
111 			}
112 			de_pop_sequence(bnep, net_packet_type_list);
113 		}
114 		de_pop_sequence(attribute, bnep);
115 	}
116 	de_pop_sequence(service, attribute);
117 
118 	// 0x0005 "Public Browse Group"
119 	de_add_number(service,  DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_BROWSE_GROUP_LIST); // public browse group
120 	attribute = de_push_sequence(service);
121 	{
122 		de_add_number(attribute,  DE_UUID, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_PUBLIC_BROWSE_ROOT);
123 	}
124 	de_pop_sequence(service, attribute);
125 
126 	// 0x0006 "LanguageBaseAttributeIDList"
127 	de_add_number(service,  DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_LANGUAGE_BASE_ATTRIBUTE_ID_LIST);
128 	attribute = de_push_sequence(service);
129 	{
130 		de_add_number(attribute, DE_UINT, DE_SIZE_16, 0x656e);
131 		de_add_number(attribute, DE_UINT, DE_SIZE_16, 0x006a);
132 		de_add_number(attribute, DE_UINT, DE_SIZE_16, 0x0100);	// Base for Service Name and Service Description
133 	}
134 	de_pop_sequence(service, attribute);
135 
136 	// 0x0008 "Service Availability", optional
137 	// de_add_number(service, DE_UINT, DE_SIZE_16, 0x0008);
138 	// de_add_number(service, DE_UINT, DE_SIZE_8, service_availability);
139 
140 	// 0x0009 "Bluetooth Profile Descriptor List"
141 	de_add_number(service,  DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_BLUETOOTH_PROFILE_DESCRIPTOR_LIST);
142 	attribute = de_push_sequence(service);
143 	{
144 		uint8_t *sppProfile = de_push_sequence(attribute);
145 		{
146 			de_add_number(sppProfile,  DE_UUID, DE_SIZE_16, service_uuid);
147 			de_add_number(sppProfile,  DE_UINT, DE_SIZE_16, 0x0100); // Verision 1.0
148 		}
149 		de_pop_sequence(attribute, sppProfile);
150 	}
151 	de_pop_sequence(service, attribute);
152 
153 	// 0x0100 "Service Name"
154 	de_add_number(service,  DE_UINT, DE_SIZE_16, 0x0100);
155 	if (name){
156 		de_add_data(service,  DE_STRING, strlen(name), (uint8_t *) name);
157 	} else {
158 		switch (service_uuid){
159 			case BLUETOOTH_SERVICE_CLASS_PANU:
160 				de_add_data(service,  DE_STRING, strlen(default_panu_service_name), (uint8_t *) default_panu_service_name);
161 				break;
162 			case BLUETOOTH_SERVICE_CLASS_NAP:
163 				de_add_data(service,  DE_STRING, strlen(default_nap_service_name), (uint8_t *) default_nap_service_name);
164 				break;
165 			case BLUETOOTH_SERVICE_CLASS_GN:
166 				de_add_data(service,  DE_STRING, strlen(default_gn_service_name), (uint8_t *) default_gn_service_name);
167 				break;
168 			default:
169 				break;
170 		}
171 	}
172 
173 	// 0x0101 "Service Description"
174 	de_add_number(service,  DE_UINT, DE_SIZE_16, 0x0101);
175 	if (descriptor){
176 		de_add_data(service,  DE_STRING, strlen(descriptor), (uint8_t *) descriptor);
177 	} else {
178 		switch (service_uuid){
179 			case BLUETOOTH_SERVICE_CLASS_PANU:
180 				de_add_data(service,  DE_STRING, strlen(default_panu_service_desc), (uint8_t *) default_panu_service_desc);
181 				break;
182 			case BLUETOOTH_SERVICE_CLASS_NAP:
183 				de_add_data(service,  DE_STRING, strlen(default_nap_service_desc), (uint8_t *) default_nap_service_desc);
184 				break;
185 			case BLUETOOTH_SERVICE_CLASS_GN:
186 				de_add_data(service,  DE_STRING, strlen(default_gn_service_desc), (uint8_t *) default_gn_service_desc);
187 				break;
188 			default:
189 				break;
190 		}
191 	}
192 
193 	// 0x030A "Security Description"
194 	de_add_number(service, DE_UINT, DE_SIZE_16, 0x030A);
195 	de_add_number(service, DE_UINT, DE_SIZE_16, security_desc);
196 
197 	if (service_uuid == BLUETOOTH_SERVICE_CLASS_PANU) return;
198 
199 	if (IPv4Subnet){
200 		// 0x030D "IPv4Subnet", optional
201 		de_add_number(service,  DE_UINT, DE_SIZE_16, 0x030D);
202 		de_add_data(service,  DE_STRING, strlen(IPv4Subnet), (uint8_t *) IPv4Subnet);
203 	}
204 
205 	if (IPv6Subnet){
206 		// 0x030E "IPv6Subnet", optional
207 		de_add_number(service,  DE_UINT, DE_SIZE_16, 0x030E);
208 		de_add_data(service,  DE_STRING, strlen(IPv6Subnet), (uint8_t *) IPv6Subnet);
209 	}
210 
211 	if (service_uuid == BLUETOOTH_SERVICE_CLASS_GN) return;
212 
213 	// 0x030B "NetAccessType"
214 	de_add_number(service, DE_UINT, DE_SIZE_16, 0x030B);
215 	de_add_number(service, DE_UINT, DE_SIZE_16, net_access_type);
216 
217 	// 0x030C "MaxNetAccessRate"
218 	de_add_number(service, DE_UINT, DE_SIZE_16, 0x030C);
219 	de_add_number(service, DE_UINT, DE_SIZE_32, max_net_access_rate);
220 
221 }
222 
223 
224 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,
225 	net_access_type_t net_access_type, uint32_t max_net_access_rate, const char *IPv4Subnet, const char *IPv6Subnet){
226 
227 	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);
228 }
229 
230 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,
231 	const char *IPv4Subnet, const char *IPv6Subnet){
232 	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);
233 }
234 
235 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){
236 	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);
237 }
238