Archive for the Bluetooth Category

Get Bluetooth Dongle Address for WINCE 5.0/WM5/WM6

Posted in Bluetooth, WinCE on 2008 年 06 月 27 日 by Kun-Yi

Just need 2 step.

  1. Get “BTD0:" handle
  2. Call DeviceIOControl, ReadLocalAddr (14)
BOOL GetBTH_ADDR(BT_ADDR *btaddr)
{
	HANDLE hDev = INVALID_HANDLE_VALUE;

	unsigned buff[8];

	memset(buff, 0, sizeof(buff));

	*btaddr = 0;

	hDev = CreateFile(L"BTD0:", GENERIC_READ | GENERIC_WRITE,
		FILE_SHARE_READ | FILE_SHARE_WRITE,
		NULL,
		OPEN_EXISTING,
		0,
		NULL);

	if (hDev == INVALID_HANDLE_VALUE)
	{
		return FALSE;
	}

#define BT_IOCTL_ReadLocalAddr 14

	int iErr = DeviceIoControl(hDev, BT_IOCTL_ReadLocalAddr, &buff, sizeof(buff), NULL, NULL, NULL, NULL);
	CloseHandle(hDev);
	hDev = INVALID_HANDLE_VALUE;

	if (iErr)
	{
		*btaddr = *((BT_ADDR*)buff);
		return TRUE;
	}

	return FALSE;
}

static WCHAR NUM2HEX(UINT i)
{
	const WCHAR idx[] = { L'0', L'1', L'2', L'3',
			L'4', L'5', L'6', L'7',
			L'8', L'9', L'A', L'B',
			L'C', L'D', L'E', L'F' };
	i &= 0xF;
	return idx[i];
/*
	if (i < 10)
	 return i + L'0';

	i -= 10;
	return i + L'A';
*/
}

static WCHAR LOBYTE2WC(const UCHAR x)
{
	return NUM2HEX(x & 0x0F);
}

static WCHAR HIBYTE2WC(const UCHAR x)
{
	return NUM2HEX(x>>4);
}

void BTADDR2WC(WCHAR* buff, BT_ADDR _btAddr, UINT sz)
{
	BYTE *pB = (BYTE*)&_btAddr+5;
	UINT i = 0;

	if (sz < (6*3 + 1))
		return;

	do
	{
		buff[i*3]=HIBYTE2WC(*(pB-i));
		buff[i*3+1]=LOBYTE2WC(*(pB-i));
		buff[i*3+2]=L':';
	} while (++i < 6);
	buff[i*3-1] = L'/0';
}

Bluetooth Service UUID List

Posted in Bluetooth on 2007 年 06 月 08 日 by Kun-Yi

今天找了一下 關於 Bluetooth 的標準 Service/Profile 的 UUID ,但是看了一下 Specification Doucments 都只有 16bits 長,這是所謂的UUID16格式

後來才了解,原來Bluetooth 將UUID 的部份固定,只取16bits 作為各種 Service 的區分,這樣可以節省分析 SDP Record and 與程式空間,避免增加 Bluetooth Device 的成本。

底下的值可以從 windows XP or Server 2003 SDK 的 bt_sdp.h or BlueZ 的 sdp.h(UUID16) 中找到定義,可以觀察出 下列的固定序列除了替換 XXXX部份

‘{0000xxxx-0000-1000-8000-00805F9B34FB}’,而XXXX 部份就是 所謂的 UUID16 定義。

