hfp.c (5611a760af48d1ce1beea59c7908be73bd2393f1) hfp.c (f8fbdce0c5067e7e7edd3a29934b1f9b79c8ff2d)
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

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

221
222static void hfp_emit_audio_connection_established_event(hfp_callback_t callback, uint8_t value, uint16_t sco_handle){
223 if (!callback) return;
224 uint8_t event[6];
225 event[0] = HCI_EVENT_HFP_META;
226 event[1] = sizeof(event) - 2;
227 event[2] = HFP_SUBEVENT_AUDIO_CONNECTION_ESTABLISHED;
228 event[3] = value; // status 0 == OK
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

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

221
222static void hfp_emit_audio_connection_established_event(hfp_callback_t callback, uint8_t value, uint16_t sco_handle){
223 if (!callback) return;
224 uint8_t event[6];
225 event[0] = HCI_EVENT_HFP_META;
226 event[1] = sizeof(event) - 2;
227 event[2] = HFP_SUBEVENT_AUDIO_CONNECTION_ESTABLISHED;
228 event[3] = value; // status 0 == OK
229 bt_store_16(event, 4, sco_handle);
229 little_endian_store_16(event, 4, sco_handle);
230 (*callback)(event, sizeof(event));
231}
232
233btstack_linked_list_t * hfp_get_connections(){
234 return (btstack_linked_list_t *) &hfp_connections;
235}
236
237hfp_connection_t * get_hfp_connection_context_for_rfcomm_cid(uint16_t cid){

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

467
468 case RFCOMM_EVENT_INCOMING_CONNECTION:
469 // data: event (8), len(8), address(48), channel (8), rfcomm_cid (16)
470 bt_flip_addr(event_addr, &packet[2]);
471 context = provide_hfp_connection_context_for_bd_addr(event_addr);
472
473 if (!context || context->state != HFP_IDLE) return;
474
230 (*callback)(event, sizeof(event));
231}
232
233btstack_linked_list_t * hfp_get_connections(){
234 return (btstack_linked_list_t *) &hfp_connections;
235}
236
237hfp_connection_t * get_hfp_connection_context_for_rfcomm_cid(uint16_t cid){

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

467
468 case RFCOMM_EVENT_INCOMING_CONNECTION:
469 // data: event (8), len(8), address(48), channel (8), rfcomm_cid (16)
470 bt_flip_addr(event_addr, &packet[2]);
471 context = provide_hfp_connection_context_for_bd_addr(event_addr);
472
473 if (!context || context->state != HFP_IDLE) return;
474
475 context->rfcomm_cid = READ_BT_16(packet, 9);
475 context->rfcomm_cid = little_endian_read_16(packet, 9);
476 context->state = HFP_W4_RFCOMM_CONNECTED;
477 printf("RFCOMM channel %u requested for %s\n", context->rfcomm_cid, bd_addr_to_str(context->remote_addr));
478 rfcomm_accept_connection(context->rfcomm_cid);
479 break;
480
481 case RFCOMM_EVENT_OPEN_CHANNEL_COMPLETE:
482 // data: event(8), len(8), status (8), address (48), handle(16), server channel(8), rfcomm_cid(16), max frame size(16)
483 printf("RFCOMM_EVENT_OPEN_CHANNEL_COMPLETE packet_handler type %u, packet[0] %x, size %u\n", packet_type, packet[0], size);
484
485 bt_flip_addr(event_addr, &packet[3]);
486 context = get_hfp_connection_context_for_bd_addr(event_addr);
487 if (!context || context->state != HFP_W4_RFCOMM_CONNECTED) return;
488
489 if (packet[2]) {
490 hfp_emit_event(callback, HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_ESTABLISHED, packet[2]);
491 remove_hfp_connection_context(context);
492 } else {
476 context->state = HFP_W4_RFCOMM_CONNECTED;
477 printf("RFCOMM channel %u requested for %s\n", context->rfcomm_cid, bd_addr_to_str(context->remote_addr));
478 rfcomm_accept_connection(context->rfcomm_cid);
479 break;
480
481 case RFCOMM_EVENT_OPEN_CHANNEL_COMPLETE:
482 // data: event(8), len(8), status (8), address (48), handle(16), server channel(8), rfcomm_cid(16), max frame size(16)
483 printf("RFCOMM_EVENT_OPEN_CHANNEL_COMPLETE packet_handler type %u, packet[0] %x, size %u\n", packet_type, packet[0], size);
484
485 bt_flip_addr(event_addr, &packet[3]);
486 context = get_hfp_connection_context_for_bd_addr(event_addr);
487 if (!context || context->state != HFP_W4_RFCOMM_CONNECTED) return;
488
489 if (packet[2]) {
490 hfp_emit_event(callback, HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_ESTABLISHED, packet[2]);
491 remove_hfp_connection_context(context);
492 } else {
493 context->con_handle = READ_BT_16(packet, 9);
493 context->con_handle = little_endian_read_16(packet, 9);
494 printf("RFCOMM_EVENT_OPEN_CHANNEL_COMPLETE con_handle 0x%02x\n", context->con_handle);
495
494 printf("RFCOMM_EVENT_OPEN_CHANNEL_COMPLETE con_handle 0x%02x\n", context->con_handle);
495
496 context->rfcomm_cid = READ_BT_16(packet, 12);
497 uint16_t mtu = READ_BT_16(packet, 14);
496 context->rfcomm_cid = little_endian_read_16(packet, 12);
497 uint16_t mtu = little_endian_read_16(packet, 14);
498 printf("RFCOMM channel open succeeded. Context %p, RFCOMM Channel ID 0x%02x, max frame size %u\n", context, context->rfcomm_cid, mtu);
499
500 switch (context->state){
501 case HFP_W4_RFCOMM_CONNECTED:
502 context->state = HFP_EXCHANGE_SUPPORTED_FEATURES;
503 break;
504 case HFP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN:
505 context->state = HFP_W2_DISCONNECT_RFCOMM;

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

544 // context->link_setting = HFP_LINK_SETTINGS_S3;
545 context->link_setting = HFP_LINK_SETTINGS_D0;
546 break;
547 }
548 context->establish_audio_connection = 1;
549 break;
550 }
551
498 printf("RFCOMM channel open succeeded. Context %p, RFCOMM Channel ID 0x%02x, max frame size %u\n", context, context->rfcomm_cid, mtu);
499
500 switch (context->state){
501 case HFP_W4_RFCOMM_CONNECTED:
502 context->state = HFP_EXCHANGE_SUPPORTED_FEATURES;
503 break;
504 case HFP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN:
505 context->state = HFP_W2_DISCONNECT_RFCOMM;

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

544 // context->link_setting = HFP_LINK_SETTINGS_S3;
545 context->link_setting = HFP_LINK_SETTINGS_D0;
546 break;
547 }
548 context->establish_audio_connection = 1;
549 break;
550 }
551
552 uint16_t sco_handle = READ_BT_16(packet, index);
552 uint16_t sco_handle = little_endian_read_16(packet, index);
553 index+=2;
554
555 bt_flip_addr(event_addr, &packet[index]);
556 index+=6;
557
558 uint8_t link_type = packet[index++];
559 uint8_t transmission_interval = packet[index++]; // measured in slots
560 uint8_t retransmission_interval = packet[index++];// measured in slots
553 index+=2;
554
555 bt_flip_addr(event_addr, &packet[index]);
556 index+=6;
557
558 uint8_t link_type = packet[index++];
559 uint8_t transmission_interval = packet[index++]; // measured in slots
560 uint8_t retransmission_interval = packet[index++];// measured in slots
561 uint16_t rx_packet_length = READ_BT_16(packet, index); // measured in bytes
561 uint16_t rx_packet_length = little_endian_read_16(packet, index); // measured in bytes
562 index+=2;
562 index+=2;
563 uint16_t tx_packet_length = READ_BT_16(packet, index); // measured in bytes
563 uint16_t tx_packet_length = little_endian_read_16(packet, index); // measured in bytes
564 index+=2;
565 uint8_t air_mode = packet[index];
566
567 switch (link_type){
568 case 0x00:
569 log_info("SCO Connection established.");
570 if (transmission_interval != 0) log_error("SCO Connection: transmission_interval not zero: %d.", transmission_interval);
571 if (retransmission_interval != 0) log_error("SCO Connection: retransmission_interval not zero: %d.", retransmission_interval);

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

598 context->sco_handle = sco_handle;
599 context->establish_audio_connection = 0;
600 context->state = HFP_AUDIO_CONNECTION_ESTABLISHED;
601 hfp_emit_audio_connection_established_event(callback, packet[2], sco_handle);
602 break;
603 }
604
605 case RFCOMM_EVENT_CHANNEL_CLOSED:
564 index+=2;
565 uint8_t air_mode = packet[index];
566
567 switch (link_type){
568 case 0x00:
569 log_info("SCO Connection established.");
570 if (transmission_interval != 0) log_error("SCO Connection: transmission_interval not zero: %d.", transmission_interval);
571 if (retransmission_interval != 0) log_error("SCO Connection: retransmission_interval not zero: %d.", retransmission_interval);

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

598 context->sco_handle = sco_handle;
599 context->establish_audio_connection = 0;
600 context->state = HFP_AUDIO_CONNECTION_ESTABLISHED;
601 hfp_emit_audio_connection_established_event(callback, packet[2], sco_handle);
602 break;
603 }
604
605 case RFCOMM_EVENT_CHANNEL_CLOSED:
606 rfcomm_cid = READ_BT_16(packet,2);
606 rfcomm_cid = little_endian_read_16(packet,2);
607 context = get_hfp_connection_context_for_rfcomm_cid(rfcomm_cid);
608 if (!context) break;
609 if (context->state == HFP_W4_RFCOMM_DISCONNECTED_AND_RESTART){
610 context->state = HFP_IDLE;
611 hfp_establish_service_level_connection(context->remote_addr, context->service_uuid);
612 break;
613 }
614
615 hfp_emit_event(callback, HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_RELEASED, 0);
616 remove_hfp_connection_context(context);
617 break;
618
619 case HCI_EVENT_DISCONNECTION_COMPLETE:
607 context = get_hfp_connection_context_for_rfcomm_cid(rfcomm_cid);
608 if (!context) break;
609 if (context->state == HFP_W4_RFCOMM_DISCONNECTED_AND_RESTART){
610 context->state = HFP_IDLE;
611 hfp_establish_service_level_connection(context->remote_addr, context->service_uuid);
612 break;
613 }
614
615 hfp_emit_event(callback, HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_RELEASED, 0);
616 remove_hfp_connection_context(context);
617 break;
618
619 case HCI_EVENT_DISCONNECTION_COMPLETE:
620 handle = READ_BT_16(packet,3);
620 handle = little_endian_read_16(packet,3);
621 context = get_hfp_connection_context_for_sco_handle(handle);
622
623 if (!context) break;
624
625 if (context->state != HFP_W4_SCO_DISCONNECTED){
626 log_info("Received gap disconnect in wrong hfp state");
627 }
628 log_info("Check SCO handle: incoming 0x%02x, context 0x%02x\n", handle,context->sco_handle);

--- 732 unchanged lines hidden ---
621 context = get_hfp_connection_context_for_sco_handle(handle);
622
623 if (!context) break;
624
625 if (context->state != HFP_W4_SCO_DISCONNECTED){
626 log_info("Received gap disconnect in wrong hfp state");
627 }
628 log_info("Check SCO handle: incoming 0x%02x, context 0x%02x\n", handle,context->sco_handle);

--- 732 unchanged lines hidden ---