xref: /btstack/src/classic/pan.c (revision 3deb3ec68039c68a16974dffc53343233662f909)
1*3deb3ec6SMatthias Ringwald /*
2*3deb3ec6SMatthias Ringwald  * Copyright (C) 2014 BlueKitchen GmbH
3*3deb3ec6SMatthias Ringwald  *
4*3deb3ec6SMatthias Ringwald  * Redistribution and use in source and binary forms, with or without
5*3deb3ec6SMatthias Ringwald  * modification, are permitted provided that the following conditions
6*3deb3ec6SMatthias Ringwald  * are met:
7*3deb3ec6SMatthias Ringwald  *
8*3deb3ec6SMatthias Ringwald  * 1. Redistributions of source code must retain the above copyright
9*3deb3ec6SMatthias Ringwald  *    notice, this list of conditions and the following disclaimer.
10*3deb3ec6SMatthias Ringwald  * 2. Redistributions in binary form must reproduce the above copyright
11*3deb3ec6SMatthias Ringwald  *    notice, this list of conditions and the following disclaimer in the
12*3deb3ec6SMatthias Ringwald  *    documentation and/or other materials provided with the distribution.
13*3deb3ec6SMatthias Ringwald  * 3. Neither the name of the copyright holders nor the names of
14*3deb3ec6SMatthias Ringwald  *    contributors may be used to endorse or promote products derived
15*3deb3ec6SMatthias Ringwald  *    from this software without specific prior written permission.
16*3deb3ec6SMatthias Ringwald  * 4. Any redistribution, use, or modification is done solely for
17*3deb3ec6SMatthias Ringwald  *    personal benefit and not for any commercial purpose or for
18*3deb3ec6SMatthias Ringwald  *    monetary gain.
19*3deb3ec6SMatthias Ringwald  *
20*3deb3ec6SMatthias Ringwald  * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
21*3deb3ec6SMatthias Ringwald  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22*3deb3ec6SMatthias Ringwald  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23*3deb3ec6SMatthias Ringwald  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS
24*3deb3ec6SMatthias Ringwald  * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25*3deb3ec6SMatthias Ringwald  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26*3deb3ec6SMatthias Ringwald  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
27*3deb3ec6SMatthias Ringwald  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28*3deb3ec6SMatthias Ringwald  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29*3deb3ec6SMatthias Ringwald  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
30*3deb3ec6SMatthias Ringwald  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31*3deb3ec6SMatthias Ringwald  * SUCH DAMAGE.
32*3deb3ec6SMatthias Ringwald  *
33*3deb3ec6SMatthias Ringwald  * Please inquire about commercial licensing options at
34*3deb3ec6SMatthias Ringwald  * [email protected]
35*3deb3ec6SMatthias Ringwald  *
36*3deb3ec6SMatthias Ringwald  */
37*3deb3ec6SMatthias Ringwald 
38*3deb3ec6SMatthias Ringwald /*
39*3deb3ec6SMatthias Ringwald  *  pan.h
40*3deb3ec6SMatthias Ringwald  *
41*3deb3ec6SMatthias Ringwald  *  Created by Milanka Ringwald on 10/16/14.
42*3deb3ec6SMatthias Ringwald  */
43*3deb3ec6SMatthias Ringwald 
44*3deb3ec6SMatthias Ringwald #include "pan.h"
45*3deb3ec6SMatthias Ringwald 
46*3deb3ec6SMatthias Ringwald #include <stdio.h>
47*3deb3ec6SMatthias Ringwald #include <string.h>
48*3deb3ec6SMatthias Ringwald 
49*3deb3ec6SMatthias Ringwald #include "sdp_util.h"
50*3deb3ec6SMatthias Ringwald #include "hci_cmds.h"
51*3deb3ec6SMatthias Ringwald 
52*3deb3ec6SMatthias Ringwald static const char default_panu_service_name[] = "Personal Ad-hoc User Service";
53*3deb3ec6SMatthias Ringwald static const char default_panu_service_desc[] = "Personal Ad-hoc User Service";
54*3deb3ec6SMatthias Ringwald 
55*3deb3ec6SMatthias Ringwald static const char default_nap_service_name[] = "Network Access Point Service";
56*3deb3ec6SMatthias Ringwald static const char default_nap_service_desc[] = "Personal Ad-hoc Network Service which provides access to a network";
57*3deb3ec6SMatthias Ringwald 
58*3deb3ec6SMatthias Ringwald static const char default_gn_service_name[] = "Group Ad-hoc Network Service";
59*3deb3ec6SMatthias Ringwald static const char default_gn_service_desc[] = "Personal Group Ad-hoc Network Service";
60*3deb3ec6SMatthias Ringwald 
61*3deb3ec6SMatthias Ringwald static void pan_create_service(uint8_t *service, uint32_t service_uuid, uint16_t * network_packet_types, const char *name, const char *descriptor,
62*3deb3ec6SMatthias Ringwald 	 security_description_t security_desc, net_access_type_t net_access_type, uint32_t max_net_access_rate,
63*3deb3ec6SMatthias Ringwald 	 const char *IPv4Subnet, const char *IPv6Subnet){
64*3deb3ec6SMatthias Ringwald 
65*3deb3ec6SMatthias Ringwald 	uint8_t* attribute;
66*3deb3ec6SMatthias Ringwald 	de_create_sequence(service);
67*3deb3ec6SMatthias Ringwald 
68*3deb3ec6SMatthias Ringwald 	// 0x0000 "Service Record Handle"
69*3deb3ec6SMatthias Ringwald 	de_add_number(service, DE_UINT, DE_SIZE_16, SDP_ServiceRecordHandle);
70*3deb3ec6SMatthias Ringwald 	de_add_number(service, DE_UINT, DE_SIZE_32, 0x10001);
71*3deb3ec6SMatthias Ringwald 
72*3deb3ec6SMatthias Ringwald 	// 0x0001 "Service Class ID List"
73*3deb3ec6SMatthias Ringwald 	de_add_number(service,  DE_UINT, DE_SIZE_16, SDP_ServiceClassIDList);
74*3deb3ec6SMatthias Ringwald 	attribute = de_push_sequence(service);
75*3deb3ec6SMatthias Ringwald 	{
76*3deb3ec6SMatthias Ringwald 		//  "UUID for PAN Service"
77*3deb3ec6SMatthias Ringwald 		de_add_number(attribute, DE_UUID, DE_SIZE_32, service_uuid);
78*3deb3ec6SMatthias Ringwald 	}
79*3deb3ec6SMatthias Ringwald 	de_pop_sequence(service, attribute);
80*3deb3ec6SMatthias Ringwald 
81*3deb3ec6SMatthias Ringwald 	// 0x0004 "Protocol Descriptor List"
82*3deb3ec6SMatthias Ringwald 	de_add_number(service,  DE_UINT, DE_SIZE_16, SDP_ProtocolDescriptorList);
83*3deb3ec6SMatthias Ringwald 	attribute = de_push_sequence(service);
84*3deb3ec6SMatthias Ringwald 	{
85*3deb3ec6SMatthias Ringwald 		uint8_t* l2cpProtocol = de_push_sequence(attribute);
86*3deb3ec6SMatthias Ringwald 		{
87*3deb3ec6SMatthias Ringwald 			de_add_number(l2cpProtocol,  DE_UUID, DE_SIZE_16, SDP_L2CAPProtocol);
88*3deb3ec6SMatthias Ringwald 			de_add_number(l2cpProtocol,  DE_UINT, DE_SIZE_16, PSM_BNEP);  // l2cap psm
89*3deb3ec6SMatthias Ringwald 		}
90*3deb3ec6SMatthias Ringwald 		de_pop_sequence(attribute, l2cpProtocol);
91*3deb3ec6SMatthias Ringwald 
92*3deb3ec6SMatthias Ringwald 		uint8_t* bnep = de_push_sequence(attribute);
93*3deb3ec6SMatthias Ringwald 		{
94*3deb3ec6SMatthias Ringwald 			de_add_number(bnep,  DE_UUID, DE_SIZE_16, SDP_BNEPProtocol);
95*3deb3ec6SMatthias Ringwald 			de_add_number(bnep,  DE_UINT, DE_SIZE_16, 0x0100);  // version
96*3deb3ec6SMatthias Ringwald 
97*3deb3ec6SMatthias Ringwald 			uint8_t * net_packet_type_list = de_push_sequence(bnep);
98*3deb3ec6SMatthias Ringwald 			{
99*3deb3ec6SMatthias Ringwald 				if (network_packet_types){
100*3deb3ec6SMatthias Ringwald 					while (*network_packet_types){
101*3deb3ec6SMatthias Ringwald 						de_add_number(net_packet_type_list,  DE_UINT, DE_SIZE_16, *network_packet_types++);
102*3deb3ec6SMatthias Ringwald 					}
103*3deb3ec6SMatthias Ringwald 				}
104*3deb3ec6SMatthias Ringwald 			}
105*3deb3ec6SMatthias Ringwald 			de_pop_sequence(bnep, net_packet_type_list);
106*3deb3ec6SMatthias Ringwald 		}
107*3deb3ec6SMatthias Ringwald 		de_pop_sequence(attribute, bnep);
108*3deb3ec6SMatthias Ringwald 	}
109*3deb3ec6SMatthias Ringwald 	de_pop_sequence(service, attribute);
110*3deb3ec6SMatthias Ringwald 
111*3deb3ec6SMatthias Ringwald 	// 0x0005 "Public Browse Group"
112*3deb3ec6SMatthias Ringwald 	de_add_number(service,  DE_UINT, DE_SIZE_16, SDP_BrowseGroupList); // public browse group
113*3deb3ec6SMatthias Ringwald 	attribute = de_push_sequence(service);
114*3deb3ec6SMatthias Ringwald 	{
115*3deb3ec6SMatthias Ringwald 		de_add_number(attribute,  DE_UUID, DE_SIZE_16, SDP_PublicBrowseGroup);
116*3deb3ec6SMatthias Ringwald 	}
117*3deb3ec6SMatthias Ringwald 	de_pop_sequence(service, attribute);
118*3deb3ec6SMatthias Ringwald 
119*3deb3ec6SMatthias Ringwald 	// 0x0006 "LanguageBaseAttributeIDList"
120*3deb3ec6SMatthias Ringwald 	de_add_number(service,  DE_UINT, DE_SIZE_16, SDP_LanguageBaseAttributeIDList);
121*3deb3ec6SMatthias Ringwald 	attribute = de_push_sequence(service);
122*3deb3ec6SMatthias Ringwald 	{
123*3deb3ec6SMatthias Ringwald 		de_add_number(attribute, DE_UINT, DE_SIZE_16, 0x656e);
124*3deb3ec6SMatthias Ringwald 		de_add_number(attribute, DE_UINT, DE_SIZE_16, 0x006a);
125*3deb3ec6SMatthias Ringwald 		de_add_number(attribute, DE_UINT, DE_SIZE_16, 0x0100);	// Base for Service Name and Service Description
126*3deb3ec6SMatthias Ringwald 	}
127*3deb3ec6SMatthias Ringwald 	de_pop_sequence(service, attribute);
128*3deb3ec6SMatthias Ringwald 
129*3deb3ec6SMatthias Ringwald 	// 0x0008 "Service Availability", optional
130*3deb3ec6SMatthias Ringwald 	// de_add_number(service, DE_UINT, DE_SIZE_16, 0x0008);
131*3deb3ec6SMatthias Ringwald 	// de_add_number(service, DE_UINT, DE_SIZE_8, service_availability);
132*3deb3ec6SMatthias Ringwald 
133*3deb3ec6SMatthias Ringwald 	// 0x0009 "Bluetooth Profile Descriptor List"
134*3deb3ec6SMatthias Ringwald 	de_add_number(service,  DE_UINT, DE_SIZE_16, SDP_BluetoothProfileDescriptorList);
135*3deb3ec6SMatthias Ringwald 	attribute = de_push_sequence(service);
136*3deb3ec6SMatthias Ringwald 	{
137*3deb3ec6SMatthias Ringwald 		uint8_t *sppProfile = de_push_sequence(attribute);
138*3deb3ec6SMatthias Ringwald 		{
139*3deb3ec6SMatthias Ringwald 			de_add_number(sppProfile,  DE_UUID, DE_SIZE_16, service_uuid);
140*3deb3ec6SMatthias Ringwald 			de_add_number(sppProfile,  DE_UINT, DE_SIZE_16, 0x0100); // Verision 1.0
141*3deb3ec6SMatthias Ringwald 		}
142*3deb3ec6SMatthias Ringwald 		de_pop_sequence(attribute, sppProfile);
143*3deb3ec6SMatthias Ringwald 	}
144*3deb3ec6SMatthias Ringwald 	de_pop_sequence(service, attribute);
145*3deb3ec6SMatthias Ringwald 
146*3deb3ec6SMatthias Ringwald 	// 0x0100 "Service Name"
147*3deb3ec6SMatthias Ringwald 	de_add_number(service,  DE_UINT, DE_SIZE_16, 0x0100);
148*3deb3ec6SMatthias Ringwald 	if (name){
149*3deb3ec6SMatthias Ringwald 		de_add_data(service,  DE_STRING, strlen(name), (uint8_t *) name);
150*3deb3ec6SMatthias Ringwald 	} else {
151*3deb3ec6SMatthias Ringwald 		switch (service_uuid){
152*3deb3ec6SMatthias Ringwald 			case SDP_PANU:
153*3deb3ec6SMatthias Ringwald 				de_add_data(service,  DE_STRING, strlen(default_panu_service_name), (uint8_t *) default_panu_service_name);
154*3deb3ec6SMatthias Ringwald 				break;
155*3deb3ec6SMatthias Ringwald 			case SDP_NAP:
156*3deb3ec6SMatthias Ringwald 				de_add_data(service,  DE_STRING, strlen(default_nap_service_name), (uint8_t *) default_nap_service_name);
157*3deb3ec6SMatthias Ringwald 				break;
158*3deb3ec6SMatthias Ringwald 			case SDP_GN:
159*3deb3ec6SMatthias Ringwald 				de_add_data(service,  DE_STRING, strlen(default_gn_service_name), (uint8_t *) default_gn_service_name);
160*3deb3ec6SMatthias Ringwald 				break;
161*3deb3ec6SMatthias Ringwald 			default:
162*3deb3ec6SMatthias Ringwald 				break;
163*3deb3ec6SMatthias Ringwald 		}
164*3deb3ec6SMatthias Ringwald 	}
165*3deb3ec6SMatthias Ringwald 
166*3deb3ec6SMatthias Ringwald 	// 0x0101 "Service Description"
167*3deb3ec6SMatthias Ringwald 	de_add_number(service,  DE_UINT, DE_SIZE_16, 0x0101);
168*3deb3ec6SMatthias Ringwald 	if (descriptor){
169*3deb3ec6SMatthias Ringwald 		de_add_data(service,  DE_STRING, strlen(descriptor), (uint8_t *) descriptor);
170*3deb3ec6SMatthias Ringwald 	} else {
171*3deb3ec6SMatthias Ringwald 		switch (service_uuid){
172*3deb3ec6SMatthias Ringwald 			case SDP_PANU:
173*3deb3ec6SMatthias Ringwald 				de_add_data(service,  DE_STRING, strlen(default_panu_service_desc), (uint8_t *) default_panu_service_desc);
174*3deb3ec6SMatthias Ringwald 				break;
175*3deb3ec6SMatthias Ringwald 			case SDP_NAP:
176*3deb3ec6SMatthias Ringwald 				de_add_data(service,  DE_STRING, strlen(default_nap_service_desc), (uint8_t *) default_nap_service_desc);
177*3deb3ec6SMatthias Ringwald 				break;
178*3deb3ec6SMatthias Ringwald 			case SDP_GN:
179*3deb3ec6SMatthias Ringwald 				de_add_data(service,  DE_STRING, strlen(default_gn_service_desc), (uint8_t *) default_gn_service_desc);
180*3deb3ec6SMatthias Ringwald 				break;
181*3deb3ec6SMatthias Ringwald 			default:
182*3deb3ec6SMatthias Ringwald 				break;
183*3deb3ec6SMatthias Ringwald 		}
184*3deb3ec6SMatthias Ringwald 	}
185*3deb3ec6SMatthias Ringwald 
186*3deb3ec6SMatthias Ringwald 	// 0x030A "Security Description"
187*3deb3ec6SMatthias Ringwald 	de_add_number(service, DE_UINT, DE_SIZE_16, 0x030A);
188*3deb3ec6SMatthias Ringwald 	de_add_number(service, DE_UINT, DE_SIZE_16, security_desc);
189*3deb3ec6SMatthias Ringwald 
190*3deb3ec6SMatthias Ringwald 	if (service_uuid == SDP_PANU) return;
191*3deb3ec6SMatthias Ringwald 
192*3deb3ec6SMatthias Ringwald 	if (IPv4Subnet){
193*3deb3ec6SMatthias Ringwald 		// 0x030D "IPv4Subnet", optional
194*3deb3ec6SMatthias Ringwald 		de_add_number(service,  DE_UINT, DE_SIZE_16, 0x030D);
195*3deb3ec6SMatthias Ringwald 		de_add_data(service,  DE_STRING, strlen(IPv4Subnet), (uint8_t *) IPv4Subnet);
196*3deb3ec6SMatthias Ringwald 	}
197*3deb3ec6SMatthias Ringwald 
198*3deb3ec6SMatthias Ringwald 	if (IPv6Subnet){
199*3deb3ec6SMatthias Ringwald 		// 0x030E "IPv6Subnet", optional
200*3deb3ec6SMatthias Ringwald 		de_add_number(service,  DE_UINT, DE_SIZE_16, 0x030E);
201*3deb3ec6SMatthias Ringwald 		de_add_data(service,  DE_STRING, strlen(IPv6Subnet), (uint8_t *) IPv6Subnet);
202*3deb3ec6SMatthias Ringwald 	}
203*3deb3ec6SMatthias Ringwald 
204*3deb3ec6SMatthias Ringwald 	if (service_uuid == SDP_GN) return;
205*3deb3ec6SMatthias Ringwald 
206*3deb3ec6SMatthias Ringwald 	// 0x030B "NetAccessType"
207*3deb3ec6SMatthias Ringwald 	de_add_number(service, DE_UINT, DE_SIZE_16, 0x030B);
208*3deb3ec6SMatthias Ringwald 	de_add_number(service, DE_UINT, DE_SIZE_16, net_access_type);
209*3deb3ec6SMatthias Ringwald 
210*3deb3ec6SMatthias Ringwald 	// 0x030C "MaxNetAccessRate"
211*3deb3ec6SMatthias Ringwald 	de_add_number(service, DE_UINT, DE_SIZE_16, 0x030C);
212*3deb3ec6SMatthias Ringwald 	de_add_number(service, DE_UINT, DE_SIZE_32, max_net_access_rate);
213*3deb3ec6SMatthias Ringwald 
214*3deb3ec6SMatthias Ringwald }
215*3deb3ec6SMatthias Ringwald 
216*3deb3ec6SMatthias Ringwald 
217*3deb3ec6SMatthias Ringwald void pan_create_nap_service(uint8_t *service, uint16_t * network_packet_types, const char *name, const char *description, security_description_t security_desc,
218*3deb3ec6SMatthias Ringwald 	net_access_type_t net_access_type, uint32_t max_net_access_rate, const char *IPv4Subnet, const char *IPv6Subnet){
219*3deb3ec6SMatthias Ringwald 
220*3deb3ec6SMatthias Ringwald 	pan_create_service(service, SDP_NAP, network_packet_types, name, description, security_desc, net_access_type, max_net_access_rate, IPv4Subnet, IPv6Subnet);
221*3deb3ec6SMatthias Ringwald }
222*3deb3ec6SMatthias Ringwald 
223*3deb3ec6SMatthias Ringwald void pan_create_gn_service(uint8_t *service, uint16_t * network_packet_types, const char *name, const char *description, security_description_t security_desc,
224*3deb3ec6SMatthias Ringwald 	const char *IPv4Subnet, const char *IPv6Subnet){
225*3deb3ec6SMatthias Ringwald 	pan_create_service(service, SDP_GN, network_packet_types, name, description, security_desc, PAN_NET_ACCESS_TYPE_NONE, 0, IPv4Subnet, IPv6Subnet);
226*3deb3ec6SMatthias Ringwald }
227*3deb3ec6SMatthias Ringwald 
228*3deb3ec6SMatthias Ringwald void pan_create_panu_service(uint8_t *service, uint16_t * network_packet_types, const char *name, const char *description, security_description_t security_desc){
229*3deb3ec6SMatthias Ringwald 	pan_create_service(service, SDP_PANU, network_packet_types, name, description, security_desc, PAN_NET_ACCESS_TYPE_NONE, 0, NULL, NULL);
230*3deb3ec6SMatthias Ringwald }
231