Protocols UUID http://www.bluetooth.org/Technical/AssignedNumbers/service_discovery.htm
BASE UUID 00000000-0000-1000-8000-00805F9B34FB
SDP_PROTOCOL_UUID         = '{00000001-0000-1000-8000-00805F9B34FB}';
UDP_PROTOCOL_UUID         = '{00000002-0000-1000-8000-00805F9B34FB}';
RFCOMM_PROTOCOL_UUID      = '{00000003-0000-1000-8000-00805F9B34FB}';
TCP_PROTOCOL_UUID         = '{00000004-0000-1000-8000-00805F9B34FB}';
TCSBIN_PROTOCOL_UUID      = '{00000005-0000-1000-8000-00805F9B34FB}';
TCSAT_PROTOCOL_UUID       = '{00000006-0000-1000-8000-00805F9B34FB}';
OBEX_PROTOCOL_UUID        = '{00000008-0000-1000-8000-00805F9B34FB}';
IP_PROTOCOL_UUID          = '{00000009-0000-1000-8000-00805F9B34FB}';
FTP_PROTOCOL_UUID         = '{0000000A-0000-1000-8000-00805F9B34FB}';
HTTP_PROTOCOL_UUID        = '{0000000C-0000-1000-8000-00805F9B34FB}';
WSP_PROTOCOL_UUID         = '{0000000E-0000-1000-8000-00805F9B34FB}';
BNEP_PROTOCOL_UUID        = '{0000000F-0000-1000-8000-00805F9B34FB}';
UPNP_PROTOCOL_UUID        = '{00000010-0000-1000-8000-00805F9B34FB}';
HID_PROTOCOL_UUID         = '{00000011-0000-1000-8000-00805F9B34FB}';
HCCC_PROTOCOL_UUID        = '{00000012-0000-1000-8000-00805F9B34FB}';
HCDC_PROTOCOL_UUID        = '{00000014-0000-1000-8000-00805F9B34FB}';
HN_PROTOCOL_UUID          = '{00000016-0000-1000-8000-00805F9B34FB}';
AVCTP_PROTOCOL_UUID       = '{00000017-0000-1000-8000-00805F9B34FB}';
AVDTP_PROTOCOL_UUID       = '{00000019-0000-1000-8000-00805F9B34FB}';
CMPT_PROTOCOL_UUID        = '{0000001B-0000-1000-8000-00805F9B34FB}';
UDI_C_PLANE_PROTOCOL_UUID = '{0000001D-0000-1000-8000-00805F9B34FB}';
L2CAP_PROTOCOL_UUID       = '{00000100-0000-1000-8000-00805F9B34FB}';
Ref. Service class IDs http://www.bluetooth.org/Technical/AssignedNumbers/service_discovery.htm
ServiceDiscoveryServerServiceClassID_UUID       = '{00001000-0000-1000-8000-00805F9B34FB}';
BrowseGroupDescriptorServiceClassID_UUID        = '{00001001-0000-1000-8000-00805F9B34FB}';
PublicBrowseGroupServiceClass_UUID              = '{00001002-0000-1000-8000-00805F9B34FB}';
SerialPortServiceClass_UUID                     = '{00001101-0000-1000-8000-00805F9B34FB}';
LANAccessUsingPPPServiceClass_UUID              = '{00001102-0000-1000-8000-00805F9B34FB}';
DialupNetworkingServiceClass_UUID               = '{00001103-0000-1000-8000-00805F9B34FB}';
IrMCSyncServiceClass_UUID                       = '{00001104-0000-1000-8000-00805F9B34FB}';
OBEXObjectPushServiceClass_UUID                 = '{00001105-0000-1000-8000-00805F9B34FB}';
OBEXFileTransferServiceClass_UUID               = '{00001106-0000-1000-8000-00805F9B34FB}';
IrMCSyncCommandServiceClass_UUID                = '{00001107-0000-1000-8000-00805F9B34FB}';
HeadsetServiceClass_UUID                        = '{00001108-0000-1000-8000-00805F9B34FB}';
CordlessTelephonyServiceClass_UUID              = '{00001109-0000-1000-8000-00805F9B34FB}';
AudioSourceServiceClass_UUID                    = '{0000110A-0000-1000-8000-00805F9B34FB}';
AudioSinkServiceClass_UUID                      = '{0000110B-0000-1000-8000-00805F9B34FB}';
AVRemoteControlTargetServiceClass_UUID          = '{0000110C-0000-1000-8000-00805F9B34FB}';
AdvancedAudioDistributionServiceClass_UUID      = '{0000110D-0000-1000-8000-00805F9B34FB}';
AVRemoteControlServiceClass_UUID                = '{0000110E-0000-1000-8000-00805F9B34FB}';
VideoConferencingServiceClass_UUID              = '{0000110F-0000-1000-8000-00805F9B34FB}';
IntercomServiceClass_UUID                       = '{00001110-0000-1000-8000-00805F9B34FB}';
FaxServiceClass_UUID                            = '{00001111-0000-1000-8000-00805F9B34FB}';
HeadsetAudioGatewayServiceClass_UUID            = '{00001112-0000-1000-8000-00805F9B34FB}';
WAPServiceClass_UUID                            = '{00001113-0000-1000-8000-00805F9B34FB}';
WAPClientServiceClass_UUID                      = '{00001114-0000-1000-8000-00805F9B34FB}';
PANUServiceClass_UUID                           = '{00001115-0000-1000-8000-00805F9B34FB}';
NAPServiceClass_UUID                            = '{00001116-0000-1000-8000-00805F9B34FB}';
GNServiceClass_UUID                             = '{00001117-0000-1000-8000-00805F9B34FB}';
DirectPrintingServiceClass_UUID                 = '{00001118-0000-1000-8000-00805F9B34FB}';
ReferencePrintingServiceClass_UUID              = '{00001119-0000-1000-8000-00805F9B34FB}';
ImagingServiceClass_UUID                        = '{0000111A-0000-1000-8000-00805F9B34FB}';
ImagingResponderServiceClass_UUID               = '{0000111B-0000-1000-8000-00805F9B34FB}';
ImagingAutomaticArchiveServiceClass_UUID        = '{0000111C-0000-1000-8000-00805F9B34FB}';
ImagingReferenceObjectsServiceClass_UUID        = '{0000111D-0000-1000-8000-00805F9B34FB}';
HandsfreeServiceClass_UUID                      = '{0000111E-0000-1000-8000-00805F9B34FB}';
HandsfreeAudioGatewayServiceClass_UUID          = '{0000111F-0000-1000-8000-00805F9B34FB}';
DirectPrintingReferenceObjectsServiceClass_UUID = '{00001120-0000-1000-8000-00805F9B34FB}';
ReflectedUIServiceClass_UUID                    = '{00001121-0000-1000-8000-00805F9B34FB}';
BasicPringingServiceClass_UUID                  = '{00001122-0000-1000-8000-00805F9B34FB}';
PrintingStatusServiceClass_UUID                 = '{00001123-0000-1000-8000-00805F9B34FB}';
HumanInterfaceDeviceServiceClass_UUID           = '{00001124-0000-1000-8000-00805F9B34FB}';
HardcopyCableReplacementServiceClass_UUID       = '{00001125-0000-1000-8000-00805F9B34FB}';
HCRPrintServiceClass_UUID                       = '{00001126-0000-1000-8000-00805F9B34FB}';
HCRScanServiceClass_UUID                        = '{00001127-0000-1000-8000-00805F9B34FB}';
CommonISDNAccessServiceClass_UUID               = '{00001128-0000-1000-8000-00805F9B34FB}';
VideoConferencingGWServiceClass_UUID            = '{00001129-0000-1000-8000-00805F9B34FB}';
UDIMTServiceClass_UUID                          = '{0000112A-0000-1000-8000-00805F9B34FB}';
UDITAServiceClass_UUID                          = '{0000112B-0000-1000-8000-00805F9B34FB}';
AudioVideoServiceClass_UUID                     = '{0000112C-0000-1000-8000-00805F9B34FB}';
PnPInformationServiceClass_UUID                 = '{00001200-0000-1000-8000-00805F9B34FB}';
GenericNetworkingServiceClass_UUID              = '{00001201-0000-1000-8000-00805F9B34FB}';
GenericFileTransferServiceClass_UUID            = '{00001202-0000-1000-8000-00805F9B34FB}';
GenericAudioServiceClass_UUID                   = '{00001203-0000-1000-8000-00805F9B34FB}';
GenericAudioServiceClass_UUID                   = '{00001203-0000-1000-8000-00805F9B34FB}';
GenericTelephonyServiceClass_UUID               = '{00001204-0000-1000-8000-00805F9B34FB}';
UPnPServiceClass_UUID                           = '{00001205-0000-1000-8000-00805F9B34FB}';
UPnPIpServiceClass_UUID                         = '{00001206-0000-1000-8000-00805F9B34FB}';
ESdpUPnPIpPanServiceClass_UUID                  = '{00001300-0000-1000-8000-00805F9B34FB}';
ESdpUPnPIpLapServiceClass_UUID                  = '{00001301-0000-1000-8000-00805F9B34FB}';
EdpUPnpIpL2CAPServiceClass_UUID                 = '{00001302-0000-1000-8000-00805F9B34FB}';
Technorati tags: , , , , 

