Exemple #1
0
static void advertising_packet(const void *data, uint8_t size)
{
	const uint8_t *ptr = data;
	uint8_t pdu_type, length, win_size, hop, sca;
	bool tx_add, rx_add;
	uint32_t access_addr, crc_init;
	uint16_t win_offset, interval, latency, timeout;
	const char *str;

	if (size < 2) {
		print_text(COLOR_ERROR, "packet too short");
		packet_hexdump(data, size);
		return;
	}

	pdu_type = ptr[0] & 0x0f;
	tx_add = !!(ptr[0] & 0x40);
	rx_add = !!(ptr[0] & 0x80);
	length = ptr[1] & 0x3f;

	switch (pdu_type) {
	case 0x00:
		str = "ADV_IND";
		break;
	case 0x01:
		str = "ADV_DIRECT_IND";
		break;
	case 0x02:
		str = "ADV_NONCONN_IND";
		break;
	case 0x03:
		str = "SCAN_REQ";
		break;
	case 0x04:
		str = "SCAN_RSP";
		break;
	case 0x05:
		str = "CONNECT_REQ";
		break;
	case 0x06:
		str = "ADV_SCAN_IND";
		break;
	default:
		str = "Reserved";
		break;
	}

	print_field("Type: %s (0x%2.2x)", str, pdu_type);
	print_field("TxAdd: %u", tx_add);
	print_field("RxAdd: %u", rx_add);
	print_field("Length: %u", length);

	if (length != size - 2) {
		print_text(COLOR_ERROR, "packet size mismatch");
		packet_hexdump(data + 2, size - 2);
		return;
	}

	switch (pdu_type) {
	case 0x00:	/* ADV_IND */
	case 0x02:	/* AVD_NONCONN_IND */
	case 0x06:	/* ADV_SCAN_IND */
	case 0x04:	/* SCAN_RSP */
		if (length < 6) {
			print_text(COLOR_ERROR, "payload too short");
			packet_hexdump(data + 2, length);
			return;
		}

		packet_print_addr("Advertiser address", data + 2, tx_add);
		packet_print_ad(data + 8, length - 6);
		break;

	case 0x01:	/* ADV_DIRECT_IND */
		if (length < 12) {
			print_text(COLOR_ERROR, "payload too short");
			packet_hexdump(data + 2, length);
			return;
		}

		packet_print_addr("Advertiser address", data + 2, tx_add);
		packet_print_addr("Inititator address", data + 8, rx_add);
		break;

	case 0x03:	/* SCAN_REQ */
		if (length < 12) {
			print_text(COLOR_ERROR, "payload too short");
			packet_hexdump(data + 2, length);
			return;
		}

		packet_print_addr("Scanner address", data + 2, tx_add);
		packet_print_addr("Advertiser address", data + 8, rx_add);
		break;

	case 0x05:	/* CONNECT_REQ */
		if (length < 34) {
			print_text(COLOR_ERROR, "payload too short");
			packet_hexdump(data + 2, length);
			return;
		}

		packet_print_addr("Inititator address", data + 2, tx_add);
		packet_print_addr("Advertiser address", data + 8, rx_add);

		access_addr = ptr[14] | ptr[15] << 8 |
					ptr[16] << 16 | ptr[17] << 24;
		crc_init = ptr[18] | ptr[19] << 8 | ptr[20] << 16;

		print_field("Access address: 0x%8.8x", access_addr);
		print_field("CRC init: 0x%6.6x", crc_init);

		set_crc_init(access_addr, crc24_bit_reverse(crc_init));

		win_size = ptr[21];
		win_offset = ptr[22] | ptr[23] << 8;
		interval = ptr[24] | ptr[25] << 8;
		latency = ptr[26] | ptr[27] << 8;
		timeout = ptr[28] | ptr[29] << 8;

		print_field("Transmit window size: %u", win_size);
		print_field("Transmit window offset: %u", win_offset);
		print_field("Connection interval: %u", interval);
		print_field("Connection slave latency: %u", latency);
		print_field("Connection supervision timeout: %u", timeout);

		packet_print_channel_map_ll(ptr + 30);

		hop = ptr[35] & 0x1f;
		sca = (ptr[35] & 0xe0) >> 5;

		switch (sca) {
		case 0:
			str = "251 ppm to 500 ppm";
			break;
		case 1:
			str = "151 ppm to 250 ppm";
			break;
		case 2:
			str = "101 ppm to 150ppm";
			break;
		case 3:
			str = "76 ppm to 100 ppm";
			break;
		case 4:
			str = "51 ppm to 75 ppm";
			break;
		case 5:
			str = "31 ppm to 50 ppm";
			break;
		case 6:
			str = "21 ppm to 30 ppm";
			break;
		case 7:
			str = "0 ppm to 20 ppm";
			break;
		default:
			str = "Invalid";
			break;
		}

		print_field("Hop increment: %u", hop);
		print_field("Sleep clock accuracy: %s (%u)", str, sca);
		break;

	default:
		packet_hexdump(data + 2, length);
		break;
	}
}
Exemple #2
0
static void write_bd_addr_cmd(const void *data, uint8_t size)
{
	packet_print_addr("Address", data, false);
}