xref: /btstack/src/classic/hsp_ag.c (revision c9921182ab4b1f83e3e5c671446dca5ffdf45b90)
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__ "hsp_ag.c"
39 
40 // *****************************************************************************
41 //
42 // HSP Audio Gateway
43 //
44 // *****************************************************************************
45 
46 #include "btstack_config.h"
47 
48 #include <stdint.h>
49 #include <string.h>
50 
51 #include "bluetooth_sdp.h"
52 #include "btstack_debug.h"
53 #include "btstack_event.h"
54 #include "btstack_memory.h"
55 #include "btstack_run_loop.h"
56 #include "classic/core.h"
57 #include "classic/sdp_server.h"
58 #include "classic/sdp_client_rfcomm.h"
59 #include "classic/sdp_util.h"
60 #include "hci.h"
61 #include "hci_cmd.h"
62 #include "hci_dump.h"
63 #include "hsp_ag.h"
64 #include "l2cap.h"
65 
66 #define HSP_HS_BUTTON_PRESS "AT+CKPD=200"
67 #define HSP_HS_AT_CKPD "AT+CKPD\r\n"
68 #define HSP_AG_OK "\r\nOK\r\n"
69 #define HSP_AG_ERROR "\r\nERROR\r\n"
70 #define HSP_AG_RING "\r\nRING\r\n"
71 #define HSP_MICROPHONE_GAIN "+VGM"
72 #define HSP_SPEAKER_GAIN "+VGS"
73 
74 #define HSP_HS_MICROPHONE_GAIN "AT+VGM="
75 #define HSP_HS_SPEAKER_GAIN "AT+VGS="
76 
77 static const char default_hsp_ag_service_name[] = "Audio Gateway";
78 
79 static bd_addr_t remote;
80 static uint8_t channel_nr = 0;
81 
82 static uint16_t mtu;
83 static uint16_t rfcomm_cid = 0;
84 static uint16_t sco_handle = HCI_CON_HANDLE_INVALID;
85 static uint16_t rfcomm_handle = HCI_CON_HANDLE_INVALID;
86 static btstack_timer_source_t hs_timeout;
87 
88 static int ag_microphone_gain = -1;
89 static int ag_speaker_gain = -1;
90 static uint8_t ag_ring = 0;
91 static uint8_t ag_send_ok = 0;
92 static uint8_t ag_send_error = 0;
93 static uint8_t ag_num_button_press_received = 0;
94 static uint8_t ag_support_custom_commands = 0;
95 static uint8_t hsp_disconnect_rfcomm = 0;
96 static uint8_t hsp_establish_audio_connection = 0;
97 static uint8_t hsp_release_audio_connection = 0;
98 
99 static btstack_packet_callback_registration_t hci_event_callback_registration;
100 
101 typedef enum {
102     HSP_IDLE,
103     HSP_SDP_QUERY_RFCOMM_CHANNEL,
104     HSP_W4_SDP_EVENT_QUERY_COMPLETE,
105     HSP_W4_RFCOMM_CONNECTED,
106 
107     HSP_RFCOMM_CONNECTION_ESTABLISHED,
108 
109     HSP_W4_RING_ANSWER,
110     HSP_W4_USER_ACTION,
111     HSP_W2_CONNECT_SCO,
112     HSP_W4_SCO_CONNECTED,
113 
114     HSP_AUDIO_CONNECTION_ESTABLISHED,
115 
116     HSP_W2_DISCONNECT_SCO,
117     HSP_W4_SCO_DISCONNECTED,
118 
119     HSP_W2_DISCONNECT_RFCOMM,
120     HSP_W4_RFCOMM_DISCONNECTED,
121     HSP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN
122 } hsp_state_t;
123 
124 static hsp_state_t hsp_state = HSP_IDLE;
125 
126 
127 static btstack_packet_handler_t hsp_ag_callback;
128 
129 static void hsp_run(void);
130 static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
131 static void handle_query_rfcomm_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
132 
133 static void dummy_notify(uint8_t packet_type, uint16_t channel, uint8_t * event, uint16_t size){
134     UNUSED(packet_type);    // ok: no code
135     UNUSED(channel);        // ok: no code
136     UNUSED(event);          // ok: no code
137     UNUSED(size);           // ok: no code
138 }
139 
140 void hsp_ag_register_packet_handler(btstack_packet_handler_t callback){
141     if (callback == NULL){
142         callback = &dummy_notify;
143     }
144     hsp_ag_callback = callback;
145 }
146 
147 static void emit_event(uint8_t event_subtype, uint8_t value){
148     if (!hsp_ag_callback) return;
149     uint8_t event[4];
150     event[0] = HCI_EVENT_HSP_META;
151     event[1] = sizeof(event) - 2;
152     event[2] = event_subtype;
153     event[3] = value; // status 0 == OK
154     (*hsp_ag_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
155 }
156 
157 static void emit_event_audio_connected(uint8_t status, uint16_t handle){
158     if (!hsp_ag_callback) return;
159     uint8_t event[6];
160     event[0] = HCI_EVENT_HSP_META;
161     event[1] = sizeof(event) - 2;
162     event[2] = HSP_SUBEVENT_AUDIO_CONNECTION_COMPLETE;
163     event[3] = status;
164     little_endian_store_16(event, 4, handle);
165     (*hsp_ag_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
166 }
167 
168 void hsp_ag_create_sdp_record(uint8_t * service, uint32_t service_record_handle, int rfcomm_channel_nr, const char * name){
169     uint8_t* attribute;
170     de_create_sequence(service);
171 
172     // 0x0000 "Service Record Handle"
173     de_add_number(service, DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_SERVICE_RECORD_HANDLE);
174     de_add_number(service, DE_UINT, DE_SIZE_32, service_record_handle);
175 
176     // 0x0001 "Service Class ID List"
177     de_add_number(service,  DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_SERVICE_CLASS_ID_LIST);
178     attribute = de_push_sequence(service);
179     {
180         //  "UUID for PAN Service"
181         de_add_number(attribute, DE_UUID, DE_SIZE_16, BLUETOOTH_SERVICE_CLASS_HEADSET_AUDIO_GATEWAY_AG);
182         de_add_number(attribute, DE_UUID, DE_SIZE_16, BLUETOOTH_SERVICE_CLASS_GENERIC_AUDIO);
183     }
184     de_pop_sequence(service, attribute);
185 
186     // 0x0004 "Protocol Descriptor List"
187     de_add_number(service,  DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_PROTOCOL_DESCRIPTOR_LIST);
188     attribute = de_push_sequence(service);
189     {
190         uint8_t* l2cpProtocol = de_push_sequence(attribute);
191         {
192             de_add_number(l2cpProtocol,  DE_UUID, DE_SIZE_16, BLUETOOTH_PROTOCOL_L2CAP);
193         }
194         de_pop_sequence(attribute, l2cpProtocol);
195 
196         uint8_t* rfcomm = de_push_sequence(attribute);
197         {
198             de_add_number(rfcomm,  DE_UUID, DE_SIZE_16, BLUETOOTH_PROTOCOL_RFCOMM);  // rfcomm_service
199             de_add_number(rfcomm,  DE_UINT, DE_SIZE_8,  rfcomm_channel_nr);  // rfcomm channel
200         }
201         de_pop_sequence(attribute, rfcomm);
202     }
203     de_pop_sequence(service, attribute);
204 
205     // 0x0005 "Public Browse Group"
206     de_add_number(service,  DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_BROWSE_GROUP_LIST); // public browse group
207     attribute = de_push_sequence(service);
208     {
209         de_add_number(attribute,  DE_UUID, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_PUBLIC_BROWSE_ROOT);
210     }
211     de_pop_sequence(service, attribute);
212 
213     // 0x0009 "Bluetooth Profile Descriptor List"
214     de_add_number(service,  DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_BLUETOOTH_PROFILE_DESCRIPTOR_LIST);
215     attribute = de_push_sequence(service);
216     {
217         uint8_t *sppProfile = de_push_sequence(attribute);
218         {
219             de_add_number(sppProfile,  DE_UUID, DE_SIZE_16, BLUETOOTH_SERVICE_CLASS_HEADSET);
220             de_add_number(sppProfile,  DE_UINT, DE_SIZE_16, 0x0102); // Verision 1.2
221         }
222         de_pop_sequence(attribute, sppProfile);
223     }
224     de_pop_sequence(service, attribute);
225 
226     // 0x0100 "Service Name"
227     de_add_number(service,  DE_UINT, DE_SIZE_16, 0x0100);
228     if (name){
229         de_add_data(service,  DE_STRING, strlen(name), (uint8_t *) name);
230     } else {
231         de_add_data(service,  DE_STRING, strlen(default_hsp_ag_service_name), (uint8_t *) default_hsp_ag_service_name);
232     }
233 }
234 
235 static int hsp_ag_send_str_over_rfcomm(const uint16_t cid, const char * command){
236     int err = rfcomm_send(cid, (uint8_t*) command, strlen(command));
237     if (err){
238         log_error("rfcomm_send_internal -> error 0X%02x", err);
239         return err;
240     }
241     return err;
242 }
243 
244 void hsp_ag_enable_custom_commands(int enable){
245     ag_support_custom_commands = enable;
246 }
247 
248 int hsp_ag_send_result(char * result){
249     if (!ag_support_custom_commands) return 1;
250     return hsp_ag_send_str_over_rfcomm(rfcomm_cid, result);
251 }
252 
253 static void hsp_ag_reset_state(void){
254     hsp_state = HSP_IDLE;
255 
256     rfcomm_cid = 0;
257     rfcomm_handle = HCI_CON_HANDLE_INVALID;
258     sco_handle = 0;
259 
260     ag_send_ok = 0;
261     ag_send_error = 0;
262     ag_ring = 0;
263 
264     ag_num_button_press_received = 0;
265     ag_support_custom_commands = 0;
266 
267     ag_microphone_gain = -1;
268     ag_speaker_gain = -1;
269 
270     hsp_disconnect_rfcomm = 0;
271     hsp_establish_audio_connection = 0;
272     hsp_release_audio_connection = 0;
273 }
274 
275 void hsp_ag_init(uint8_t rfcomm_channel_nr){
276     // register for HCI events
277     hci_event_callback_registration.callback = &packet_handler;
278     hci_add_event_handler(&hci_event_callback_registration);
279 
280     rfcomm_register_service(packet_handler, rfcomm_channel_nr, 0xffff);  // reserved channel, mtu limited by l2cap
281 
282     hsp_ag_reset_state();
283 }
284 
285 void hsp_ag_connect(bd_addr_t bd_addr){
286     if (hsp_state != HSP_IDLE) return;
287     hsp_state = HSP_SDP_QUERY_RFCOMM_CHANNEL;
288     (void)memcpy(remote, bd_addr, 6);
289     hsp_run();
290 }
291 
292 void hsp_ag_disconnect(void){
293     hsp_ag_release_audio_connection();
294     if (hsp_state < HSP_W4_RFCOMM_CONNECTED){
295         hsp_state = HSP_IDLE;
296         return;
297     }
298 
299     if (hsp_state == HSP_W4_RFCOMM_CONNECTED){
300         hsp_state = HSP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN;
301         return;
302     }
303     hsp_disconnect_rfcomm = 1;
304     hsp_run();
305 }
306 
307 void hsp_ag_establish_audio_connection(void){
308     switch (hsp_state){
309         case HSP_RFCOMM_CONNECTION_ESTABLISHED:
310             hsp_establish_audio_connection = 1;
311             hsp_state = HSP_W4_SCO_CONNECTED;
312             break;
313         case HSP_W4_RFCOMM_CONNECTED:
314             hsp_state = HSP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN;
315             break;
316         default:
317             break;
318     }
319     hsp_run();
320 }
321 
322 void hsp_ag_release_audio_connection(void){
323     if (hsp_state >= HSP_W2_DISCONNECT_SCO) return;
324     if (hsp_state < HSP_AUDIO_CONNECTION_ESTABLISHED) return;
325 
326     hsp_release_audio_connection = 1;
327     hsp_run();
328 }
329 
330 
331 void hsp_ag_set_microphone_gain(uint8_t gain){
332     if (gain >15) {
333         log_error("Gain must be in interval [0..15], it is given %d", gain);
334         return;
335     }
336     ag_microphone_gain = gain;
337     hsp_run();
338 }
339 
340 // AG +VGS=5  [0..15] ; HS AT+VGM=6 | AG OK
341 void hsp_ag_set_speaker_gain(uint8_t gain){
342     if (gain >15) {
343         log_error("Gain must be in interval [0..15], it is given %d", gain);
344         return;
345     }
346     ag_speaker_gain = gain;
347     hsp_run();
348 }
349 
350 static void hsp_ringing_timeout_handler(btstack_timer_source_t * timer){
351     ag_ring = 1;
352     btstack_run_loop_set_timer(timer, 2000); // 2 seconds timeout
353     btstack_run_loop_add_timer(timer);
354     hsp_run();
355 }
356 
357 static void hsp_ringing_timer_start(void){
358     btstack_run_loop_remove_timer(&hs_timeout);
359     btstack_run_loop_set_timer_handler(&hs_timeout, hsp_ringing_timeout_handler);
360     btstack_run_loop_set_timer(&hs_timeout, 2000); // 2 seconds timeout
361     btstack_run_loop_add_timer(&hs_timeout);
362 }
363 
364 static void hsp_ringing_timer_stop(void){
365     btstack_run_loop_remove_timer(&hs_timeout);
366 }
367 
368 void hsp_ag_start_ringing(void){
369     ag_ring = 1;
370     if (hsp_state == HSP_W2_CONNECT_SCO) {
371         hsp_state = HSP_W4_RING_ANSWER;
372     }
373     hsp_ringing_timer_start();
374 }
375 
376 void hsp_ag_stop_ringing(void){
377     ag_ring = 0;
378     if (hsp_state == HSP_W4_RING_ANSWER){
379         hsp_state = HSP_W2_CONNECT_SCO;
380     }
381     hsp_ringing_timer_stop();
382 }
383 
384 static void hsp_run(void){
385 
386     if (ag_send_ok){
387         if (!rfcomm_can_send_packet_now(rfcomm_cid)) {
388             rfcomm_request_can_send_now_event(rfcomm_cid);
389             return;
390         }
391         ag_send_ok = 0;
392         hsp_ag_send_str_over_rfcomm(rfcomm_cid, HSP_AG_OK);
393         return;
394     }
395 
396     if (ag_send_error){
397         if (!rfcomm_can_send_packet_now(rfcomm_cid)) {
398             rfcomm_request_can_send_now_event(rfcomm_cid);
399             return;
400         }
401         ag_send_error = 0;
402         hsp_ag_send_str_over_rfcomm(rfcomm_cid, HSP_AG_ERROR);
403         return;
404     }
405 
406     if (ag_ring){
407         if (!rfcomm_can_send_packet_now(rfcomm_cid)) {
408             rfcomm_request_can_send_now_event(rfcomm_cid);
409             return;
410         }
411         ag_ring = 0;
412         hsp_ag_send_str_over_rfcomm(rfcomm_cid, HSP_AG_RING);
413         return;
414     }
415 
416     if (hsp_establish_audio_connection){
417         if (!hci_can_send_command_packet_now()) return;
418         hsp_establish_audio_connection = 0;
419         hci_send_cmd(&hci_setup_synchronous_connection, rfcomm_handle, 8000, 8000, 0xFFFF, hci_get_sco_voice_setting(), 0xFF, 0x003F);
420         return;
421     }
422 
423     if (hsp_release_audio_connection){
424         hsp_release_audio_connection = 0;
425         gap_disconnect(sco_handle);
426         return;
427     }
428 
429     if (hsp_disconnect_rfcomm){
430         hsp_disconnect_rfcomm = 0;
431         hsp_establish_audio_connection = 0;
432         rfcomm_disconnect(rfcomm_cid);
433         return;
434     }
435 
436     switch (hsp_state){
437         case HSP_SDP_QUERY_RFCOMM_CHANNEL:
438             hsp_state = HSP_W4_SDP_EVENT_QUERY_COMPLETE;
439             log_info("Start SDP query %s, 0x%02x", bd_addr_to_str(remote), BLUETOOTH_SERVICE_CLASS_HEADSET);
440             sdp_client_query_rfcomm_channel_and_name_for_uuid(&handle_query_rfcomm_event, remote, BLUETOOTH_SERVICE_CLASS_HEADSET);
441             break;
442 
443         case HSP_W4_RING_ANSWER:
444             if (!ag_num_button_press_received) break;
445 
446             if (!rfcomm_can_send_packet_now(rfcomm_cid)) {
447                 rfcomm_request_can_send_now_event(rfcomm_cid);
448                 return;
449             }
450 
451             ag_send_ok = 0;
452             ag_num_button_press_received = 0;
453             hsp_state = HSP_W2_CONNECT_SCO;
454 
455             hsp_ag_send_str_over_rfcomm(rfcomm_cid, HSP_AG_OK);
456             break;
457 
458         case HSP_W2_CONNECT_SCO:
459             if (!hci_can_send_command_packet_now()) return;
460             hsp_state = HSP_W4_SCO_CONNECTED;
461             hci_send_cmd(&hci_setup_synchronous_connection, rfcomm_handle, 8000, 8000, 0xFFFF, hci_get_sco_voice_setting(), 0xFF, 0x003F);
462             break;
463 
464         case HSP_W2_DISCONNECT_SCO:
465             ag_num_button_press_received = 0;
466 
467             hsp_state = HSP_W4_SCO_DISCONNECTED;
468             gap_disconnect(sco_handle);
469             break;
470 
471         case HSP_W2_DISCONNECT_RFCOMM:
472             rfcomm_disconnect(rfcomm_cid);
473             break;
474 
475         case HSP_AUDIO_CONNECTION_ESTABLISHED:
476         case HSP_RFCOMM_CONNECTION_ESTABLISHED:
477 
478             if (ag_microphone_gain >= 0){
479                 if (!rfcomm_can_send_packet_now(rfcomm_cid)) {
480                     rfcomm_request_can_send_now_event(rfcomm_cid);
481                     return;
482                 }
483                 int gain = ag_microphone_gain;
484                 ag_microphone_gain = -1;
485                 char buffer[10];
486                 sprintf(buffer, "%s=%d\r\n", HSP_MICROPHONE_GAIN, gain);
487                 hsp_ag_send_str_over_rfcomm(rfcomm_cid, buffer);
488                 break;
489             }
490 
491             if (ag_speaker_gain >= 0){
492                 if (!rfcomm_can_send_packet_now(rfcomm_cid)) {
493                     rfcomm_request_can_send_now_event(rfcomm_cid);
494                     return;
495                 }
496                 int gain = ag_speaker_gain;
497                 ag_speaker_gain = -1;
498                 char buffer[10];
499                 sprintf(buffer, "%s=%d\r\n", HSP_SPEAKER_GAIN, gain);
500                 hsp_ag_send_str_over_rfcomm(rfcomm_cid, buffer);
501                 break;
502             }
503             break;
504         default:
505             break;
506     }
507 }
508 
509 
510 static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
511     UNUSED(channel);    // ok: no channel for HCI_EVENT_PACKET and only single active RFCOMM channel
512 
513     if (packet_type == RFCOMM_DATA_PACKET){
514         while ((size > 0) && ((packet[0] == '\n') || (packet[0] == '\r'))){
515             size--;
516             packet++;
517         }
518 
519         if (strncmp((char *)packet, HSP_HS_BUTTON_PRESS, strlen(HSP_HS_BUTTON_PRESS)) == 0){
520             log_info("Received button press %s", HSP_HS_BUTTON_PRESS);
521             ag_send_ok = 1;
522             switch (hsp_state){
523                 case HSP_AUDIO_CONNECTION_ESTABLISHED:
524                     hsp_release_audio_connection = 1;
525                     break;
526                 case HSP_RFCOMM_CONNECTION_ESTABLISHED:
527                     hsp_establish_audio_connection = 1;
528                     break;
529                 default:
530                     break;
531             }
532         } else if (strncmp((char *)packet, HSP_HS_MICROPHONE_GAIN, strlen(HSP_HS_MICROPHONE_GAIN)) == 0){
533             uint8_t gain = (uint8_t)btstack_atoi((char*)&packet[strlen(HSP_HS_MICROPHONE_GAIN)]);
534             ag_send_ok = 1;
535             emit_event(HSP_SUBEVENT_MICROPHONE_GAIN_CHANGED, gain);
536 
537         } else if (strncmp((char *)packet, HSP_HS_SPEAKER_GAIN, strlen(HSP_HS_SPEAKER_GAIN)) == 0){
538             uint8_t gain = (uint8_t)btstack_atoi((char*)&packet[strlen(HSP_HS_SPEAKER_GAIN)]);
539             ag_send_ok = 1;
540             emit_event(HSP_SUBEVENT_SPEAKER_GAIN_CHANGED, gain);
541 
542         } else if (strncmp((char *)packet, "AT+", 3) == 0){
543             ag_send_error = 1;
544             if (!hsp_ag_callback) return;
545             // re-use incoming buffer to avoid reserving large buffers - ugly but efficient
546             uint8_t * event = packet - 4;
547             event[0] = HCI_EVENT_HSP_META;
548             event[1] = size + 2;
549             event[2] = HSP_SUBEVENT_HS_COMMAND;
550             event[3] = size;
551             (*hsp_ag_callback)(HCI_EVENT_PACKET, 0, event, size+4);
552         }
553 
554         hsp_run();
555         return;
556     }
557 
558     if (packet_type != HCI_EVENT_PACKET) return;
559     uint8_t event = hci_event_packet_get_type(packet);
560     bd_addr_t event_addr;
561     uint16_t handle;
562 
563     switch (event) {
564         case HCI_EVENT_SYNCHRONOUS_CONNECTION_COMPLETE:{
565             uint8_t status = hci_event_synchronous_connection_complete_get_status(packet);
566             if (status != 0){
567                 log_error("(e)SCO Connection failed, status %u", status);
568                 emit_event_audio_connected(status, sco_handle);
569                 break;
570             }
571 
572             hci_event_synchronous_connection_complete_get_bd_addr(packet, event_addr);
573             sco_handle = hci_event_synchronous_connection_complete_get_handle(packet);
574             uint8_t  link_type = hci_event_synchronous_connection_complete_get_link_type(packet);
575             uint8_t  transmission_interval = hci_event_synchronous_connection_complete_get_transmission_interval(packet);  // measured in slots
576             uint8_t  retransmission_interval = hci_event_synchronous_connection_complete_get_retransmission_interval(packet);// measured in slots
577             uint16_t rx_packet_length = hci_event_synchronous_connection_complete_get_rx_packet_length(packet); // measured in bytes
578             uint16_t tx_packet_length = hci_event_synchronous_connection_complete_get_tx_packet_length(packet); // measured in bytes
579             uint8_t  air_mode = hci_event_synchronous_connection_complete_get_air_mode(packet);
580 
581             switch (link_type){
582                 case 0x00:
583                     log_info("SCO Connection established.");
584                     if (transmission_interval != 0) log_error("SCO Connection: transmission_interval not zero: %d.", transmission_interval);
585                     if (retransmission_interval != 0) log_error("SCO Connection: retransmission_interval not zero: %d.", retransmission_interval);
586                     if (rx_packet_length != 0) log_error("SCO Connection: rx_packet_length not zero: %d.", rx_packet_length);
587                     if (tx_packet_length != 0) log_error("SCO Connection: tx_packet_length not zero: %d.", tx_packet_length);
588                     break;
589                 case 0x02:
590                     log_info("eSCO Connection established.");
591                     break;
592                 default:
593                     log_error("(e)SCO reserved link_type 0x%2x", link_type);
594                     break;
595             }
596             log_info("sco_handle 0x%2x, address %s, transmission_interval %u slots, retransmission_interval %u slots, "
597                  " rx_packet_length %u bytes, tx_packet_length %u bytes, air_mode 0x%2x (0x02 == CVSD)", sco_handle,
598                  bd_addr_to_str(event_addr), transmission_interval, retransmission_interval, rx_packet_length, tx_packet_length, air_mode);
599 
600             if (hsp_state == HSP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN){
601                 hsp_state = HSP_W2_DISCONNECT_SCO;
602                 break;
603             }
604 
605             hsp_state = HSP_AUDIO_CONNECTION_ESTABLISHED;
606             emit_event_audio_connected(status, sco_handle);
607             break;
608         }
609 
610         case RFCOMM_EVENT_INCOMING_CONNECTION:
611             if (hsp_state != HSP_IDLE) return;
612 
613             rfcomm_event_incoming_connection_get_bd_addr(packet, event_addr);
614             rfcomm_cid = rfcomm_event_incoming_connection_get_rfcomm_cid(packet);
615             log_info("RFCOMM channel %u requested for %s with cid 0x%04x", rfcomm_event_incoming_connection_get_server_channel(packet), bd_addr_to_str(event_addr), rfcomm_cid);
616             hsp_state = HSP_W4_RFCOMM_CONNECTED;
617             rfcomm_accept_connection(rfcomm_cid);
618             break;
619 
620         case RFCOMM_EVENT_CHANNEL_OPENED:
621             log_info("RFCOMM_EVENT_CHANNEL_OPENED packet_handler type %u, packet[0] %x", packet_type, packet[0]);
622             if (rfcomm_event_channel_opened_get_status(packet)) {
623                 log_info("RFCOMM channel open failed, status %u§", rfcomm_event_channel_opened_get_status(packet));
624                 hsp_ag_reset_state();
625                 hsp_state = HSP_IDLE;
626             } else {
627                 rfcomm_handle = rfcomm_event_channel_opened_get_con_handle(packet);
628                 rfcomm_cid = rfcomm_event_channel_opened_get_rfcomm_cid(packet);
629                 mtu = rfcomm_event_channel_opened_get_max_frame_size(packet);
630                 log_info("RFCOMM channel open succeeded. New RFCOMM Channel ID %u, max frame size %u, state %d", rfcomm_cid, mtu, hsp_state);
631                 hsp_state = HSP_RFCOMM_CONNECTION_ESTABLISHED;
632             }
633             emit_event(HSP_SUBEVENT_RFCOMM_CONNECTION_COMPLETE, packet[2]);
634             break;
635 
636         case RFCOMM_EVENT_CHANNEL_CLOSED:
637             hsp_ag_reset_state();
638             emit_event(HSP_SUBEVENT_RFCOMM_DISCONNECTION_COMPLETE,0);
639             break;
640 
641         case RFCOMM_EVENT_CAN_SEND_NOW:
642             hsp_run();
643             break;
644 
645         case HCI_EVENT_DISCONNECTION_COMPLETE:
646             handle = little_endian_read_16(packet,3);
647             if (handle == sco_handle){
648                 sco_handle = HCI_CON_HANDLE_INVALID;
649                 hsp_state = HSP_RFCOMM_CONNECTION_ESTABLISHED;
650                 emit_event(HSP_SUBEVENT_AUDIO_DISCONNECTION_COMPLETE,0);
651                 break;
652             }
653             break;
654 
655         default:
656             break;
657     }
658 
659     hsp_run();
660 }
661 
662 static void handle_query_rfcomm_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
663     UNUSED(packet_type);    // ok: handling own sdp events
664     UNUSED(channel);        // ok: no channel
665     UNUSED(size);           // ok: handling own sdp events
666 
667     switch (packet[0]){
668         case SDP_EVENT_QUERY_RFCOMM_SERVICE:
669             channel_nr = sdp_event_query_rfcomm_service_get_rfcomm_channel(packet);
670             log_info("** Service name: '%s', RFCOMM port %u", sdp_event_query_rfcomm_service_get_name(packet), channel_nr);
671             break;
672         case SDP_EVENT_QUERY_COMPLETE:
673             if (channel_nr > 0){
674                 hsp_state = HSP_W4_RFCOMM_CONNECTED;
675                 log_info("RFCOMM create channel. state %d", HSP_W4_RFCOMM_CONNECTED);
676                 rfcomm_create_channel(packet_handler, remote, channel_nr, NULL);
677                 break;
678             }
679             hsp_ag_reset_state();
680             log_info("Service not found, status %u.\n", sdp_event_query_complete_get_status(packet));
681             if (sdp_event_query_complete_get_status(packet)){
682                 emit_event(HSP_SUBEVENT_AUDIO_CONNECTION_COMPLETE, sdp_event_query_complete_get_status(packet));
683             } else {
684                 emit_event(HSP_SUBEVENT_AUDIO_CONNECTION_COMPLETE, SDP_SERVICE_NOT_FOUND);
685             }
686             break;
687         default:
688             break;
689     }
690 }
691 
692 
693