ref. An Introduction to Bluetooth programming in GNU/Linux – Chapter 4. Bluetooth programming in C with BlueZ
4.4. Service Discovery Protocol

CSR HCI Extension Packet

Posted in Bluetooth on 2006 年 11 月 28 日 by Kun-Yi
CSR使用一個 HCI Extension 包裹 其 BCCMD 命令
基本的結構就是 OGF: 0x03F, OCF:0x00 => OpCode:0xFC00
BYTE cmdArray[] = { 0x00, 0x0FC, parameters total length, payload description, payload };
其 HCI_EVENT 則為下列結構
BYTE eventArray[] = {0xFF, parameters total length, payload decription, payload }; 


Payload Description
MSB
  • bit 7, Last Fragment
  • bit 6, First Fragment
  • bit 5~0, Channel ID
LSB
refer CSR HCI Extensions, July 2004.
 


而BCCMD 使用 Channel 2,BCCMD 基本結構是 是被 CSR 稱為 Message,由 5 個 UINT 16bits 的Head 開始

  • Type
    • GETREQ, 0x0000
    • GETRESP, 0x0001
    • SETREQ, 0x0002
  • Length, 整個 Message 的長度
  • Seq. No
  • Varid, 用來識別 CSR 內部獨特的資料庫 像是 PS Key 等, 0x0000 代表沒有使用
  • Status, 在 GETREQ 與 SETREQ 永遠是 0x0000(0K)
    • OK, 0x0000
    • NO_SUCH_VARID, 0x0001
    • TO_BIG, 0x0002
    • NO_VALUE, 0x0003
    • BAD_REG, 0x0004
    • NO_ACCESS, 0x0005
    • READ_ONLY, 0x0006
    • WRITE_ONLY, 0x0007
    • ERROR, 0x0008
    • PERMISSION_DENIED, 0x0009

