hsp_ag.c (efda0b48f920fa795cb4c2d0cf0c4acf184fb858) hsp_ag.c (fffdd288575b1b4b1bf0e7fec3011e209f5de43f)
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

--- 77 unchanged lines hidden (view full) ---

86static int ag_microphone_gain = -1;
87static int ag_speaker_gain = -1;
88static uint8_t ag_ring = 0;
89static uint8_t ag_send_ok = 0;
90static uint8_t ag_send_error = 0;
91static uint8_t ag_num_button_press_received = 0;
92static uint8_t ag_support_custom_commands = 0;
93
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

--- 77 unchanged lines hidden (view full) ---

86static int ag_microphone_gain = -1;
87static int ag_speaker_gain = -1;
88static uint8_t ag_ring = 0;
89static uint8_t ag_send_ok = 0;
90static uint8_t ag_send_error = 0;
91static uint8_t ag_num_button_press_received = 0;
92static uint8_t ag_support_custom_commands = 0;
93
94static uint8_t hsp_disconnect_rfcomm = 0;
95static uint8_t hsp_establish_audio_connection = 0;
96static uint8_t hsp_release_audio_connection = 0;
97
94static btstack_packet_callback_registration_t hci_event_callback_registration;
95
96typedef enum {
97 HSP_IDLE,
98 HSP_SDP_QUERY_RFCOMM_CHANNEL,
99 HSP_W4_SDP_EVENT_QUERY_COMPLETE,
100 HSP_W4_RFCOMM_CONNECTED,
98static btstack_packet_callback_registration_t hci_event_callback_registration;
99
100typedef enum {
101 HSP_IDLE,
102 HSP_SDP_QUERY_RFCOMM_CHANNEL,
103 HSP_W4_SDP_EVENT_QUERY_COMPLETE,
104 HSP_W4_RFCOMM_CONNECTED,
105
106 HSP_RFCOMM_CONNECTION_ESTABLISHED,
107
101 HSP_W4_RING_ANSWER,
102 HSP_W4_USER_ACTION,
103 HSP_W2_CONNECT_SCO,
104 HSP_W4_SCO_CONNECTED,
108 HSP_W4_RING_ANSWER,
109 HSP_W4_USER_ACTION,
110 HSP_W2_CONNECT_SCO,
111 HSP_W4_SCO_CONNECTED,
105 HSP_ACTIVE,
112
113 HSP_AUDIO_CONNECTION_ESTABLISHED,
114
106 HSP_W2_DISCONNECT_SCO,
107 HSP_W4_SCO_DISCONNECTED,
115 HSP_W2_DISCONNECT_SCO,
116 HSP_W4_SCO_DISCONNECTED,
117
108 HSP_W2_DISCONNECT_RFCOMM,
109 HSP_W4_RFCOMM_DISCONNECTED,
110 HSP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN
111} hsp_state_t;
112
113static hsp_state_t hsp_state = HSP_IDLE;
114
115
116static hsp_ag_callback_t hsp_ag_callback;
117
118 HSP_W2_DISCONNECT_RFCOMM,
119 HSP_W4_RFCOMM_DISCONNECTED,
120 HSP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN
121} hsp_state_t;
122
123static hsp_state_t hsp_state = HSP_IDLE;
124
125
126static hsp_ag_callback_t hsp_ag_callback;
127
118static void hsp_run();
128static void hsp_run(void);
119static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
120static void handle_query_rfcomm_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
121
122static void dummy_notify(uint8_t * event, uint16_t size){}
123
124void hsp_ag_register_packet_handler(hsp_ag_callback_t callback){
125 if (callback == NULL){
126 callback = &dummy_notify;

--- 85 unchanged lines hidden (view full) ---

212 if (name){
213 de_add_data(service, DE_STRING, strlen(name), (uint8_t *) name);
214 } else {
215 de_add_data(service, DE_STRING, strlen(default_hsp_ag_service_name), (uint8_t *) default_hsp_ag_service_name);
216 }
217}
218
219static int hsp_ag_send_str_over_rfcomm(uint16_t cid, char * command){
129static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
130static void handle_query_rfcomm_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
131
132static void dummy_notify(uint8_t * event, uint16_t size){}
133
134void hsp_ag_register_packet_handler(hsp_ag_callback_t callback){
135 if (callback == NULL){
136 callback = &dummy_notify;

--- 85 unchanged lines hidden (view full) ---

222 if (name){
223 de_add_data(service, DE_STRING, strlen(name), (uint8_t *) name);
224 } else {
225 de_add_data(service, DE_STRING, strlen(default_hsp_ag_service_name), (uint8_t *) default_hsp_ag_service_name);
226 }
227}
228
229static int hsp_ag_send_str_over_rfcomm(uint16_t cid, char * command){
220 if (!rfcomm_can_send_packet_now(cid)) return 1;
221 int err = rfcomm_send(cid, (uint8_t*) command, strlen(command));
222 if (err){
223 log_error("rfcomm_send_internal -> error 0X%02x", err);
224 return err;
225 }
226 return err;
227}
228

--- 17 unchanged lines hidden (view full) ---

246 ag_send_error = 0;
247 ag_ring = 0;
248
249 ag_num_button_press_received = 0;
250 ag_support_custom_commands = 0;
251
252 ag_microphone_gain = -1;
253 ag_speaker_gain = -1;
230 int err = rfcomm_send(cid, (uint8_t*) command, strlen(command));
231 if (err){
232 log_error("rfcomm_send_internal -> error 0X%02x", err);
233 return err;
234 }
235 return err;
236}
237

--- 17 unchanged lines hidden (view full) ---

255 ag_send_error = 0;
256 ag_ring = 0;
257
258 ag_num_button_press_received = 0;
259 ag_support_custom_commands = 0;
260
261 ag_microphone_gain = -1;
262 ag_speaker_gain = -1;
263
264 hsp_disconnect_rfcomm = 0;
265 hsp_establish_audio_connection = 0;
266 hsp_release_audio_connection = 0;
254}
255
256void hsp_ag_init(uint8_t rfcomm_channel_nr){
257 // register for HCI events
258 hci_event_callback_registration.callback = &packet_handler;
259 hci_add_event_handler(&hci_event_callback_registration);
260
261 // init L2CAP
267}
268
269void hsp_ag_init(uint8_t rfcomm_channel_nr){
270 // register for HCI events
271 hci_event_callback_registration.callback = &packet_handler;
272 hci_add_event_handler(&hci_event_callback_registration);
273
274 // init L2CAP
262 l2cap_init();
275 l2cap_register_packet_handler(packet_handler);
263
276
264 rfcomm_init();
265 rfcomm_register_service(packet_handler, rfcomm_channel_nr, 0xffff); // reserved channel, mtu limited by l2cap
266
267 hsp_ag_reset_state();
268}
269
270void hsp_ag_connect(bd_addr_t bd_addr){
271 if (hsp_state != HSP_IDLE) return;
272 hsp_state = HSP_SDP_QUERY_RFCOMM_CHANNEL;
273 memcpy(remote, bd_addr, 6);
274 hsp_run();
275}
276
277void hsp_ag_disconnect(void){
277 rfcomm_register_service(packet_handler, rfcomm_channel_nr, 0xffff); // reserved channel, mtu limited by l2cap
278
279 hsp_ag_reset_state();
280}
281
282void hsp_ag_connect(bd_addr_t bd_addr){
283 if (hsp_state != HSP_IDLE) return;
284 hsp_state = HSP_SDP_QUERY_RFCOMM_CHANNEL;
285 memcpy(remote, bd_addr, 6);
286 hsp_run();
287}
288
289void hsp_ag_disconnect(void){
290 hsp_ag_release_audio_connection();
291 printf(" rfcomm diconnect %d\n", hsp_state);
292 if (hsp_state < HSP_W4_RFCOMM_CONNECTED){
293 hsp_state = HSP_IDLE;
294 return;
295 }
296
297 if (hsp_state == HSP_W4_RFCOMM_CONNECTED){
298 hsp_state = HSP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN;
299 return;
300 }
301 hsp_disconnect_rfcomm = 1;
302 hsp_run();
303}
304
305void hsp_ag_establish_audio_connection(void){
306 printf("hsp_ag_establish_audio_connection state %d\n", hsp_state);
307
278 switch (hsp_state){
308 switch (hsp_state){
279 case HSP_ACTIVE:
280 hsp_state = HSP_W2_DISCONNECT_SCO;
309 case HSP_RFCOMM_CONNECTION_ESTABLISHED:
310 printf("set flag hsp_establish_audio_connection\n");
311 hsp_establish_audio_connection = 1;
312 hsp_state = HSP_W4_SCO_CONNECTED;
281 break;
313 break;
282 case HSP_W2_CONNECT_SCO:
283 hsp_state = HSP_W2_DISCONNECT_RFCOMM;
284 break;
285
286 case HSP_W4_RFCOMM_CONNECTED:
314 case HSP_W4_RFCOMM_CONNECTED:
287 case HSP_W4_SCO_CONNECTED:
288 hsp_state = HSP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN;
289 break;
290 default:
315 hsp_state = HSP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN;
316 break;
317 default:
291 return;
318 break;
292 }
293 hsp_run();
294}
295
319 }
320 hsp_run();
321}
322
323void hsp_ag_release_audio_connection(void){
324 if (hsp_state >= HSP_W2_DISCONNECT_SCO) return;
325 if (hsp_state < HSP_AUDIO_CONNECTION_ESTABLISHED) return;
326
327 hsp_release_audio_connection = 1;
328 hsp_run();
329}
330
331
296void hsp_ag_set_microphone_gain(uint8_t gain){
297 if (gain < 0 || gain >15) {
298 log_error("Gain must be in interval [0..15], it is given %d", gain);
299 return;
300 }
301 ag_microphone_gain = gain;
302 hsp_run();
303}

