hci.c (8254e329c4214c740af04ff7882112fc4df7461e) | hci.c (7aa35f6a68be293b189765703d55a2983fa71909) |
---|---|
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 --- 216 unchanged lines hidden (view full) --- 225#endif /* ENABLE_LE_PERIPHERAL */ 226#ifdef ENABLE_LE_ISOCHRONOUS_STREAMS 227static uint8_t hci_iso_stream_create(hci_con_handle_t cis_handle); 228static void hci_iso_stream_finalize(hci_iso_stream_t * iso_stream); 229static hci_iso_stream_t * hci_iso_stream_for_cis_handle(hci_con_handle_t cis_handle); 230static void hci_iso_stream_requested_finalize(void); 231static void hci_iso_stream_requested_confirm(void); 232static void hci_iso_packet_handler(uint8_t * packet, uint16_t size); | 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 --- 216 unchanged lines hidden (view full) --- 225#endif /* ENABLE_LE_PERIPHERAL */ 226#ifdef ENABLE_LE_ISOCHRONOUS_STREAMS 227static uint8_t hci_iso_stream_create(hci_con_handle_t cis_handle); 228static void hci_iso_stream_finalize(hci_iso_stream_t * iso_stream); 229static hci_iso_stream_t * hci_iso_stream_for_cis_handle(hci_con_handle_t cis_handle); 230static void hci_iso_stream_requested_finalize(void); 231static void hci_iso_stream_requested_confirm(void); 232static void hci_iso_packet_handler(uint8_t * packet, uint16_t size); |
233static le_audio_big_t * hci_big_for_handle(uint8_t big_handle); 234static void hci_emit_big_created(const le_audio_big_t * big, uint8_t status); 235static void hci_emit_big_terminated(const le_audio_big_t * big); |
|
233#endif /* ENABLE_LE_ISOCHRONOUS_STREAMS */ 234#endif /* ENABLE_BLE */ 235 236// the STACK is here 237#ifndef HAVE_MALLOC 238static hci_stack_t hci_stack_static; 239#endif 240static hci_stack_t * hci_stack = NULL; --- 2489 unchanged lines hidden (view full) --- 2730#ifdef ENABLE_LE_ISOCHRONOUS_STREAMS 2731 case HCI_OPCODE_HCI_LE_ACCEPT_CIS_REQUEST: 2732 case HCI_OPCODE_HCI_LE_CREATE_CIS: 2733 status = packet[OFFSET_OF_DATA_IN_COMMAND_COMPLETE]; 2734 if (status != ERROR_CODE_SUCCESS){ 2735 hci_iso_stream_requested_finalize(); 2736 } 2737 break; | 236#endif /* ENABLE_LE_ISOCHRONOUS_STREAMS */ 237#endif /* ENABLE_BLE */ 238 239// the STACK is here 240#ifndef HAVE_MALLOC 241static hci_stack_t hci_stack_static; 242#endif 243static hci_stack_t * hci_stack = NULL; --- 2489 unchanged lines hidden (view full) --- 2733#ifdef ENABLE_LE_ISOCHRONOUS_STREAMS 2734 case HCI_OPCODE_HCI_LE_ACCEPT_CIS_REQUEST: 2735 case HCI_OPCODE_HCI_LE_CREATE_CIS: 2736 status = packet[OFFSET_OF_DATA_IN_COMMAND_COMPLETE]; 2737 if (status != ERROR_CODE_SUCCESS){ 2738 hci_iso_stream_requested_finalize(); 2739 } 2740 break; |
2741 case HCI_OPCODE_HCI_LE_SETUP_ISO_DATA_PATH: { 2742 // lookup BIG by state 2743 btstack_linked_list_iterator_t it; 2744 btstack_linked_list_iterator_init(&it, &hci_stack->le_audio_bigs); 2745 while (btstack_linked_list_iterator_has_next(&it)) { 2746 le_audio_big_t *big = (le_audio_big_t *) btstack_linked_list_iterator_next(&it); 2747 if (big->state == LE_AUDIO_BIG_STATE_W4_SETUP_ISO_PATH){ 2748 status = packet[OFFSET_OF_DATA_IN_COMMAND_COMPLETE]; 2749 if (status == ERROR_CODE_SUCCESS){ 2750 big->state_vars.next_bis++; 2751 if (big->state_vars.next_bis == big->num_bis){ 2752 big->state = LE_AUDIO_BIG_STATE_ACTIVE; 2753 hci_emit_big_created(big, ERROR_CODE_SUCCESS); 2754 } else { 2755 big->state = LE_AUDIO_BIG_STATE_SETUP_ISO_PATH; 2756 } 2757 } else { 2758 big->state = LE_AUDIO_BIG_STATE_SETUP_ISO_PATHS_FAILED; 2759 big->state_vars.status = status; 2760 break; 2761 } 2762 return; 2763 } 2764 } 2765 break; 2766 } |
|
2738#endif 2739#endif 2740 default: 2741 break; 2742 } 2743} 2744 2745static void handle_command_status_event(uint8_t * packet, uint16_t size) { --- 286 unchanged lines hidden (view full) --- 3032 3033#ifdef ENABLE_CLASSIC 3034 hci_link_type_t link_type; 3035 bd_addr_t addr; 3036 bd_addr_type_t addr_type; 3037#endif 3038#ifdef ENABLE_LE_ISOCHRONOUS_STREAMS 3039 hci_iso_stream_t * iso_stream; | 2767#endif 2768#endif 2769 default: 2770 break; 2771 } 2772} 2773 2774static void handle_command_status_event(uint8_t * packet, uint16_t size) { --- 286 unchanged lines hidden (view full) --- 3061 3062#ifdef ENABLE_CLASSIC 3063 hci_link_type_t link_type; 3064 bd_addr_t addr; 3065 bd_addr_type_t addr_type; 3066#endif 3067#ifdef ENABLE_LE_ISOCHRONOUS_STREAMS 3068 hci_iso_stream_t * iso_stream; |
3069 le_audio_big_t * big; |
|
3040#endif 3041 3042 // log_info("HCI:EVENT:%02x", hci_event_packet_get_type(packet)); 3043 3044 switch (hci_event_packet_get_type(packet)) { 3045 3046 case HCI_EVENT_COMMAND_COMPLETE: 3047 handle_command_complete_event(packet, size); --- 680 unchanged lines hidden (view full) --- 3728 if (iso_stream){ 3729 uint8_t status = hci_subevent_le_cis_established_get_status(packet); 3730 if (status == ERROR_CODE_SUCCESS){ 3731 iso_stream->state = HCI_ISO_STREAM_STATE_ESTABLISHED; 3732 } else { 3733 hci_iso_stream_finalize(iso_stream); 3734 } 3735 } | 3070#endif 3071 3072 // log_info("HCI:EVENT:%02x", hci_event_packet_get_type(packet)); 3073 3074 switch (hci_event_packet_get_type(packet)) { 3075 3076 case HCI_EVENT_COMMAND_COMPLETE: 3077 handle_command_complete_event(packet, size); --- 680 unchanged lines hidden (view full) --- 3758 if (iso_stream){ 3759 uint8_t status = hci_subevent_le_cis_established_get_status(packet); 3760 if (status == ERROR_CODE_SUCCESS){ 3761 iso_stream->state = HCI_ISO_STREAM_STATE_ESTABLISHED; 3762 } else { 3763 hci_iso_stream_finalize(iso_stream); 3764 } 3765 } |
3766 break; 3767 case HCI_SUBEVENT_LE_CREATE_BIG_COMPLETE: 3768 big = hci_big_for_handle(packet[4]); 3769 if (big != NULL){ 3770 uint8_t status = packet[3]; 3771 if (status == ERROR_CODE_SUCCESS){ 3772 // store bis_con_handles and trigger iso path setup 3773 uint8_t num_bis = btstack_min(MAX_NR_BIS, packet[20]); 3774 uint8_t i; 3775 for (i=0;i<num_bis;i++){ 3776 big->bis_con_handles[i] = little_endian_read_16(packet, 21 + (2 * i)); 3777 } 3778 big->state = LE_AUDIO_BIG_STATE_SETUP_ISO_PATH; 3779 big->state_vars.next_bis = 0; 3780 } else { 3781 // create BIG failed 3782 btstack_linked_list_remove(&hci_stack->le_audio_bigs, (btstack_linked_item_t *) big); 3783 hci_emit_big_created(big, status); 3784 } 3785 } 3786 break; 3787 case HCI_SUBEVENT_LE_TERMINATE_BIG_COMPLETE: 3788 big = hci_big_for_handle(hci_subevent_le_terminate_big_complete_get_big_handle(packet)); 3789 if (big != NULL){ 3790 btstack_linked_list_remove(&hci_stack->le_audio_bigs, (btstack_linked_item_t *) big); 3791 switch (big->state){ 3792 case LE_AUDIO_BIG_STATE_W4_TERMINATED_AFTER_SETUP_FAILED: 3793 hci_emit_big_created(big, big->state_vars.status); 3794 break; 3795 default: 3796 hci_emit_big_terminated(big); 3797 break; 3798 } 3799 } 3800 break; |
|
3736#endif 3737 default: 3738 break; 3739 } 3740 break; 3741#endif 3742 case HCI_EVENT_VENDOR_SPECIFIC: 3743 // Vendor specific commands often create vendor specific event instead of num completed packets --- 2080 unchanged lines hidden (view full) --- 5824#endif /* ENABLE_LE_PERIODIC_ADVERTISING */ 5825 } 5826 } 5827#endif 5828#endif 5829 5830 return false; 5831} | 3801#endif 3802 default: 3803 break; 3804 } 3805 break; 3806#endif 3807 case HCI_EVENT_VENDOR_SPECIFIC: 3808 // Vendor specific commands often create vendor specific event instead of num completed packets --- 2080 unchanged lines hidden (view full) --- 5889#endif /* ENABLE_LE_PERIODIC_ADVERTISING */ 5890 } 5891 } 5892#endif 5893#endif 5894 5895 return false; 5896} |
5897 5898#ifdef ENABLE_LE_ISOCHRONOUS_STREAMS 5899static bool hci_run_iso_tasks(void){ 5900 btstack_linked_list_iterator_t it; 5901 btstack_linked_list_iterator_init(&it, &hci_stack->le_audio_bigs); 5902 while (btstack_linked_list_iterator_has_next(&it)){ 5903 le_audio_big_t * big = (le_audio_big_t *) btstack_linked_list_iterator_next(&it); 5904 switch (big->state){ 5905 case LE_AUDIO_BIG_STATE_CREATE: 5906 big->state = LE_AUDIO_BIG_STATE_W4_ESTABLISHED; 5907 hci_send_cmd(&hci_le_create_big, 5908 big->params->big_handle, 5909 big->params->advertising_handle, 5910 big->params->num_bis, 5911 big->params->sdu_interval_us, 5912 big->params->max_sdu, 5913 big->params->max_transport_latency_ms, 5914 big->params->rtn, 5915 big->params->phy, 5916 big->params->packing, 5917 big->params->framing, 5918 big->params->encryption, 5919 big->params->broadcast_code); 5920 return true; 5921 case LE_AUDIO_BIG_STATE_SETUP_ISO_PATH: 5922 big->state = LE_AUDIO_BIG_STATE_W4_SETUP_ISO_PATH; 5923 hci_send_cmd(&hci_le_setup_iso_data_path, big->bis_con_handles[big->state_vars.next_bis], 0, 0, 0, 0, 0, 0, 0, NULL); 5924 return true; 5925 case LE_AUDIO_BIG_STATE_SETUP_ISO_PATHS_FAILED: 5926 big->state = LE_AUDIO_BIG_STATE_W4_TERMINATED_AFTER_SETUP_FAILED; 5927 hci_send_cmd(&hci_le_terminate_big, big->big_handle); 5928 break; 5929 case LE_AUDIO_BIG_STATE_TERMINATE: 5930 big->state = LE_AUDIO_BIG_STATE_W4_TERMINATED; 5931 hci_send_cmd(&hci_le_terminate_big, big->big_handle); 5932 return true; 5933 default: 5934 break; 5935 } 5936 } 5937 return false; 5938} 5939#endif /* ENABLE_LE_ISOCHRONOUS_STREAMS */ |
|
5832#endif 5833 5834static bool hci_run_general_pending_commands(void){ 5835 btstack_linked_item_t * it; 5836 for (it = (btstack_linked_item_t *) hci_stack->connections; it != NULL; it = it->next){ 5837 hci_connection_t * connection = (hci_connection_t *) it; 5838 5839 switch(connection->state){ --- 435 unchanged lines hidden (view full) --- 6275 done = hci_run_general_gap_classic(); 6276 if (done) return; 6277#endif 6278 6279#ifdef ENABLE_BLE 6280 // general gap le 6281 done = hci_run_general_gap_le(); 6282 if (done) return; | 5940#endif 5941 5942static bool hci_run_general_pending_commands(void){ 5943 btstack_linked_item_t * it; 5944 for (it = (btstack_linked_item_t *) hci_stack->connections; it != NULL; it = it->next){ 5945 hci_connection_t * connection = (hci_connection_t *) it; 5946 5947 switch(connection->state){ --- 435 unchanged lines hidden (view full) --- 6383 done = hci_run_general_gap_classic(); 6384 if (done) return; 6385#endif 6386 6387#ifdef ENABLE_BLE 6388 // general gap le 6389 done = hci_run_general_gap_le(); 6390 if (done) return; |
6391 6392#ifdef ENABLE_LE_ISOCHRONOUS_STREAMS 6393 // ISO related tasks, e.g. BIG create/terminate/sync 6394 done = hci_run_iso_tasks(); 6395 if (done) return; |
|
6283#endif | 6396#endif |
6397#endif |
|
6284 6285 // send pending HCI commands 6286 hci_run_general_pending_commands(); 6287} 6288 6289uint8_t hci_send_cmd_packet(uint8_t *packet, int size){ 6290 // house-keeping 6291 --- 2325 unchanged lines hidden (view full) --- 8617 if (hci_iso_sdu_complete(iso_stream->reassembly_buffer, iso_stream->reassembly_pos)){ 8618 (hci_stack->iso_packet_handler)(HCI_ISO_DATA_PACKET, 0, iso_stream->reassembly_buffer, iso_stream->reassembly_pos); 8619 } 8620 iso_stream->reassembly_pos = 0; 8621 } 8622 } 8623} 8624 | 6398 6399 // send pending HCI commands 6400 hci_run_general_pending_commands(); 6401} 6402 6403uint8_t hci_send_cmd_packet(uint8_t *packet, int size){ 6404 // house-keeping 6405 --- 2325 unchanged lines hidden (view full) --- 8731 if (hci_iso_sdu_complete(iso_stream->reassembly_buffer, iso_stream->reassembly_pos)){ 8732 (hci_stack->iso_packet_handler)(HCI_ISO_DATA_PACKET, 0, iso_stream->reassembly_buffer, iso_stream->reassembly_pos); 8733 } 8734 iso_stream->reassembly_pos = 0; 8735 } 8736 } 8737} 8738 |
8739static void hci_emit_big_created(const le_audio_big_t * big, uint8_t status){ 8740 uint8_t event [6 + (MAX_NR_BIS * 2)]; 8741 uint16_t pos = 0; 8742 event[pos++] = HCI_EVENT_META_GAP; 8743 event[pos++] = 4 + (2 * big->num_bis); 8744 event[pos++] = GAP_SUBEVENT_BIG_CREATED; 8745 event[pos++] = status; 8746 event[pos++] = big->big_handle; 8747 event[pos++] = big->num_bis; 8748 uint8_t i; 8749 for (i=0;i<big->num_bis;i++){ 8750 little_endian_store_16(event, pos, big->bis_con_handles[i]); 8751 pos += 2; 8752 } 8753 hci_emit_event(event, pos, 0); 8754} |
|
8625 | 8755 |
8756static void hci_emit_big_terminated(const le_audio_big_t * big){ 8757 uint8_t event [4]; 8758 uint16_t pos = 0; 8759 event[pos++] = HCI_EVENT_META_GAP; 8760 event[pos++] = 2; 8761 event[pos++] = GAP_SUBEVENT_BIG_TERMINATED; 8762 event[pos++] = big->big_handle; 8763 hci_emit_event(event, pos, 0); 8764} 8765 8766static le_audio_big_t * hci_big_for_handle(uint8_t big_handle){ 8767 btstack_linked_list_iterator_t it; 8768 btstack_linked_list_iterator_init(&it, &hci_stack->le_audio_bigs); 8769 while (btstack_linked_list_iterator_has_next(&it)){ 8770 le_audio_big_t * big = (le_audio_big_t *) btstack_linked_list_iterator_next(&it); 8771 if ( big->big_handle == big_handle ) { 8772 return big; 8773 } 8774 } 8775 return NULL; 8776} 8777 8778uint8_t gap_big_create(le_audio_big_t * storage, le_audio_big_params_t * big_params){ 8779 if (hci_big_for_handle(big_params->big_handle) != NULL){ 8780 return ERROR_CODE_ACL_CONNECTION_ALREADY_EXISTS; 8781 } 8782 8783 if (big_params->num_bis == 0){ 8784 return ERROR_CODE_INVALID_HCI_COMMAND_PARAMETERS; 8785 } 8786 if (big_params->num_bis > MAX_NR_BIS){ 8787 return ERROR_CODE_INVALID_HCI_COMMAND_PARAMETERS; 8788 } 8789 8790 le_audio_big_t * big = storage; 8791 big->big_handle = big_params->big_handle; 8792 big->params = big_params; 8793 big->state = LE_AUDIO_BIG_STATE_CREATE; 8794 big->num_bis = big_params->num_bis; 8795 btstack_linked_list_add(&hci_stack->le_audio_bigs, (btstack_linked_item_t *) big); 8796 8797 hci_run(); 8798 8799 return ERROR_CODE_SUCCESS; 8800} 8801 8802uint8_t gap_big_terminate(uint8_t big_handle){ 8803 le_audio_big_t * big = hci_big_for_handle(big_handle); 8804 if (big == NULL){ 8805 return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER; 8806 } 8807 switch (big->state){ 8808 case LE_AUDIO_BIG_STATE_CREATE: 8809 btstack_linked_list_remove(&hci_stack->le_audio_bigs, (btstack_linked_item_t *) big); 8810 break; 8811 case LE_AUDIO_BIG_STATE_W4_ESTABLISHED: 8812 big->state = LE_AUDIO_BIG_STATE_W4_ESTABLISHED_THEN_TERMINATE; 8813 break; 8814 case LE_AUDIO_BIG_STATE_SETUP_ISO_PATH: 8815 case LE_AUDIO_BIG_STATE_ACTIVE: 8816 big->state = LE_AUDIO_BIG_STATE_TERMINATE; 8817 hci_run(); 8818 break; 8819 case LE_AUDIO_BIG_STATE_W4_SETUP_ISO_PATH: 8820 big->state = LE_AUDIO_BIG_STATE_W4_SETUP_ISO_PATH_THEN_TERMINATE; 8821 break; 8822 default: 8823 return ERROR_CODE_COMMAND_DISALLOWED; 8824 } 8825 return ERROR_CODE_SUCCESS; 8826} 8827 |
|
8626#endif 8627#endif /* ENABLE_BLE */ 8628 8629#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION 8630void hci_setup_test_connections_fuzz(void){ 8631 hci_connection_t * conn; 8632 8633 // default address: 66:55:44:33:00:01 --- 63 unchanged lines hidden --- | 8828#endif 8829#endif /* ENABLE_BLE */ 8830 8831#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION 8832void hci_setup_test_connections_fuzz(void){ 8833 hci_connection_t * conn; 8834 8835 // default address: 66:55:44:33:00:01 --- 63 unchanged lines hidden --- |