一個設定Radio TX testing 範例就是如下

Host –> BlueCore(SETREQ)

    1. BCCMD. TYPE:  SETREQ(0x0002)
    2. BCCMD. LENGTH:  0x0009
    3. BCCMD. SEQ_NO:  ANY from HOST
    4. BCCMD. VARID:  RADIO_TEST(0x5004 or 20484)
    5. BCCMD. STATUS: OK(0x0000)
    6. BCCMD. RADIO_TEST.TYPE: TX_START (0x0001)
    7. BCCMD. RADIO_TEST.TX_START.FREQUENCY(2402 ~ 2495) (Mhz)
    8. BCCMD. RADIO_TEST.TX AMP. default (0xff32)
    9. BCCMD. RADIO_TEST.MODULATION: default (0x0000)

BYTE bccmd[18] = { 0x02, 0x00, 0x09, 0x00, 0x01, 0x00, 0x04, 0x05, 0x00, 0x00, 0x01, 0x00, 0x62, 0x09, 0x32, 0xFF, 0x00, 0x00};

BYTE hci_cmd[] = { 0x00, 0xFC, 19, 0x02, include bccmd};

BlueCore –> Host (GETRESP)

    1. BCCMD. TYPE:  GETRESP(0x0001)
    2. BCCMD. LENGTH:  0x0009
    3. BCCMD. SEQ_NO:  same SETREQ
    4. BCCMD. VARID:  RADIO_TEST(0x5004 or 20484)
    5. BCCMD. STATUS: OK(0x0000)
    6. BCCMD. RADIO_TEST.TYPE: TX_START (0x0001)
    7. BCCMD. RADIO_TEST.TX_START.FREQUENCY(2402 ~ 2495) (Mhz)
    8. BCCMD. RADIO_TEST.TX AMP. default (0xff32)
    9. BCCMD. RADIO_TEST.MODULATION: default (0x0000)

BYTE hci_event[] = { 0xFF, 19, 0x02, 0x01, 0x00, 0x09, 0x01, 0x00, 0x04, 0x05, 0x00, 0x00, 0x01, 0x00, 0x62, 0x09, 0x32, 0xff, 0x00, 0x00 };



Click to Original Size

Bluetooth HCI Data format

Posted in Bluetooth on 2006 年 11 月 28 日 by Kun-Yi

HCI (Host Control Interface) 是 Bluetooth SIG 設計用來提供Host 與 Bluetooth Module 連接的軟體介面(Software Inferface),在實際連結的硬體上目前制定了Transport 可以使HOST 與BT Module 實際連結有所依據,目前已經制定的Transport 有

  • UART
  • USB
  • SD
  • 3-Wire UART
HCI 有四種基本型態的封包,在不同的傳輸層透過不同的方式區別,
  • Commands, 用於Host 對 BT Module的控制
    • 在UART  Transport 使用 0x01 放在packet的開頭作識別
    • USB Transport  是 control endpoint(endpoint 0)
  • ACL, 用於傳輸一般性資料具有基本的資料可靠性保證
    • UART transport 使用 0x02
    • USB transport用Bulk endpoint 傳輸
  • SCO, 用於語音資料的傳遞
    • UART transport 使用 0x03
    • USB transport用Isochronous endpoint 傳輸
  • Event, 用於BT Module 回應 Host 的控制
    • UART transport 使用 0x04
    • USB transport 則用 Interrupt endpoint
typedef  enum _HCI_PACKET_TYPE_ {
HCI_COMMAND = 0x01,
HCI_ACL = 0x02,
HCI_SCL = 0x03,
HCI_EVENT = 0x04
} HCI_PACKET_TYPE;
HCI 是採用 Little Endian, signal 採用2’s 補數表示(Refer Section 5.2, Part E, Volume 2, Core Spec.)
HCI 命令封包(Command Packet) 是由一個16bits 唯一操作碼(Opcode)開始, 操作碼由兩部份組成 分別是 OGF(OpCode Group Field, Lenght: 6bits) 與 OCF (OpCode Command Field, 10bits) OGF:0x3F (111111B)是保留給Vendor-Specific 測試使用, OGF:0x3E(111110B)則是保留給 Bluetooth Logo Test。
當OGF與OCF 都為0 時則是一個 NOP 命令,在流量控制中可能會需要使用到。
接在Opcode 後的就是命令參數總長度具有 8bits 長,每個參數有多長則依據不同的命令有所不同

HCI Command Packet Format
用C Strruce 可以這樣表示
_HCI_PACKET_ {
union
{
UINT16 code;
struct {
unsigned int ocf :10;
unsigned int ogf : 6;
} op;
}
unsigned char Size;     // parameter total length
unsgined char* body; // context of parameters
} HCI_PACKET;

OGF 目前定義了 6 個 Group

  1. 連結控制命令(Link Control Command), OGF: 0x01
  2. 連結方式命令(Link Policy Command), OGF: 0x02
  3. 控制器與基頻命令(Controller & Baseband Command), OGF: 0x03
  4. 資訊參數(Informational Parameters), OGF: 0x04
  5. 狀態參數(Status Parameters), OGF: 0x05
  6. 測試命令(Testing Command), OGF: 0x06
因此要對一個BT Module 下達進入測試模式(Enable Device Under Test Mode)的話透過 HCI 需要使用 OGF:0x06, 而OCF:0x03(Refer Section 7.6.3 Part E, Volume 2, Core Spec.)。而要離開的話則是使用 HCI_Reset (OGF:0x03, OCF:0x03, Refer Section 7.3.2 Part E, Volume 2, Core Spec. ) 。每當一個Command 下達給BT Module內的Control 後,會回應一個HCI Command Complete Event 給Host端表示完成命令,除了HCI_RESET 命令外。因為HCI_RESET是使得Controller進入重置狀態,因此當收到HCI_RESET 的 Command Complete Event 是表示Controller 正準備執行HCI_RESET 而已。
HCI Event 是BT Module 用來回應 HCI Command 的封包,基本結構如下

HCI Event Packet Format