⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usb2uart.c

📁 To change pskey, convert USB bluetooth to UART
💻 C
📖 第 1 页 / 共 3 页
字号:
	{	
		while (!(chunk = get_hci_event (&buf[1])))
			Sleep(10);
		chunk++;
	}

	for (len = chunk; len != buf[1] + 2; len = len + chunk)
	{
		while (!(chunk = get_hci_event (&buf[len])))
			Sleep(10);
	}

#ifdef PKT_DUMP
	printf("Event  [%d]:    ", len);
	for (chunk=0; chunk!=len; chunk++)
		printf("%02x ", buf[chunk]);
	printf("\n");
#endif

	if (buf[0] != 0xFF)			/* manuf-specific HCI event */
		close_connection_on_error ("invalid packet received");

	if (buf[1] != ((buf[5] + (buf[6] << 8)) * 2 + 1))
		close_connection_on_error ("invalid length");

	if (buf[2] != 0xC2)			/* payload descriptor */
		close_connection_on_error ("invalid payload descriptor");
	
	if ((buf[3] + (buf[4] << 8)) != BCCMD_GETRESP)
		close_connection_on_error ("!= GETRESP");

	if ((buf[5] + (buf[6] << 8)) != bccmd_len)
		close_connection_on_error ("invalid length");

	if ((buf[7] + (buf[8] << 8)) != bccmd_seq)
		close_connection_on_error ("invalid sequence number");

	if ((buf[9] + (buf[10] << 8)) != bccmd_varid)
		close_connection_on_error ("invalid varid");

	switch  (buf[11] + (buf[12] << 8))
	{
		case 0x0000:
			/* OK status, continue */
			break;
		case 0x0001:
			close_connection_on_error ("status NO_SUCH_VARID");
			break;
		case 0x0002:
			close_connection_on_error ("status TOO_BIG");
			break;
		case 0x0003:
			close_connection_on_error ("status NO_VALUE");
			break;
		case 0x0004:
			close_connection_on_error ("status BAD_REQ");
			break;
		case 0x0005:
			close_connection_on_error ("status NO_ACCESS");
			break;
		case 0x0006:
			close_connection_on_error ("status READ_ONLY");
			break;
		case 0x0007:
			close_connection_on_error ("status WRITE_ONLY");
			break;
		case 0x0008:
			close_connection_on_error ("status ERROR");
			break;
		case 0x0009:
			close_connection_on_error ("status PERMISSION_DENIED");
			break;
		default:
			close_connection_on_error ("invalid status");
			break;
	}

	if ((buf[13] + (buf[14] << 8)) != pfkey)
		close_connection_on_error ("incorrect pfkey");

	if ((buf[15] + (buf[16] << 8)) != pskey_len)
		close_connection_on_error ("incorrect pfkey length");

	if ((buf[17] + (buf[18] << 8)) != psstore)
		close_connection_on_error ("incorrect psstore");

	if (!write)
	{
		memcpy(data, &buf[19], pskey_len * 2);
		return pskey_len * 2;
	}
	else
		return 0;

}