--- 35 unchanged lines hidden (view full) ---

339void hsp_ag_stop_ringing(void){
340 ag_ring = 0;
341 ag_num_button_press_received = 0;
342 hsp_state = HSP_W2_CONNECT_SCO;
343 hsp_ringing_timer_stop();
344}
345
346static void hsp_run(void){
332void hsp_ag_set_microphone_gain(uint8_t gain){
333 if (gain < 0 || gain >15) {
334 log_error("Gain must be in interval [0..15], it is given %d", gain);
335 return;
336 }
337 ag_microphone_gain = gain;
338 hsp_run();
339}

--- 35 unchanged lines hidden (view full) ---

375void hsp_ag_stop_ringing(void){
376 ag_ring = 0;
377 ag_num_button_press_received = 0;
378 hsp_state = HSP_W2_CONNECT_SCO;
379 hsp_ringing_timer_stop();
380}
381
382static void hsp_run(void){
383 if (!rfcomm_can_send_packet_now(rfcomm_cid)) return;
347 int err;
348
349 if (ag_send_ok){
350 ag_send_ok = 0;
351 err = hsp_ag_send_str_over_rfcomm(rfcomm_cid, HSP_AG_OK);
352 if (err){
353 ag_send_ok = 1;
354 }

--- 4 unchanged lines hidden (view full) ---

359 ag_send_error = 0;
360 err = hsp_ag_send_str_over_rfcomm(rfcomm_cid, HSP_AG_ERROR);
361 if (err) {
362 ag_send_error = 1;
363 }
364 return;
365 }
366
384 int err;
385
386 if (ag_send_ok){
387 ag_send_ok = 0;
388 err = hsp_ag_send_str_over_rfcomm(rfcomm_cid, HSP_AG_OK);
389 if (err){
390 ag_send_ok = 1;
391 }

--- 4 unchanged lines hidden (view full) ---

396 ag_send_error = 0;
397 err = hsp_ag_send_str_over_rfcomm(rfcomm_cid, HSP_AG_ERROR);
398 if (err) {
399 ag_send_error = 1;
400 }
401 return;
402 }
403
404 if (hsp_establish_audio_connection){
405 hsp_establish_audio_connection = 0;
406 hci_send_cmd(&hci_setup_synchronous_connection, rfcomm_handle, 8000, 8000, 0xFFFF, hci_get_sco_voice_setting(), 0xFF, 0x003F);
407 return;
408 }
409
410 if (hsp_release_audio_connection){
411 hsp_release_audio_connection = 0;
412 gap_disconnect(sco_handle);
413 return;
414 }
415
416 if (hsp_disconnect_rfcomm){
417 hsp_disconnect_rfcomm = 0;
418 hsp_establish_audio_connection = 0;
419 rfcomm_disconnect(rfcomm_cid);
420 return;
421 }
422
367 switch (hsp_state){
368 case HSP_SDP_QUERY_RFCOMM_CHANNEL:
369 hsp_state = HSP_W4_SDP_EVENT_QUERY_COMPLETE;
370 log_info("Start SDP query %s, 0x%02x", bd_addr_to_str(remote), SDP_HSP);
371 sdp_client_query_rfcomm_channel_and_name_for_uuid(&handle_query_rfcomm_event, remote, SDP_HSP);
372 break;
373
374 case HSP_W4_RING_ANSWER:

--- 13 unchanged lines hidden (view full) ---

388 hsp_state = HSP_W2_CONNECT_SCO;
389
390 err = hsp_ag_send_str_over_rfcomm(rfcomm_cid, HSP_AG_OK);
391 if (err) {
392 hsp_state = HSP_W4_RING_ANSWER;
393 ag_num_button_press_received = 1;
394 }
395 break;
423 switch (hsp_state){
424 case HSP_SDP_QUERY_RFCOMM_CHANNEL:
425 hsp_state = HSP_W4_SDP_EVENT_QUERY_COMPLETE;
426 log_info("Start SDP query %s, 0x%02x", bd_addr_to_str(remote), SDP_HSP);
427 sdp_client_query_rfcomm_channel_and_name_for_uuid(&handle_query_rfcomm_event, remote, SDP_HSP);
428 break;
429
430 case HSP_W4_RING_ANSWER:

--- 13 unchanged lines hidden (view full) ---

444 hsp_state = HSP_W2_CONNECT_SCO;
445
446 err = hsp_ag_send_str_over_rfcomm(rfcomm_cid, HSP_AG_OK);
447 if (err) {
448 hsp_state = HSP_W4_RING_ANSWER;
449 ag_num_button_press_received = 1;
450 }
451 break;
452
396 case HSP_W2_CONNECT_SCO:
453 case HSP_W2_CONNECT_SCO:
397 if (!hci_can_send_command_packet_now()) break;
398 hsp_state = HSP_W4_SCO_CONNECTED;
399 hci_send_cmd(&hci_setup_synchronous_connection, rfcomm_handle, 8000, 8000, 0xFFFF, hci_get_sco_voice_setting(), 0xFF, 0x003F);
400 break;
401
402 case HSP_W2_DISCONNECT_SCO:
403 ag_num_button_press_received = 0;
404
405 hsp_state = HSP_W4_SCO_DISCONNECTED;
406 gap_disconnect(sco_handle);
407 break;
408
409 case HSP_W2_DISCONNECT_RFCOMM:
454 hsp_state = HSP_W4_SCO_CONNECTED;
455 hci_send_cmd(&hci_setup_synchronous_connection, rfcomm_handle, 8000, 8000, 0xFFFF, hci_get_sco_voice_setting(), 0xFF, 0x003F);
456 break;
457
458 case HSP_W2_DISCONNECT_SCO:
459 ag_num_button_press_received = 0;
460
461 hsp_state = HSP_W4_SCO_DISCONNECTED;
462 gap_disconnect(sco_handle);
463 break;
464
465 case HSP_W2_DISCONNECT_RFCOMM:
410 hsp_state = HSP_W4_RFCOMM_DISCONNECTED;
411 rfcomm_disconnect(rfcomm_cid);
412 break;
466 rfcomm_disconnect(rfcomm_cid);
467 break;
413 case HSP_ACTIVE:
468
469 case HSP_AUDIO_CONNECTION_ESTABLISHED:
470 case HSP_RFCOMM_CONNECTION_ESTABLISHED:
414
415 if (ag_microphone_gain >= 0){
416 int gain = ag_microphone_gain;
417 ag_microphone_gain = -1;
418 char buffer[10];
419 sprintf(buffer, "%s=%d\r\n", HSP_MICROPHONE_GAIN, gain);
420 err = hsp_ag_send_str_over_rfcomm(rfcomm_cid, buffer);
421 if (err) {

--- 24 unchanged lines hidden (view full) ---

446 if (packet_type == RFCOMM_DATA_PACKET){
447 while (size > 0 && (packet[0] == '\n' || packet[0] == '\r')){
448 size--;
449 packet++;
450 }
451
452 if (strncmp((char *)packet, HSP_HS_BUTTON_PRESS, strlen(HSP_HS_BUTTON_PRESS)) == 0){
453 log_info("Received button press %s", HSP_HS_BUTTON_PRESS);
471
472 if (ag_microphone_gain >= 0){
473 int gain = ag_microphone_gain;
474 ag_microphone_gain = -1;
475 char buffer[10];
476 sprintf(buffer, "%s=%d\r\n", HSP_MICROPHONE_GAIN, gain);
477 err = hsp_ag_send_str_over_rfcomm(rfcomm_cid, buffer);
478 if (err) {

--- 24 unchanged lines hidden (view full) ---

503 if (packet_type == RFCOMM_DATA_PACKET){
504 while (size > 0 && (packet[0] == '\n' || packet[0] == '\r')){
505 size--;
506 packet++;
507 }
508
509 if (strncmp((char *)packet, HSP_HS_BUTTON_PRESS, strlen(HSP_HS_BUTTON_PRESS)) == 0){
510 log_info("Received button press %s", HSP_HS_BUTTON_PRESS);
454 ag_num_button_press_received++;
455 ag_send_ok = 1;
511 ag_send_ok = 1;
456 if (hsp_state == HSP_ACTIVE && ag_num_button_press_received >=2){
457 ag_num_button_press_received = 0;
458 hsp_state = HSP_W2_DISCONNECT_SCO;
459 }
512 switch (hsp_state){
513 case HSP_AUDIO_CONNECTION_ESTABLISHED:
514 hsp_release_audio_connection = 1;
515 break;
516 case HSP_RFCOMM_CONNECTION_ESTABLISHED:
517 hsp_establish_audio_connection = 1;
518 break;
519 default:
520 break;
521 }
460 } else if (strncmp((char *)packet, HSP_HS_MICROPHONE_GAIN, strlen(HSP_HS_MICROPHONE_GAIN)) == 0){
461 uint8_t gain = (uint8_t)atoi((char*)&packet[strlen(HSP_HS_MICROPHONE_GAIN)]);
462 ag_send_ok = 1;
463 emit_event(HSP_SUBEVENT_MICROPHONE_GAIN_CHANGED, gain);
464
465 } else if (strncmp((char *)packet, HSP_HS_SPEAKER_GAIN, strlen(HSP_HS_SPEAKER_GAIN)) == 0){
466 uint8_t gain = (uint8_t)atoi((char*)&packet[strlen(HSP_HS_SPEAKER_GAIN)]);
467 ag_send_ok = 1;

--- 62 unchanged lines hidden (view full) ---

530 " rx_packet_length %u bytes, tx_packet_length %u bytes, air_mode 0x%2x (0x02 == CVSD)", sco_handle,
531 bd_addr_to_str(address), transmission_interval, retransmission_interval, rx_packet_length, tx_packet_length, air_mode);
532
533 if (hsp_state == HSP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN){
534 hsp_state = HSP_W2_DISCONNECT_SCO;
535 break;
536 }
537
522 } else if (strncmp((char *)packet, HSP_HS_MICROPHONE_GAIN, strlen(HSP_HS_MICROPHONE_GAIN)) == 0){
523 uint8_t gain = (uint8_t)atoi((char*)&packet[strlen(HSP_HS_MICROPHONE_GAIN)]);
524 ag_send_ok = 1;
525 emit_event(HSP_SUBEVENT_MICROPHONE_GAIN_CHANGED, gain);
526
527 } else if (strncmp((char *)packet, HSP_HS_SPEAKER_GAIN, strlen(HSP_HS_SPEAKER_GAIN)) == 0){
528 uint8_t gain = (uint8_t)atoi((char*)&packet[strlen(HSP_HS_SPEAKER_GAIN)]);
529 ag_send_ok = 1;

--- 62 unchanged lines hidden (view full) ---

592 " rx_packet_length %u bytes, tx_packet_length %u bytes, air_mode 0x%2x (0x02 == CVSD)", sco_handle,
593 bd_addr_to_str(address), transmission_interval, retransmission_interval, rx_packet_length, tx_packet_length, air_mode);
594
595 if (hsp_state == HSP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN){
596 hsp_state = HSP_W2_DISCONNECT_SCO;
597 break;
598 }
599
538 hsp_state = HSP_ACTIVE;
600 hsp_state = HSP_AUDIO_CONNECTION_ESTABLISHED;
539 emit_event_audio_connected(status, sco_handle);
540 break;
541 }
542
543 case RFCOMM_EVENT_INCOMING_CONNECTION:
544 // data: event (8), len(8), address(48), channel (8), rfcomm_cid (16)
545 if (hsp_state != HSP_IDLE) return;
546
547 reverse_bd_addr(&packet[2], event_addr);
548 rfcomm_cid = little_endian_read_16(packet, 9);
549 log_info("RFCOMM channel %u requested for %s", packet[8], bd_addr_to_str(event_addr));
601 emit_event_audio_connected(status, sco_handle);
602 break;
603 }
604
605 case RFCOMM_EVENT_INCOMING_CONNECTION:
606 // data: event (8), len(8), address(48), channel (8), rfcomm_cid (16)
607 if (hsp_state != HSP_IDLE) return;
608
609 reverse_bd_addr(&packet[2], event_addr);
610 rfcomm_cid = little_endian_read_16(packet, 9);
611 log_info("RFCOMM channel %u requested for %s", packet[8], bd_addr_to_str(event_addr));
550 rfcomm_accept_connection(rfcomm_cid);
551
552 hsp_state = HSP_W4_RFCOMM_CONNECTED;
612 hsp_state = HSP_W4_RFCOMM_CONNECTED;
613 rfcomm_accept_connection(rfcomm_cid);
553 break;
554
555 case RFCOMM_EVENT_OPEN_CHANNEL_COMPLETE:
556 log_info("RFCOMM_EVENT_OPEN_CHANNEL_COMPLETE packet_handler type %u, packet[0] %x", packet_type, packet[0]);
557 // data: event(8), len(8), status (8), address (48), handle(16), server channel(8), rfcomm_cid(16), max frame size(16)
558 if (packet[2]) {
559 log_info("RFCOMM channel open failed, status %u§", packet[2]);
560 hsp_ag_reset_state();
614 break;
615
616 case RFCOMM_EVENT_OPEN_CHANNEL_COMPLETE:
617 log_info("RFCOMM_EVENT_OPEN_CHANNEL_COMPLETE packet_handler type %u, packet[0] %x", packet_type, packet[0]);
618 // data: event(8), len(8), status (8), address (48), handle(16), server channel(8), rfcomm_cid(16), max frame size(16)
619 if (packet[2]) {
620 log_info("RFCOMM channel open failed, status %u§", packet[2]);
621 hsp_ag_reset_state();
561 emit_event(HSP_SUBEVENT_AUDIO_CONNECTION_COMPLETE, packet[2]);
622 hsp_state = HSP_IDLE;
562 } else {
563 // data: event(8) , len(8), status (8), address (48), handle (16), server channel(8), rfcomm_cid(16), max frame size(16)
564 rfcomm_handle = little_endian_read_16(packet, 9);
565 rfcomm_cid = little_endian_read_16(packet, 12);
566 mtu = little_endian_read_16(packet, 14);
567 log_info("RFCOMM channel open succeeded. New RFCOMM Channel ID %u, max frame size %u, state %d", rfcomm_cid, mtu, hsp_state);
623 } else {
624 // data: event(8) , len(8), status (8), address (48), handle (16), server channel(8), rfcomm_cid(16), max frame size(16)
625 rfcomm_handle = little_endian_read_16(packet, 9);
626 rfcomm_cid = little_endian_read_16(packet, 12);
627 mtu = little_endian_read_16(packet, 14);
628 log_info("RFCOMM channel open succeeded. New RFCOMM Channel ID %u, max frame size %u, state %d", rfcomm_cid, mtu, hsp_state);
568
569 switch (hsp_state){
570 case HSP_W4_RFCOMM_CONNECTED:
571 ag_num_button_press_received = 0;
572 hsp_state = HSP_W2_CONNECT_SCO;
573 break;
574 case HSP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN:
575 hsp_state = HSP_W2_DISCONNECT_RFCOMM;
576 break;
577 default:
578 log_error("no valid state");
579 break;
580 }
629 hsp_state = HSP_RFCOMM_CONNECTION_ESTABLISHED;
581 }
630 }
631 emit_event(HSP_SUBEVENT_RFCOMM_CONNECTION_COMPLETE, packet[2]);
582 break;
583
584 case HCI_EVENT_DISCONNECTION_COMPLETE:
585 handle = little_endian_read_16(packet,3);
586 if (handle == sco_handle){
632 break;
633
634 case HCI_EVENT_DISCONNECTION_COMPLETE:
635 handle = little_endian_read_16(packet,3);
636 if (handle == sco_handle){
587 log_info("SCO disconnected, w2 disconnect RFCOMM");
588 sco_handle = 0;
637 sco_handle = 0;
589 hsp_state = HSP_W2_DISCONNECT_RFCOMM;
638 hsp_state = HSP_RFCOMM_CONNECTION_ESTABLISHED;
639 emit_event(HSP_SUBEVENT_AUDIO_DISCONNECTION_COMPLETE,0);
590 break;
640 break;
641 }
642 if (handle == rfcomm_handle) {
643 rfcomm_handle = 0;
644 hsp_state = HSP_IDLE;
645 hsp_ag_reset_state();
646 emit_event(HSP_SUBEVENT_RFCOMM_DISCONNECTION_COMPLETE,0);
591 }
592 break;
593
594 case RFCOMM_EVENT_CHANNEL_CLOSED:
647 }
648 break;
649
650 case RFCOMM_EVENT_CHANNEL_CLOSED:
595 log_info("RFCOMM channel closed");
651 rfcomm_handle = 0;
652 hsp_state = HSP_IDLE;
596 hsp_ag_reset_state();
653 hsp_ag_reset_state();
597 emit_event(HSP_SUBEVENT_AUDIO_DISCONNECTION_COMPLETE,0);
654 emit_event(HSP_SUBEVENT_RFCOMM_DISCONNECTION_COMPLETE,0);
598 break;
599 default:
600 break;
601 }
602 hsp_run();
603}
604
605static void handle_query_rfcomm_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){

--- 26 unchanged lines hidden ---
655 break;
656 default:
657 break;
658 }
659 hsp_run();
660}
661
662static void handle_query_rfcomm_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){

--- 26 unchanged lines hidden ---