예제 #1
0
void _bt_rfcomm_send_uih_msc_cmd(uint16_t source_cid, uint8_t initiator, uint8_t channel, uint8_t signals)
{
	uint8_t address = (1 << 0) | (initiator << 1); // EA and C/R bit set - always server channel 0
	uint8_t payload[4]; 
	uint8_t pos = 0;
	payload[pos++] = BT_RFCOMM_MSC_CMD;
	payload[pos++] = 2 << 1 | 1;  // len
	payload[pos++] = (1 << 0) | (1 << 1) | (0 << 2) | (channel << 3); // shouldn't D = initiator = 1 ?
	payload[pos++] = signals;
	rfcomm_send_packet(source_cid, address, BT_RFCOMM_UIH, 0, (uint8_t *) payload, pos);
}
예제 #2
0
int	rfcomm_msc_cmd(uint8_t *packet, uint16_t size)
{
	printf("Received BT_RFCOMM_MSC_CMD\n");
	printf("Responding to 'I'm ready'\n");
		// fine with this
	uint8_t address = packet[0] | 2; // set response 
	packet[3]  = BT_RFCOMM_MSC_RSP;  //  "      "
	rfcomm_send_packet(bt_accessor(0)->connflags.source_cid, address, BT_RFCOMM_UIH, 0x30, (uint8_t*)&packet[3], 4);
	bt_accessor(0)->connflags.msc_resp_send = 1;
	return (0);
}
예제 #3
0
void _bt_rfcomm_send_uih_pn_command(uint16_t source_cid, uint8_t initiator, uint8_t channel, uint16_t max_frame_size){
	uint8_t payload[10];
	uint8_t address = (1 << 0) | (initiator << 1); // EA and C/R bit set - always server channel 0
	uint8_t pos = 0;
	payload[pos++] = BT_RFCOMM_PN_CMD;
	payload[pos++] = 8 << 1 | 1;  // len
	payload[pos++] = channel << 1;
	payload[pos++] = 0xf0; // pre defined for Bluetooth, see 5.5.3 of TS 07.10 Adaption for RFCOMM
	payload[pos++] = 0; // priority
	payload[pos++] = 0; // max 60 seconds ack
	payload[pos++] = max_frame_size & 0xff; // max framesize low
	payload[pos++] = max_frame_size >> 8;   // max framesize high
	payload[pos++] = 0x00; // number of retransmissions
	payload[pos++] = 0x00; // unused error recovery window
	rfcomm_send_packet(source_cid, address, BT_RFCOMM_UIH, 0, (uint8_t *) payload, pos);
}
예제 #4
0
파일: commons.c 프로젝트: ap4y/iSAP
void process_rfcomm_packet(uint8_t *packet)
{

	switch (packet[0]) {
		case (3 | (0 << 3)):
			
			process_rfcomm_init(packet);			
			break;
		case ((1 << 0) | (1 << 1) | (0 << 2) | (RFCOMM_CHANNEL_ID << 3)):
		
			process_rfcomm_data(packet);
			break;

		default:
			break;
	}
																	
	uint8_t send_credits_packet = 0;
	
	if (credits_used >= CREDITS_CNT ) {
		send_credits_packet = 1;
		credits_used -= CREDITS_CNT;
	}
	
	if (msc_resp_send && msc_resp_received) {
		send_credits_packet = 1;
		msc_resp_send = msc_resp_received = 0;				
	}
	
	if (send_credits_packet) {
		uint8_t initiator = 0;
		uint8_t address = (1 << 0) | (initiator << 1) |  (initiator << 1) | (RFCOMM_CHANNEL_ID << 3); 
		rfcomm_send_packet(source_cid, address, BT_RFCOMM_UIH_PF, CREDITS_CNT, NULL, 0);
	}
	
	if (!packet_processed && DEBUG){
		printf("%02x: address %02x, control %02x: ", packet[3], packet[0], packet[1]);
		//hexdump( packet, size );
	}		
}
예제 #5
0
파일: rfcomm.c 프로젝트: ap4y/iSAP
void _bt_rfcomm_send_uih_test_cmd(uint16_t source_cid, uint8_t initiator, uint8_t channel)
{
	uint8_t address = (1 << 0) | (initiator << 1) | (initiator << 1) | (channel << 3) ; // EA and C/R bit set - always server channel 0
	uint8_t payload[13]; 
	uint8_t pos = 0;
	payload[pos++] = BT_RFCOMM_TEST_CMD;
	payload[pos++] = 11 << 1 | 1;  // len
	
	payload[pos++] = 0x00;
	payload[pos++] = 0x01;
	payload[pos++] = 0x02;
	payload[pos++] = 0x03;
	payload[pos++] = 0x04;
	payload[pos++] = 0x05;
	payload[pos++] = 0x06;
	payload[pos++] = 0x07;
	payload[pos++] = 0x08;
	payload[pos++] = 0x09;
	payload[pos++] = 0x0a;
	
	rfcomm_send_packet(source_cid, address, BT_RFCOMM_UIH, 0, (uint8_t *) payload, pos);
}
예제 #6
0
void comm_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
	bd_addr_t event_addr;
	
	static uint8_t msc_resp_send = 0;
	static uint8_t msc_resp_received = 0;
	static uint8_t credits_used = 0;
	static uint8_t credits_free = 0;
	uint8_t packet_processed = 0;
	
	switch (packet_type) {
			
		case L2CAP_DATA_PACKET:
			// rfcomm: data[8] = addr
			// rfcomm: data[9] = command
			
			// 	received 1. message BT_RF_COMM_UA
			if (size == 4 && packet[1] == BT_RFCOMM_UA && packet[0] == 0x03){
				packet_processed++;
				printf("Received RFCOMM unnumbered acknowledgement for channel 0 - multiplexer working\n");
				printf("Sending UIH Parameter Negotiation Command\n");
				_bt_rfcomm_send_uih_pn_command(source_cid, 1, RFCOMM_CHANNEL_ID, 100);
			}
			
			//  received UIH Parameter Negotiation Response
			if (size == 14 && packet[1] == BT_RFCOMM_UIH && packet[3] == BT_RFCOMM_PN_RSP){
				packet_processed++;
				printf("UIH Parameter Negotiation Response\n");
				printf("Sending SABM #%u\n", RFCOMM_CHANNEL_ID);
				_bt_rfcomm_send_sabm(source_cid, 1, RFCOMM_CHANNEL_ID);
			}
			
			// 	received 2. message BT_RF_COMM_UA
			if (size == 4 && packet[1] == BT_RFCOMM_UA && packet[0] == ((RFCOMM_CHANNEL_ID << 3) | 3) ){
				packet_processed++;
				printf("Received RFCOMM unnumbered acknowledgement for channel %u - channel opened\n", RFCOMM_CHANNEL_ID);
				printf("Sending MSC  'I'm ready'\n");
				_bt_rfcomm_send_uih_msc_cmd(source_cid, 1, RFCOMM_CHANNEL_ID, 0x8d);  // ea=1,fc=0,rtc=1,rtr=1,ic=0,dv=1
			}
			
			// received BT_RFCOMM_MSC_CMD
			if (size == 8 && packet[1] == BT_RFCOMM_UIH && packet[3] == BT_RFCOMM_MSC_CMD){
				packet_processed++;
				printf("Received BT_RFCOMM_MSC_CMD\n");
				printf("Responding to 'I'm ready'\n");
				// fine with this
				uint8_t address = packet[0] | 2; // set response 
				packet[3]  = BT_RFCOMM_MSC_RSP;  //  "      "
				rfcomm_send_packet(source_cid, address, BT_RFCOMM_UIH, 0x30, (uint8_t*)&packet[3], 4);
				msc_resp_send = 1;
			}
			
			// received BT_RFCOMM_MSC_RSP
			if (size == 8 && packet[1] == BT_RFCOMM_UIH && packet[3] == BT_RFCOMM_MSC_RSP){
				packet_processed++;
				msc_resp_received = 1;
			}
			
			if (packet[1] == BT_RFCOMM_UIH && packet[0] == ((RFCOMM_CHANNEL_ID<<3)|1)){
				packet_processed++;
				credits_used++;
				if(DEBUG){
					printf("RX: address %02x, control %02x: ", packet[0], packet[1]);
					hexdump( (uint8_t*) &packet[3], size-4);
				}
				int written = 0;
				int length = size-4;
				int start_of_data = 3;
				//write data to fifo
				while (length) {
					if ((written = write(fifo_fd, &packet[start_of_data], length)) == -1) {
						printf("Error writing to FIFO\n");
					} else {
						length -= written;
					}
				}
			}
			
			if (packet[1] == BT_RFCOMM_UIH_PF && packet[0] == ((RFCOMM_CHANNEL_ID<<3)|1)){
				packet_processed++;
				credits_used++;
				if (!credits_free) {
					printf("Got %u credits, can send!\n", packet[2]);
				}
				credits_free = packet[2];
				if(DEBUG){
					printf("RX: address %02x, control %02x: ", packet[0], packet[1]);
					hexdump( (uint8_t *) &packet[4], size-5);				
				}
				int written = 0;
				int length = size-5;
				int start_of_data = 4;
				//write data to fifo
				while (length) {
					if ((written = write(fifo_fd, &packet[start_of_data], length)) == -1) {
						printf("Error writing to FIFO\n");
					} else {
						length -= written;
					}
				}
			}
			
			uint8_t send_credits_packet = 0;
			
			if (credits_used >= NR_CREDITS ) {
				send_credits_packet = 1;
				credits_used -= NR_CREDITS;
			}
			
			if (msc_resp_send && msc_resp_received) {
				send_credits_packet = 1;
				msc_resp_send = msc_resp_received = 0;
				
				printf("RFCOMM up and running!\n");
			}
			
			if (send_credits_packet) {
				// send 0x30 credits
				uint8_t initiator = 1;
				uint8_t address = (1 << 0) | (initiator << 1) |  (initiator << 1) | (RFCOMM_CHANNEL_ID << 3); 
				rfcomm_send_packet(source_cid, address, BT_RFCOMM_UIH_PF, NR_CREDITS, NULL, 0);
			}
			
			if (!packet_processed){
				// just dump data for now
				printf("??: address %02x, control %02x: ", packet[0], packet[1]);
				hexdump( packet, size );
			}
			
			break;
			
		case HCI_EVENT_PACKET:
			
			switch (packet[0]) {
					
				case BTSTACK_EVENT_POWERON_FAILED:
					// handle HCI init failure
					printf("HCI Init failed - make sure you have turned off Bluetooth in the System Settings\n");
					exit(1);
					break;		
					
				case BTSTACK_EVENT_STATE:
					// bt stack activated, get started - use authentication yes/no
					if (packet[2] == HCI_STATE_WORKING) {
						bt_send_cmd(&hci_write_authentication_enable, 1);
					}
					break;
					
				case HCI_EVENT_LINK_KEY_REQUEST:
					// link key request
					bt_flip_addr(event_addr, &packet[2]);
					bt_send_cmd(&hci_link_key_request_negative_reply, &event_addr);
					break;
					
				case HCI_EVENT_PIN_CODE_REQUEST:
					// inform about pin code request
					bt_flip_addr(event_addr, &packet[2]); 
					bt_send_cmd(&hci_pin_code_request_reply, &event_addr, 4, PIN);
					printf("Please enter PIN %s on remote device\n", PIN);
					break;
					
				case L2CAP_EVENT_CHANNEL_OPENED:
					// inform about new l2cap connection
					bt_flip_addr(event_addr, &packet[3]);
					uint16_t psm = READ_BT_16(packet, 11); 
					source_cid = READ_BT_16(packet, 13); 
					con_handle = READ_BT_16(packet, 9);
					if (packet[2] == 0) {
						printf("Channel successfully opened: ");
						print_bd_addr(event_addr);
						printf(", handle 0x%02x, psm 0x%02x, source cid 0x%02x, dest cid 0x%02x\n",
							   con_handle, psm, source_cid,  READ_BT_16(packet, 15));
						
						// send SABM command on dlci 0
						printf("Sending SABM #0\n");
						_bt_rfcomm_send_sabm(source_cid, 1, 0);
					} else {
						printf("L2CAP connection to device ");
						print_bd_addr(event_addr);
						printf(" failed. status code %u\n", packet[2]);
						exit(1);
					}
					break;
					
				case HCI_EVENT_DISCONNECTION_COMPLETE:
					// connection closed -> quit test app
					printf("Basebank connection closed, exit.\n");
					exit(0);
					break;
					
				case HCI_EVENT_COMMAND_COMPLETE:
					// connect to RFCOMM device (PSM 0x03) at addr
					if ( COMMAND_COMPLETE_EVENT(packet, hci_write_authentication_enable) ) {
						bt_send_cmd(&l2cap_create_channel, addr, 0x03);
					}
					break;
					
				default:
					// unhandled event
					if(DEBUG) printf("unhandled event : %02x\n", packet[0]);
					break;
			}
			break;
		default:
			// unhandled packet type
			if(DEBUG) printf("unhandled packet type : %02x\n", packet_type);
			break;
	}
}
예제 #7
0
void _bt_rfcomm_send_uih_data(uint16_t source_cid, uint8_t initiator, uint8_t channel, uint8_t *data, uint16_t len) {
	uint8_t address = (1 << 0) | (initiator << 1) |  (initiator << 1) | (channel << 3); 
	rfcomm_send_packet(source_cid, address, BT_RFCOMM_UIH, 0, data, len);
}	
예제 #8
0
void _bt_rfcomm_send_sabm(uint16_t source_cid, uint8_t initiator, uint8_t channel)
{
	uint8_t address = (1 << 0) | (initiator << 1) |  (initiator << 1) | (channel << 3); 
	rfcomm_send_packet(source_cid, address, BT_RFCOMM_SABM, 0, NULL, 0);
}
예제 #9
0
파일: rfcomm.c 프로젝트: ap4y/iSAP
void _bt_rfcomm_send_ua(uint16_t source_cid, uint8_t address)
{
	//uint8_t address = (1 << 0) | (initiator << 1) |  (initiator << 1) | (channel << 3); 
	rfcomm_send_packet(source_cid, address, BT_RFCOMM_UA, 0, NULL, 0);
}