/* read CSR firmware build id/number */
static uint16 buildid(void)
{
	uint16 bccmd_req, bccmd_varid, bccmd_len;
	unsigned char buf[258];
	int len = 0, chunk = 0;

	bccmd_req = BCCMD_GETREQ;
	
	bccmd_seq++;
	bccmd_varid = 0x2819; 			/* varid: BUILDID */
	bccmd_len = 9;					/* minimum possible length, one uint16 is wasted */

	memset(&buf, 0, sizeof(buf));

	/* need to construct a hand-crafted HCI cmd pkt */
	buf[0] = 0x00; buf[1] = 0xFC;	/* OGF = 0x3F & OCF = 0x00 */

	buf[2] = bccmd_len * 2 + 1;		/* pkt len - 3 */

	buf[3] = 0xC2;					/* payload descriptor: last frag =1; 
									first frag = 1; channel = 2 */

	buf[4] = bccmd_req & 0xFF; buf[5] = bccmd_req >> 8;

	buf[6] = bccmd_len & 0xFF; buf[7] = bccmd_len >> 8;

	buf[8]  = bccmd_seq & 0xFF; buf[9] = bccmd_seq >> 8;

	buf[10] = bccmd_varid & 0xFF; buf[11] = bccmd_varid >> 8;

	buf[12] = 0x00; buf[13] = 0x00;	/* status */


	/*  FIXME: IOCTL_CSRBC01_SEND_HCI_COMMAND doesn't return the number of bytes written? */
	send_hci_command (&buf, buf[2] + 3);

#ifdef PKT_DUMP
	printf("HCI cmd[%d]: ", buf[2] + 3);
	for (chunk=0; chunk != buf[2] + 3; chunk++)
		printf("%02x ", buf[chunk]);
	printf("\n");
#endif

	/* not really efficient, but who cares? */
	while (!(chunk = get_hci_event (&buf)))
		Sleep(10);
	
	if (chunk == 1)					/* too short to read packet length */
	{	
		while (!(chunk = get_hci_event (&buf[1])))
			Sleep(10);
		chunk++;
	}

	for (len = chunk; len != buf[1] + 2; len = len + chunk)
	{
		while (!(chunk = get_hci_event (&buf[len])))
			Sleep(10);
	}

#ifdef PKT_DUMP
	printf("Event  [%d]:    ", len);
	for (chunk=0; chunk!=len; chunk++)
		printf("%02x ", buf[chunk]);
	printf("\n");
#endif

	if (buf[0] != 0xFF)			/* manuf-specific HCI event */
		close_connection_on_error ("invalid packet received");

	if (buf[1] != 9 * 2 + 1)
		close_connection_on_error ("hci event has invalid length");

	if (buf[2] != 0xC2)			/* payload descriptor */
		close_connection_on_error ("invalid payload descriptor");
	
	if ((buf[3] + (buf[4] << 8)) != BCCMD_GETRESP)
		close_connection_on_error ("!= GETRESP");

	if ((buf[5] + (buf[6] << 8)) != 9)
		close_connection_on_error ("invalid length");

	if ((buf[7] + (buf[8] << 8)) != bccmd_seq)
		close_connection_on_error ("invalid sequence number");

	if ((buf[9] + (buf[10] << 8)) != bccmd_varid)
		close_connection_on_error ("invalid varid");

	switch  (buf[11] + (buf[12] << 8))
	{
		case 0x0000:
			/* OK status, continue */
			break;
		case 0x0001:
			close_connection_on_error ("status NO_SUCH_VARID");
			break;
		case 0x0002:
			close_connection_on_error ("status TOO_BIG");
			break;
		case 0x0003:
			close_connection_on_error ("status NO_VALUE");
			break;
		case 0x0004:
			close_connection_on_error ("status BAD_REQ");
			break;
		case 0x0005:
			close_connection_on_error ("status NO_ACCESS");
			break;
		case 0x0006:
			close_connection_on_error ("status READ_ONLY");
			break;
		case 0x0007:
			close_connection_on_error ("status WRITE_ONLY");
			break;
		case 0x0008:
			close_connection_on_error ("status ERROR");
			break;
		case 0x0009:
			close_connection_on_error ("status PERMISSION_DENIED");
			break;
		default:
			close_connection_on_error ("invalid status");
			break;
	}

	return buf[13] + (buf[14] << 8);

}


/* set UART baud rate, stop bit(s), parity 
 *
 * The change happens immediately, most probably the response on this command will be received back
 * after the new UART settings took effect.
 * 
 * Parameters:
 *
 * baud = baud rate, the value is used as a clock divisor, any value can be programmed.
 *        the common values are: 9600, 19200, ... 115200, 230400, 460800, 921600.
 * stop = number of stop bits, either 1 or 2
 * parity = parity, 0 - no parity, 1 - even parity, 2 - odd parity
 *
*/
static void uart_config(int baud, int stop, int parity)
{
	uint16 bccmd_req, bccmd_varid, bccmd_len, divisor;
	unsigned char buf[258];
	int len = 0, chunk = 0;

	bccmd_req = BCCMD_SETREQ;
	
	bccmd_seq++;
	bccmd_varid = 0x6802; 			/* varid: CONFIG_UART */
	bccmd_len = 9;					/* minimum possible length, one uint16 is wasted */

	memset(&buf, 0, sizeof(buf));

	/* need to construct a hand-crafted HCI cmd pkt */
	buf[0] = 0x00; buf[1] = 0xFC;	/* OGF = 0x3F & OCF = 0x00 */

	buf[2] = bccmd_len * 2 + 1;		/* pkt len - 3 */

	buf[3] = 0xC2;					/* payload descriptor: last frag =1; 
									first frag = 1; channel = 2 */

	buf[4] = bccmd_req & 0xFF; buf[5] = bccmd_req >> 8;

	buf[6] = bccmd_len & 0xFF; buf[7] = bccmd_len >> 8;

	buf[8]  = bccmd_seq & 0xFF; buf[9] = bccmd_seq >> 8;

	buf[10] = bccmd_varid & 0xFF; buf[11] = bccmd_varid >> 8;

	buf[12] = 0x00; buf[13] = 0x00;	/* status */

	divisor = (baud*64+7812)/15625;

	if (stop == 1)
		divisor |= 0x0000;
	else if (stop == 2)
		divisor |= 0x2000;
	else
		close_connection_on_error ("invalid stop bit number");
	
	if (parity == 0)
		divisor |= 0x0000;
	else if (parity == 1)
		divisor |= 0xC000;
	else if (parity == 2)
		divisor |= 0x4000;
	else
		close_connection_on_error ("invalid parity bit value");

	buf[14] = divisor & 0xFF; buf[15] = divisor >> 8;

	/*  FIXME: IOCTL_CSRBC01_SEND_HCI_COMMAND doesn't return the number of bytes written? */
	send_hci_command (&buf, buf[2] + 3);

#ifdef PKT_DUMP
	printf("HCI cmd[%d]: ", buf[2] + 3);
	for (chunk=0; chunk != buf[2] + 3; chunk++)
		printf("%02x ", buf[chunk]);
	printf("\n");
#endif

	/* not really efficient, but who cares? */
	while (!(chunk = get_hci_event (&buf)))
		Sleep(10);
	
	if (chunk == 1)					/* too short to read packet length */
	{	
		while (!(chunk = get_hci_event (&buf[1])))
			Sleep(10);
		chunk++;
	}

	for (len = chunk; len != buf[1] + 2; len = len + chunk)
	{
		while (!(chunk = get_hci_event (&buf[len])))
			Sleep(10);
	}

#ifdef PKT_DUMP
	printf("Event  [%d]:    ", len);
	for (chunk=0; chunk!=len; chunk++)
		printf("%02x ", buf[chunk]);
	printf("\n");
#endif

	if (buf[0] != 0xFF)			/* manuf-specific HCI event */
		close_connection_on_error ("invalid packet received");

	if (buf[1] != 9 * 2 + 1)
		close_connection_on_error ("hci event has invalid length");

	if (buf[2] != 0xC2)			/* payload descriptor */
		close_connection_on_error ("invalid payload descriptor");
	
	if ((buf[3] + (buf[4] << 8)) != BCCMD_GETRESP)
		close_connection_on_error ("!= GETRESP");

	if ((buf[5] + (buf[6] << 8)) != 9)
		close_connection_on_error ("invalid length");

	if ((buf[7] + (buf[8] << 8)) != bccmd_seq)
		close_connection_on_error ("invalid sequence number");

	if ((buf[9] + (buf[10] << 8)) != bccmd_varid)
		close_connection_on_error ("invalid varid");

	switch  (buf[11] + (buf[12] << 8))
	{
		case 0x0000:
			/* OK status, continue */
			break;
		case 0x0001:
			close_connection_on_error ("status NO_SUCH_VARID");
			break;
		case 0x0002:
			close_connection_on_error ("status TOO_BIG");
			break;
		case 0x0003:
			close_connection_on_error ("status NO_VALUE");
			break;
		case 0x0004:
			close_connection_on_error ("status BAD_REQ");
			break;
		case 0x0005:
			close_connection_on_error ("status NO_ACCESS");
			break;
		case 0x0006:
			close_connection_on_error ("status READ_ONLY");
			break;
		case 0x0007:
			close_connection_on_error ("status WRITE_ONLY");
			break;
		case 0x0008:
			close_connection_on_error ("status ERROR");
			break;
		case 0x0009:
			close_connection_on_error ("status PERMISSION_DENIED");
			break;
		default:
			close_connection_on_error ("invalid status");
			break;
	}

	return;

}

