src/patch.c
__attribute__((at(0x00210f00, "", CHIP_VER_BCM4375B1_BT, FW_VER_S20)))
void bthci_cmd_start_rx(uint8_t *hci_cmd_buffer) {
	char* buffer = bthci_event_AllocateEventAndFillHeader(4+2, 0xFF, 4);
	
	// save Zigbee RX mode
	rx_enabled = hci_cmd_buffer[12];

	// save Zigbee channel
	// TODO: I should check the interval and trigger an error if needed
	rx_frequency = (rx_enabled == 0x01 ? channelToFrequency(hci_cmd_buffer[13]) : hci_cmd_buffer[13]-2); 

	// Reset fake HCI buffer
	for (int i=0;i<40;i++) fake_hci_buffer[i] = 0;
	fake_hci_buffer[8] =  0x01;
	fake_hci_buffer[9] =  0x42;
	fake_hci_buffer[10] =  0x20;
	fake_hci_buffer[11] =  0x06;	
	fake_hci_buffer[12] = 0x00;
	fake_hci_buffer[13] = 0x00;
	fake_hci_buffer[14] = 0x00;
	fake_hci_buffer[15] = 0x00;
	fake_hci_buffer[16] = 0x00;
	fake_hci_buffer[17] = 0x00;
	bthci_cmd_ble_HandleSet_Extended_Scan_Enable(fake_hci_buffer);
	if (rx_enabled != 0) {
		// Reset fake HCI buffer
		for (int i=0;i<40;i++) fake_hci_buffer[i] = 0;
		fake_hci_buffer[8] =  0x01;
		fake_hci_buffer[9] =  0x41;
		fake_hci_buffer[10] =  0x20;
		fake_hci_buffer[11] =  0x08;		
		fake_hci_buffer[12] = 0x01;
		fake_hci_buffer[13] = 0x00;
		fake_hci_buffer[14] = 0x01;
		fake_hci_buffer[15] = 0x01;
		fake_hci_buffer[16] = 0x99;
		fake_hci_buffer[17] = 0x19;
		fake_hci_buffer[18] = 0x99;
		fake_hci_buffer[19] = 0x19;
		bthci_cmd_ble_HandleSet_Extended_Scan_Parameters(fake_hci_buffer);
		
		// Configure fake HCI buffer to enable or disable LE scan

		
		for (int i=0;i<40;i++) fake_hci_buffer[i] = 0;
		fake_hci_buffer[8] =  0x01;
		fake_hci_buffer[9] =  0x42;
		fake_hci_buffer[10] =  0x20;
		fake_hci_buffer[11] =  0x06;		
		fake_hci_buffer[12] = 0x01;
		fake_hci_buffer[13] = 0x00;
		fake_hci_buffer[14] = 0x00;
		fake_hci_buffer[15] = 0x00;
		fake_hci_buffer[16] = 0x00;
		fake_hci_buffer[17] = 0x00;

		bthci_cmd_ble_HandleSet_Extended_Scan_Enable(fake_hci_buffer);
	}
	if (rx_enabled == 2) {
		dongle_mode = (hci_cmd_buffer[14] == 0 ? 0x00 : 0x01);
	}
	if (rx_enabled == 3) {
		memcpybt(raw_buffer,&hci_cmd_buffer[14],4);
		raw_buffer[4] = 0x70;
		encode_mosart(buffer_decoded,raw_buffer,5);
		preamble = (buffer_decoded[8] << 24) | (buffer_decoded[7] << 16) | (buffer_decoded[6] << 8) | (buffer_decoded[5]);
	}
	else if (rx_enabled == 4) {
		dongle_mode = 0x00;
		preamble = (hci_cmd_buffer[17] << 24) | (hci_cmd_buffer[16] << 16) | ((hci_cmd_buffer[15]) << 8) | hci_cmd_buffer[14];
	}
	else if (rx_enabled == 5) {
		/*
		dongle_mode = (hci_cmd_buffer[14] == 0 ? 0x00 : 0x01);
		preamble =  (hci_cmd_buffer[17] << 16)|(hci_cmd_buffer[16] << 8)| hci_cmd_buffer[15];
		*/
	}
	else if (rx_enabled == 6) {
		memcpybt(raw_buffer,&hci_cmd_buffer[14],5);
		preamble = ((swap_bits(raw_buffer[2]) << 24) |(swap_bits(raw_buffer[1]) << 16) | (swap_bits(raw_buffer[0]) << 8) | (swap_bits(0xAA)));
	}
	// Forge HCI response and send it to host
	buffer[10] = 0x52;
	buffer[11] = 0x58;
	buffer[12] = (uint8_t)rx_enabled;
	buffer[13] = (uint8_t)rx_frequency;
	bthci_event_AttemptToEnqueueEventToTransport(buffer);
}
/*
Function allowing to enable and configure RX mode 
*/
Function allowing to enable and configure RX mode
Function allowing to enable and configure RX mode
__attribute__((at(0x00210f00, "", CHIP_VER_BCM4375B1_BT, FW_VER_S20)))
void bthci_cmd_start_rx(uint8_t *hci_cmd_buffer) {
	char* buffer = bthci_event_AllocateEventAndFillHeader(4+2, 0xFF, 4);
	rx_enabled = hci_cmd_buffer[12];
	rx_frequency = (rx_enabled == 0x01 ? channelToFrequency(hci_cmd_buffer[13]) : hci_cmd_buffer[13]-2); 
	for (int i=0;i<40;i++) fake_hci_buffer[i] = 0;
	fake_hci_buffer[8] =  0x01;
	fake_hci_buffer[9] =  0x42;
	fake_hci_buffer[10] =  0x20;
	fake_hci_buffer[11] =  0x06;	
	fake_hci_buffer[12] = 0x00;
	fake_hci_buffer[13] = 0x00;
	fake_hci_buffer[14] = 0x00;
	fake_hci_buffer[15] = 0x00;
	fake_hci_buffer[16] = 0x00;
	fake_hci_buffer[17] = 0x00;
	bthci_cmd_ble_HandleSet_Extended_Scan_Enable(fake_hci_buffer);
	if (rx_enabled != 0) {
		for (int i=0;i<40;i++) fake_hci_buffer[i] = 0;
		fake_hci_buffer[8] =  0x01;
		fake_hci_buffer[9] =  0x41;
		fake_hci_buffer[10] =  0x20;
		fake_hci_buffer[11] =  0x08;		
		fake_hci_buffer[12] = 0x01;
		fake_hci_buffer[13] = 0x00;
		fake_hci_buffer[14] = 0x01;
		fake_hci_buffer[15] = 0x01;
		fake_hci_buffer[16] = 0x99;
		fake_hci_buffer[17] = 0x19;
		fake_hci_buffer[18] = 0x99;
		fake_hci_buffer[19] = 0x19;
		bthci_cmd_ble_HandleSet_Extended_Scan_Parameters(fake_hci_buffer);
		for (int i=0;i<40;i++) fake_hci_buffer[i] = 0;
		fake_hci_buffer[8] =  0x01;
		fake_hci_buffer[9] =  0x42;
		fake_hci_buffer[10] =  0x20;
		fake_hci_buffer[11] =  0x06;		
		fake_hci_buffer[12] = 0x01;
		fake_hci_buffer[13] = 0x00;
		fake_hci_buffer[14] = 0x00;
		fake_hci_buffer[15] = 0x00;
		fake_hci_buffer[16] = 0x00;
		fake_hci_buffer[17] = 0x00;
		bthci_cmd_ble_HandleSet_Extended_Scan_Enable(fake_hci_buffer);
	}
	if (rx_enabled == 2) {
		dongle_mode = (hci_cmd_buffer[14] == 0 ? 0x00 : 0x01);
	}
	if (rx_enabled == 3) {
		memcpybt(raw_buffer,&hci_cmd_buffer[14],4);
		raw_buffer[4] = 0x70;
		encode_mosart(buffer_decoded,raw_buffer,5);
		preamble = (buffer_decoded[8] << 24) | (buffer_decoded[7] << 16) | (buffer_decoded[6] << 8) | (buffer_decoded[5]);
	}
	else if (rx_enabled == 4) {
		dongle_mode = 0x00;
		preamble = (hci_cmd_buffer[17] << 24) | (hci_cmd_buffer[16] << 16) | ((hci_cmd_buffer[15]) << 8) | hci_cmd_buffer[14];
	}
	else if (rx_enabled == 5) {
	}
	else if (rx_enabled == 6) {
		memcpybt(raw_buffer,&hci_cmd_buffer[14],5);
		preamble = ((swap_bits(raw_buffer[2]) << 24) |(swap_bits(raw_buffer[1]) << 16) | (swap_bits(raw_buffer[0]) << 8) | (swap_bits(0xAA)));
	}
	buffer[10] = 0x52;
	buffer[11] = 0x58;
	buffer[12] = (uint8_t)rx_enabled;
	buffer[13] = (uint8_t)rx_frequency;
	bthci_event_AttemptToEnqueueEventToTransport(buffer);
}
__attribute__ ( ( at ( 0x00210f00 , " " , CHIP_VER_BCM4375B1_BT , FW_VER_S20 ) ) ) void bthci_cmd_start_rx ( uint8_t * hci_cmd_buffer ) { char * buffer = bthci_event_AllocateEventAndFillHeader ( 4 + 2 , 0xFF , 4 ) ; rx_enabled = hci_cmd_buffer [ 12 ] ; rx_frequency = ( rx_enabled == 0x01 ? channelToFrequency ( hci_cmd_buffer [ 13 ] ) : hci_cmd_buffer [ 13 ] - 2 ) ; for ( int i = 0 ; i < 40 ; i ++ ) fake_hci_buffer [ i ] = 0 ; fake_hci_buffer [ 8 ] = 0x01 ; fake_hci_buffer [ 9 ] = 0x42 ; fake_hci_buffer [ 10 ] = 0x20 ; fake_hci_buffer [ 11 ] = 0x06 ; fake_hci_buffer [ 12 ] = 0x00 ; fake_hci_buffer [ 13 ] = 0x00 ; fake_hci_buffer [ 14 ] = 0x00 ; fake_hci_buffer [ 15 ] = 0x00 ; fake_hci_buffer [ 16 ] = 0x00 ; fake_hci_buffer [ 17 ] = 0x00 ; bthci_cmd_ble_HandleSet_Extended_Scan_Enable ( fake_hci_buffer ) ; if ( rx_enabled != 0 ) { for ( int i = 0 ; i < 40 ; i ++ ) fake_hci_buffer [ i ] = 0 ; fake_hci_buffer [ 8 ] = 0x01 ; fake_hci_buffer [ 9 ] = 0x41 ; fake_hci_buffer [ 10 ] = 0x20 ; fake_hci_buffer [ 11 ] = 0x08 ; fake_hci_buffer [ 12 ] = 0x01 ; fake_hci_buffer [ 13 ] = 0x00 ; fake_hci_buffer [ 14 ] = 0x01 ; fake_hci_buffer [ 15 ] = 0x01 ; fake_hci_buffer [ 16 ] = 0x99 ; fake_hci_buffer [ 17 ] = 0x19 ; fake_hci_buffer [ 18 ] = 0x99 ; fake_hci_buffer [ 19 ] = 0x19 ; bthci_cmd_ble_HandleSet_Extended_Scan_Parameters ( fake_hci_buffer ) ; for ( int i = 0 ; i < 40 ; i ++ ) fake_hci_buffer [ i ] = 0 ; fake_hci_buffer [ 8 ] = 0x01 ; fake_hci_buffer [ 9 ] = 0x42 ; fake_hci_buffer [ 10 ] = 0x20 ; fake_hci_buffer [ 11 ] = 0x06 ; fake_hci_buffer [ 12 ] = 0x01 ; fake_hci_buffer [ 13 ] = 0x00 ; fake_hci_buffer [ 14 ] = 0x00 ; fake_hci_buffer [ 15 ] = 0x00 ; fake_hci_buffer [ 16 ] = 0x00 ; fake_hci_buffer [ 17 ] = 0x00 ; bthci_cmd_ble_HandleSet_Extended_Scan_Enable ( fake_hci_buffer ) ; } if ( rx_enabled == 2 ) { dongle_mode = ( hci_cmd_buffer [ 14 ] == 0 ? 0x00 : 0x01 ) ; } if ( rx_enabled == 3 ) { memcpybt ( raw_buffer , & hci_cmd_buffer [ 14 ] , 4 ) ; raw_buffer [ 4 ] = 0x70 ; encode_mosart ( buffer_decoded , raw_buffer , 5 ) ; preamble = ( buffer_decoded [ 8 ] << 24 ) | ( buffer_decoded [ 7 ] << 16 ) | ( buffer_decoded [ 6 ] << 8 ) | ( buffer_decoded [ 5 ] ) ; } else if ( rx_enabled == 4 ) { dongle_mode = 0x00 ; preamble = ( hci_cmd_buffer [ 17 ] << 24 ) | ( hci_cmd_buffer [ 16 ] << 16 ) | ( ( hci_cmd_buffer [ 15 ] ) << 8 ) | hci_cmd_buffer [ 14 ] ; } else if ( rx_enabled == 5 ) { } else if ( rx_enabled == 6 ) { memcpybt ( raw_buffer , & hci_cmd_buffer [ 14 ] , 5 ) ; preamble = ( ( swap_bits ( raw_buffer [ 2 ] ) << 24 ) | ( swap_bits ( raw_buffer [ 1 ] ) << 16 ) | ( swap_bits ( raw_buffer [ 0 ] ) << 8 ) | ( swap_bits ( 0xAA ) ) ) ; } buffer [ 10 ] = 0x52 ; buffer [ 11 ] = 0x58 ; buffer [ 12 ] = ( uint8_t ) rx_enabled ; buffer [ 13 ] = ( uint8_t ) rx_frequency ; bthci_event_AttemptToEnqueueEventToTransport ( buffer ) ; }
Function allowing to enable and configure RX mode
Function allowing to enable and configure RX mode
// save Zigbee RX mode // save Zigbee channel // TODO: I should check the interval and trigger an error if needed // Reset fake HCI buffer // Reset fake HCI buffer // Configure fake HCI buffer to enable or disable LE scan /*
		dongle_mode = (hci_cmd_buffer[14] == 0 ? 0x00 : 0x01);
		preamble =  (hci_cmd_buffer[17] << 16)|(hci_cmd_buffer[16] << 8)| hci_cmd_buffer[15];
		*/ // Forge HCI response and send it to host