xref: /btstack/src/classic/a2dp_source.c (revision 274391e8b2f0d74a87eb98f291f95ef8eb95044e)
1 
2 /*
3  * Copyright (C) 2016 BlueKitchen GmbH
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. Neither the name of the copyright holders nor the names of
15  *    contributors may be used to endorse or promote products derived
16  *    from this software without specific prior written permission.
17  * 4. Any redistribution, use, or modification is done solely for
18  *    personal benefit and not for any commercial purpose or for
19  *    monetary gain.
20  *
21  * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
22  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS
25  * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
28  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
31  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  *
34  * Please inquire about commercial licensing options at
35  * [email protected]
36  *
37  */
38 
39 #define __BTSTACK_FILE__ "a2dp_source.c"
40 
41 #include <stdint.h>
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <string.h>
45 #include <unistd.h>
46 
47 #include "btstack.h"
48 #include "avdtp.h"
49 #include "avdtp_util.h"
50 #include "avdtp_source.h"
51 #include "a2dp_source.h"
52 
53 static const char * default_a2dp_source_service_name = "BTstack A2DP Source Service";
54 static const char * default_a2dp_source_service_provider_name = "BTstack A2DP Source Service Provider";
55 static avdtp_context_t a2dp_source_context;
56 
57 // static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
58 
59 void a2dp_source_create_sdp_record(uint8_t * service, uint32_t service_record_handle, uint16_t supported_features, const char * service_name, const char * service_provider_name){
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         de_add_number(attribute, DE_UUID, DE_SIZE_16, BLUETOOTH_SERVICE_CLASS_AUDIO_SOURCE);
72     }
73     de_pop_sequence(service, attribute);
74 
75     // 0x0004 "Protocol Descriptor List"
76     de_add_number(service,  DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_PROTOCOL_DESCRIPTOR_LIST);
77     attribute = de_push_sequence(service);
78     {
79         uint8_t* l2cpProtocol = de_push_sequence(attribute);
80         {
81             de_add_number(l2cpProtocol,  DE_UUID, DE_SIZE_16, BLUETOOTH_PROTOCOL_L2CAP);
82             de_add_number(l2cpProtocol,  DE_UINT, DE_SIZE_16, BLUETOOTH_PROTOCOL_AVDTP);
83         }
84         de_pop_sequence(attribute, l2cpProtocol);
85 
86         uint8_t* avProtocol = de_push_sequence(attribute);
87         {
88             de_add_number(avProtocol,  DE_UUID, DE_SIZE_16, BLUETOOTH_PROTOCOL_AVDTP);  // avProtocol_service
89             de_add_number(avProtocol,  DE_UINT, DE_SIZE_16,  0x0103);  // version
90         }
91         de_pop_sequence(attribute, avProtocol);
92     }
93     de_pop_sequence(service, attribute);
94 
95     // 0x0005 "Public Browse Group"
96     de_add_number(service,  DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_BROWSE_GROUP_LIST); // public browse group
97     attribute = de_push_sequence(service);
98     {
99         de_add_number(attribute,  DE_UUID, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_PUBLIC_BROWSE_ROOT);
100     }
101     de_pop_sequence(service, attribute);
102 
103     // 0x0009 "Bluetooth Profile Descriptor List"
104     de_add_number(service,  DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_BLUETOOTH_PROFILE_DESCRIPTOR_LIST);
105     attribute = de_push_sequence(service);
106     {
107         uint8_t *a2dProfile = de_push_sequence(attribute);
108         {
109             de_add_number(a2dProfile,  DE_UUID, DE_SIZE_16, BLUETOOTH_SERVICE_CLASS_ADVANCED_AUDIO_DISTRIBUTION);
110             de_add_number(a2dProfile,  DE_UINT, DE_SIZE_16, 0x0103);
111         }
112         de_pop_sequence(attribute, a2dProfile);
113     }
114     de_pop_sequence(service, attribute);
115 
116 
117     // 0x0100 "Service Name"
118     de_add_number(service,  DE_UINT, DE_SIZE_16, 0x0100);
119     if (service_name){
120         de_add_data(service,  DE_STRING, strlen(service_name), (uint8_t *) service_name);
121     } else {
122         de_add_data(service,  DE_STRING, strlen(default_a2dp_source_service_name), (uint8_t *) default_a2dp_source_service_name);
123     }
124 
125     // 0x0100 "Provider Name"
126     de_add_number(service,  DE_UINT, DE_SIZE_16, 0x0102);
127     if (service_provider_name){
128         de_add_data(service,  DE_STRING, strlen(service_provider_name), (uint8_t *) service_provider_name);
129     } else {
130         de_add_data(service,  DE_STRING, strlen(default_a2dp_source_service_provider_name), (uint8_t *) default_a2dp_source_service_provider_name);
131     }
132 
133     // 0x0311 "Supported Features"
134     de_add_number(service, DE_UINT, DE_SIZE_16, 0x0311);
135     de_add_number(service, DE_UINT, DE_SIZE_16, supported_features);
136 }
137 
138 // static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
139 //     UNUSED(channel);
140 //     UNUSED(size);
141 //     UNUSED(packet_type);
142 //     UNUSED(packet);
143 
144 // }
145 
146 void a2dp_source_register_packet_handler(btstack_packet_handler_t callback){
147     if (callback == NULL){
148         log_error("a2dp_source_register_packet_handler called with NULL callback");
149         return;
150     }
151     avdtp_source_register_packet_handler(callback);
152     a2dp_source_context.a2dp_callback = callback;
153 }
154 
155 void a2dp_source_init(void){
156     avdtp_source_init(&a2dp_source_context);
157     // l2cap_register_service(&packet_handler, BLUETOOTH_PROTOCOL_AVDTP, 0xffff, LEVEL_0);
158 }
159 
160 avdtp_stream_endpoint_t * a2dp_source_create_stream_endpoint(avdtp_media_type_t media_type, avdtp_media_codec_type_t media_codec_type, uint8_t * media_codec_info, uint16_t media_codec_info_len){
161     avdtp_stream_endpoint_t * local_stream_endpoint = avdtp_source_create_stream_endpoint(AVDTP_SOURCE, media_type);
162     avdtp_source_register_media_transport_category(avdtp_stream_endpoint_seid(local_stream_endpoint));
163     avdtp_source_register_media_codec_category(avdtp_stream_endpoint_seid(local_stream_endpoint), media_type, media_codec_type, media_codec_info, media_codec_info_len);
164     return local_stream_endpoint;
165 }
166