/* enter DEEP_SLEEP mode
 *
 * The change happens approx. 0.5s after sending event back
 *
*/
static void deep_sleep(void)
{
	uint16 bccmd_req, bccmd_varid, bccmd_len, testid;
	unsigned char buf[258];
	int len = 0, chunk = 0;

	bccmd_req = BCCMD_SETREQ;
	
	bccmd_seq++;
	bccmd_varid = 0x5004; 			/* varid: RADIOTEST */
	bccmd_len = 9;					/* minimum possible length, one uint16 is wasted */

	memset(&buf, 0, sizeof(buf));

	/* need to construct a hand-crafted HCI cmd pkt */
	buf[0] = 0x00; buf[1] = 0xFC;	/* OGF = 0x3F & OCF = 0x00 */

	buf[2] = bccmd_len * 2 + 1;		/* pkt len - 3 */

	buf[3] = 0xC2;					/* payload descriptor: last frag =1; 
									first frag = 1; channel = 2 */

	buf[4] = bccmd_req & 0xFF; buf[5] = bccmd_req >> 8;

	buf[6] = bccmd_len & 0xFF; buf[7] = bccmd_len >> 8;

	buf[8]  = bccmd_seq & 0xFF; buf[9] = bccmd_seq >> 8;

	buf[10] = bccmd_varid & 0xFF; buf[11] = bccmd_varid >> 8;

	buf[12] = 0x00; buf[13] = 0x00;	/* status */

	testid = 10;			/* DEEP_SLEEP */

	buf[14] = testid & 0xFF; buf[15] = testid >> 8;

	/*  FIXME: IOCTL_CSRBC01_SEND_HCI_COMMAND doesn't return the number of bytes written? */
	send_hci_command (&buf, buf[2] + 3);

#ifdef PKT_DUMP
	printf("HCI cmd[%d]: ", buf[2] + 3);
	for (chunk=0; chunk != buf[2] + 3; chunk++)
		printf("%02x ", buf[chunk]);
	printf("\n");
#endif

	/* not really efficient, but who cares? */
	while (!(chunk = get_hci_event (&buf)))
		Sleep(10);
	
	if (chunk == 1)					/* too short to read packet length */
	{	
		while (!(chunk = get_hci_event (&buf[1])))
			Sleep(10);
		chunk++;
	}

	for (len = chunk; len != buf[1] + 2; len = len + chunk)
	{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -