diff options
| author | Electric-Blue <Electric-Blue@users.noreply.github.com> | 2016-01-26 02:03:48 +0300 |
|---|---|---|
| committer | Electric-Blue <Electric-Blue@users.noreply.github.com> | 2016-01-26 02:03:48 +0300 |
| commit | 0c4a1cc1c2083a871562364de5df4f9d88ec321e (patch) | |
| tree | ddb8428845b663c078359eda4ec81bdcc157414f /nimbluez | |
| parent | 27a7a2a18a6db8b67cbe0e86c37cb174de2a1295 (diff) | |
| download | NimBluez-0c4a1cc1c2083a871562364de5df4f9d88ec321e.tar.gz NimBluez-0c4a1cc1c2083a871562364de5df4f9d88ec321e.zip | |
First version.
Diffstat (limited to 'nimbluez')
| -rw-r--r-- | nimbluez/bluetooth.nim | 25 | ||||
| -rw-r--r-- | nimbluez/bluetoothbluez.nim | 160 | ||||
| -rw-r--r-- | nimbluez/bluetoothmsbt.nim | 222 | ||||
| -rw-r--r-- | nimbluez/bluetoothnativesockets.nim | 433 | ||||
| -rw-r--r-- | nimbluez/bluetoothnet.nim | 69 | ||||
| -rw-r--r-- | nimbluez/bluez/bz_bluetooth.nim | 296 | ||||
| -rw-r--r-- | nimbluez/bluez/bz_hci.nim | 2594 | ||||
| -rw-r--r-- | nimbluez/bluez/bz_hci_lib.nim | 298 | ||||
| -rw-r--r-- | nimbluez/bluez/bz_l2cap.nim | 344 | ||||
| -rw-r--r-- | nimbluez/bluez/bz_rfcomm.nim | 100 | ||||
| -rw-r--r-- | nimbluez/bluez/ioctl.nim | 110 | ||||
| -rw-r--r-- | nimbluez/msbt/ms_bluetoothapis.nim | 1653 | ||||
| -rw-r--r-- | nimbluez/msbt/ms_bthdef.nim | 1279 | ||||
| -rw-r--r-- | nimbluez/msbt/ms_bthsdpdef.nim | 98 | ||||
| -rw-r--r-- | nimbluez/msbt/ms_ws2bth.nim | 372 |
15 files changed, 8053 insertions, 0 deletions
diff --git a/nimbluez/bluetooth.nim b/nimbluez/bluetooth.nim new file mode 100644 index 0000000..9a04cae --- /dev/null +++ b/nimbluez/bluetooth.nim @@ -0,0 +1,25 @@ +# Copyright (c) 2016, Maxim V. Abramov +# All rights reserved. +# Look at license.txt for more info. + +## This cross-platform module is used for discovery and managing Bluetooth +## devices and services. + +const useWinVersion = defined(Windows) or defined(nimdoc) + +when useWinVersion: + import bluetoothmsbt + + export BLUETOOTH_ADDRESS, BLUETOOTH_RADIO_INFO, BLUETOOTH_DEVICE_INFO + export ERROR_NO_MORE_ITEMS + +else: + import bluetoothbluez + + export bdaddr_t, inquiry_info + +export BluetoothDeviceLocalImpl, BluetoothDeviceLocal +export BluetoothDeviceRemoteImpl, BluetoothDeviceRemote +export getLocalDevice, getLocalDevices +export getRemoteDevice, getRemoteDevices +export address, name diff --git a/nimbluez/bluetoothbluez.nim b/nimbluez/bluetoothbluez.nim new file mode 100644 index 0000000..59dbb08 --- /dev/null +++ b/nimbluez/bluetoothbluez.nim @@ -0,0 +1,160 @@ +# Copyright (c) 2016, Maxim V. Abramov +# All rights reserved. +# Look at license.txt for more info. + +## This module is used for discovery and managing Bluetooth devices and +## services. It is based on BlueZ Bluetooth protocol stack implementation for +## Linux. + +import os +import bluez/bz_bluetooth, bluez/bz_hci, bluez/bz_hci_lib + +export bdaddr_t, inquiry_info + + +type + BluetoothDeviceLocalImpl* = object of RootObj ## Local Bluetooth device - + ## radio adapter. + fDevId*: cint + + BluetoothDeviceLocal* = ref BluetoothDeviceLocalImpl ## Local Bluetooth + ## device - raadio + ## adapter reference. + + BluetoothDeviceRemoteImpl* = object of RootObj ## Remote Bluetooth device. + fInquiryInfo*: inquiry_info + + BluetoothDeviceRemote* = ref BluetoothDeviceRemoteImpl ## Remote Bluetooth + ## device reference. + + +proc `$`*(pBdaddr: bdaddr_t): string = + ## Returns Bluetooth device address as a string. + const addressLen = 17 + result = "" + result.setLen(addressLen) + var pBdaddr = pBdaddr + let resultLen = ba2str(addr(pBdaddr), result) + if resultLen < 0: + raiseOSError(osLastError()) + result.setLen(resultLen) + + +proc parseBluetoothAddress*(str: string): bdaddr_t = + ## Converts a string to a Bluetooth device address. + let resultLen = str2ba(str, addr(result)) + if resultLen < 0: + raiseOSError(osLastError()) + + +proc getLocalDevice*(address: string): BluetoothDeviceLocal = + ## Returns local Bluetooth radio device with a specified address. + let devId = hci_devid(address) + if devId < 0: + raiseOSError(osLastError()) + return BluetoothDeviceLocal(fDevId: devId) + + +proc getLocalDevice*(): BluetoothDeviceLocal = + ## Returns default local Bluetooth radio device. + let devId = hci_get_route(nil) + if devId < 0: + raiseOSError(osLastError()) + return BluetoothDeviceLocal(fDevId: devId) + + +proc getLocalDevices*(): seq[BluetoothDeviceLocal] = + ## Returns all local Blutooth radio devices. + result = @[] + + proc devInfo(dd: cint; dev_id: cint; arg: clong): cint {.cdecl.} = + let refdevs = cast[ptr seq[BluetoothDeviceLocal]](arg) + refdevs[].add(BluetoothDeviceLocal(fDevId: dev_id)) + + discard hci_for_each_dev(HCI_UP_FLAG, devInfo, cast[clong](addr(result))); + + +proc getRemoteDevice*(address: string): BluetoothDeviceRemote = + ## Returns remote Bluetooth device with a specified address. + new(result) + if str2ba(address, addr(result.fInquiryInfo.bdaddr)) < 0: + raiseOSError(osLastError()) + + +proc getRemoteDevices*(device: BluetoothDeviceLocal; duration = 8; + flushCache = true): seq[BluetoothDeviceRemote] = + ## Returns all remote Bluetooth devices visible for the specified local + ## Bluetooth radio device. + const maxInquiryInfos = 255 + var inquiryInfos: array[maxInquiryInfos, inquiry_info] + var pInquiryInfo = addr(inquiryInfos[0]) + + let flags = if flushCache: IREQ_CACHE_FLUSH else: 0 + + let numInquiryInfos = hci_inquiry(cint(device.fDevId), cint(duration), + cint(maxInquiryInfos), nil, + addr(pInquiryInfo), clong(flags)) + if numInquiryInfos < 0: + raiseOSError(osLastError()) + + result = @[] + + for i in 0..(numInquiryInfos - 1): + result.add(BluetoothDeviceRemote(fInquiryInfo: inquiryInfos[i])) + + +proc getRemoteDevices*(duration = 8; + flushCache = true): seq[BluetoothDeviceRemote] = + ## Returns all remote Bluetooth devices visible for the default local + ## Bluetooth radio device. + return getLocalDevice().getRemoteDevices(duration, flushCache) + + +proc address*(device: BluetoothDeviceLocal): string = + ## Returns local Bluetooth device address as a string. + var bdaddr = bdaddr_t() + if hci_devba(device.fDevId, addr(bdaddr)) < 0: + raiseOSError(osLastError()) + return $bdaddr + + +proc address*(device: BluetoothDeviceRemote): string = + ## Returns remote Bluetooth device address as a string. + return $device.fInquiryInfo.bdaddr + + +proc name*(device: BluetoothDeviceLocal): string = + ## Returns local Bluetooth device name. + var socket = hci_open_dev(cint(device.fDevId)) + if socket < 0: + raiseOSError(osLastError()) + try: + result = "" + result.setLen(BLUETOOTH_MAX_NAME_SIZE) + if hci_read_local_name(socket, cint(len(result)), result, 0) < 0: + raiseOSError(osLastError()) + finally: + if hci_close_dev(socket) < 0: + raiseOSError(osLastError()) + + +proc name*(device: BluetoothDeviceRemote, + localDevice: BluetoothDeviceLocal = nil): string = + ## Returns remote Bluetooth device name. + var localDevice = localDevice + if localDevice == nil: + localDevice = getLocalDevice() + + var socket = hci_open_dev(localDevice.fDevId) + if socket < 0: + raiseOSError(osLastError()) + + try: + result = "" + result.setLen(BLUETOOTH_MAX_NAME_SIZE) + if hci_read_remote_name(socket, addr(device.fInquiryInfo.bdaddr), + cint(len(result)), result, 0) < 0: + raiseOSError(osLastError()) + finally: + if hci_close_dev(socket) < 0: + raiseOSError(osLastError()) diff --git a/nimbluez/bluetoothmsbt.nim b/nimbluez/bluetoothmsbt.nim new file mode 100644 index 0000000..4d10392 --- /dev/null +++ b/nimbluez/bluetoothmsbt.nim @@ -0,0 +1,222 @@ +# Copyright (c) 2016, Maxim V. Abramov +# All rights reserved. +# Look at license.txt for more info. + +## This module is used for discovery and managing Bluetooth devices and +## services. It is based on Microsoft Bluetooth protocol stack implementation +## for Windows. + +import os, strutils, algorithm, sequtils, winlean +import msbt/ms_bluetoothapis, msbt/ms_bthsdpdef, msbt/ms_bthdef + +export BLUETOOTH_ADDRESS, BLUETOOTH_RADIO_INFO, BLUETOOTH_DEVICE_INFO + +const + ERROR_NO_MORE_ITEMS* = OSErrorCode(259) + +type + BluetoothDeviceLocalImpl* = object of RootObj ## Local Bluetooth device - + ## radio adapter. + fRadioInfo*: BLUETOOTH_RADIO_INFO + + BluetoothDeviceLocal* = ref BluetoothDeviceLocalImpl ## Local Bluetooth + ## device - radio + ## adapter reference. + + BluetoothDeviceRemoteImpl* = object of RootObj ## Remote Bluetooth device. + fDeviceInfo*: BLUETOOTH_DEVICE_INFO + + BluetoothDeviceRemote* = ref BluetoothDeviceRemoteImpl ## Remote Bluetooth + ## device reference. + + +proc CloseHandle(hObject: HANDLE): WINBOOL{.stdcall, dynlib: "kernel32", + importc: "CloseHandle".} + + +proc `$`*(ba: BLUETOOTH_ADDRESS): string = + ## Returns Bluetooth device address as a string. + let ab = map(ba.ano_116103095.rgBytes, + proc(b: byte): string = toHex(BiggestInt(b), 2)) + result = ab.reversed.join(":") + + +proc parseBluetoothAddress*(str: string): BLUETOOTH_ADDRESS = + ## Converts a string to a Bluetooth device address. + var intVals = map(str.split(':'), + proc(s: string): int = parseHexInt(s)).reversed() + for i in 0..5: + result.ano_116103095.rgBytes[i] = byte(intVals[i]) + + +proc `==`*(x, y: BLUETOOTH_ADDRESS): bool = + ## Converts a string to a Bluetooth device address. + x.ano_116103095.ullLong == y.ano_116103095.ullLong + + +iterator localDeviceHandles*(): + tuple[handle: int , info: BLUETOOTH_RADIO_INFO] {.inline.} = + ## Iterates through the local Bluetooth devices. Closes current device + ## ''handle'' at the end of the each iteration. + var + findRadioParams: BLUETOOTH_FIND_RADIO_PARAMS + findRadioHandle: HBLUETOOTH_RADIO_FIND + radioHandle: int + errorCode: OSErrorCode + + findRadioParams.dwSize = DWORD(sizeof(findRadioParams)) + try: + findRadioHandle = BluetoothFindFirstRadio(addr(findRadioParams), + addr(radioHandle)) + if findRadioHandle == 0: + errorCode = osLastError() + if errorCode != ERROR_NO_MORE_ITEMS: + raiseOSError(errorCode) + else: + while true: + var radioInfo: BLUETOOTH_RADIO_INFO + radioInfo.dwSize = DWORD(sizeof(radioInfo)) + + errorCode = BluetoothGetRadioInfo(radioHandle, addr(radioInfo)) + .OSErrorCode + if errorCode != OSErrorCode(NO_ERROR): + raiseOSError(errorCode) + + yield (handle: radioHandle, info: radioInfo) + + if CloseHandle(radioHandle) == 0: + raiseOSError(osLastError()) + radioHandle = 0; + + if BluetoothFindNextRadio(findRadioHandle, addr(radioHandle)) == 0: + errorCode = osLastError() + if errorCode != ERROR_NO_MORE_ITEMS: + raiseOSError(errorCode) + break + finally: + if findRadioHandle != 0: + if radioHandle != 0: + if CloseHandle(radioHandle) == 0: + raiseOSError(osLastError()) + if BluetoothFindRadioClose(findRadioHandle) == 0: + raiseOSError(osLastError()) + + +iterator getLocalDevices*(): BluetoothDeviceLocal {.inline.} = + ## Returns all local Blutooth radio devices. + for item in localDeviceHandles(): + yield BluetoothDeviceLocal(fRadioInfo: item.info) + + +proc getLocalDevice*(): BluetoothDeviceLocal = + ## Returns default local Bluetooth radio device. + for item in getLocalDevices(): + return item + raiseOSError(ERROR_NO_MORE_ITEMS) + + +proc getLocalDevice*(address: string): BluetoothDeviceLocal = + ## Returns local Bluetooth radio device with a specified address. + let ba = parseBluetoothAddress(address) + for item in getLocalDevices(): + if item.fRadioInfo.address == ba: + return item + raiseOSError(ERROR_NO_MORE_ITEMS) + + +proc getRemoteDevice*(address: string): BluetoothDeviceRemote = + ## Returns remote Bluetooth device with a specified address. + new(result) + result.fDeviceInfo.Address = address.parseBluetoothAddress + + +iterator remoteDeviceInfos*(radioHandle: HANDLE; + timeoutMultiplier: UCHAR; + issueInquiry: BOOL): + BLUETOOTH_DEVICE_INFO {.inline.} = + ## Iterates through the all remote Bluetooth devices visible for the + ## specified local Bluetooth radio device. + var + deviceSearchParams: BLUETOOTH_DEVICE_SEARCH_PARAMS + deviceFindHandle: HBLUETOOTH_DEVICE_FIND + errorCode: OSErrorCode + deviceInfo: BLUETOOTH_DEVICE_INFO + + deviceSearchParams.dwSize = DWORD(sizeof(deviceSearchParams)) + deviceSearchParams.fReturnAuthenticated = BOOL(true) + deviceSearchParams.fReturnRemembered = BOOL(true) + deviceSearchParams.fReturnUnknown = BOOL(true) + deviceSearchParams.fReturnConnected = BOOL(true) + deviceSearchParams.fIssueInquiry = issueInquiry + deviceSearchParams.cTimeoutMultiplier = timeoutMultiplier + deviceSearchParams.hRadio = radioHandle + + deviceInfo.dwSize = DWORD(sizeof(deviceInfo)) + + try: + deviceFindHandle = BluetoothFindFirstDevice(addr(deviceSearchParams), + addr(deviceInfo)) + if deviceFindHandle == 0: + errorCode = osLastError() + if errorCode != ERROR_NO_MORE_ITEMS: + raiseOSError(errorCode) + else: + yield deviceInfo + + while true: + var deviceInfoLoop: BLUETOOTH_DEVICE_INFO + deviceInfoLoop.dwSize = DWORD(sizeof(deviceInfoLoop)) + + if BluetoothFindNextDevice(deviceFindHandle, addr(deviceInfoLoop)) == 0: + errorCode = osLastError() + if errorCode != ERROR_NO_MORE_ITEMS: + raiseOSError(errorCode) + break + + yield deviceInfoLoop + finally: + if deviceFindHandle != 0: + if BluetoothFindDeviceClose(deviceFindHandle) == 0: + raiseOSError(errorCode) + + +proc getRemoteDevices*(device: BluetoothDeviceLocal = nil; + duration: int = 8; + flushCache: bool = true): seq[BluetoothDeviceRemote] = + ## Returns all remote Bluetooth devices visible for the specified or default + ## local Bluetooth radio device. + result = @[] + + if device != nil: + for item in localDeviceHandles(): + if item.info.address == device.fRadioInfo.address: + for deviceInfo in remoteDeviceInfos(item.handle, UCHAR(duration), + BOOL(flushCache)): + result.add(BluetoothDeviceRemote(fDeviceInfo: deviceInfo)) + else: + for deviceInfo in remoteDeviceInfos(0, UCHAR(duration), BOOL(flushCache)): + result.add(BluetoothDeviceRemote(fDeviceInfo: deviceInfo)) + + +proc address*(device: BluetoothDeviceLocal): string = + ## Returns local Bluetooth device address as a string. + $device.fRadioInfo.address + + +proc address*(device: BluetoothDeviceRemote): string = + ## Returns remote Bluetooth device address as a string. + $device.fDeviceInfo.Address + + +proc name*(device: BluetoothDeviceLocal): string = + ## Returns local Bluetooth device name. + var buf: array[BLUETOOTH_MAX_NAME_SIZE + 1, WCHAR] + copyMem(addr(buf), addr(device.fRadioInfo.szName), BLUETOOTH_MAX_NAME_SIZE) + return cast[WideCString](addr(buf)) $ BLUETOOTH_MAX_NAME_SIZE + + +proc name*(device: BluetoothDeviceRemote): string = + ## Returns remote Bluetooth device name. + var buf: array[BLUETOOTH_MAX_NAME_SIZE + 1, WCHAR] + copyMem(addr(buf), addr(device.fDeviceInfo.szName), BLUETOOTH_MAX_NAME_SIZE) + return cast[WideCString](addr(buf)) $ BLUETOOTH_MAX_NAME_SIZE diff --git a/nimbluez/bluetoothnativesockets.nim b/nimbluez/bluetoothnativesockets.nim new file mode 100644 index 0000000..b079b42 --- /dev/null +++ b/nimbluez/bluetoothnativesockets.nim @@ -0,0 +1,433 @@ +# Copyright (c) 2016, Maxim V. Abramov +# All rights reserved. +# Look at license.txt for more info. + +## This module implements a low-level cross-platform sockets interface for +## Bluetooth. + +import os, nativesockets + +const useWinVersion = defined(Windows) or defined(nimdoc) + +when useWinVersion: + import winlean + import msbt/ms_bluetoothapis, msbt/ms_ws2bth + import bluetoothmsbt +else: + from posix import InvalidSocket, getsockname, getpeername + import bluez/bz_bluetooth, bluez/bz_rfcomm, bluez/bz_l2cap + import bluetoothbluez + +export SocketHandle, SockAddr, SockLen, SockType, Port +export + connect, close, listen, accept, send, recv, sendto, recvfrom, `==`, bindAddr, + getSockOptInt, setSockOptInt +export InvalidSocket +export + SOL_L2CAP, SOL_RFCOMM, + SO_ERROR, + SOMAXCONN, + SO_ACCEPTCONN, SO_BROADCAST, SO_DEBUG, SO_DONTROUTE, + SO_KEEPALIVE, SO_OOBINLINE, SO_REUSEADDR + #MSG_PEEK + + +type + ProtocolFamily* = enum ## Protocol family of the socket. + PF_BLUETOOTH = 31 ## for Bluetooth socket. + + BluetoothDomain* = enum ## Address family of the socket. This extends Domain + ## form the nativesockets. + AF_BLUETOOTH = 31 ## for Bluetooth socket. + + BluetoothProtocol* = enum ## third argument to `socket` proc + BTPROTO_L2CAP = 0, ## Logical link control and adaptation protocol. + ## Unsupported on Windows. + BTPROTO_RFCOMM = 3 ## Radio frequency communication. + + RfcommPort* = 0..30 ## RFCOMM channel. The valid range for requesting + ## a specific RFCOMM port is 1 through 30 or 0 for + ## automatic assign. + + L2capPort* = 0..32767 ## L2CAP port (Protocol Service Multiplexer) can take + ## on odd-numbered values between 1 and 32767. Reserved + ## (well known) port numbers are between 1 and 4095. + + +when useWinVersion: + type + RfcommAddr* = SOCKADDR_BTH + L2capAddr* = object +else: + type + RfcommAddr* = sockaddr_rc + L2capAddr* = sockaddr_l2 + + +type + RfcommAddrRef* = ref RfcommAddr + L2capAddrRef* = ref L2capAddr + + + +when useWinVersion: + const + nativePfBluetooth* = ms_ws2bth.PF_BTH + nativeAfBluetooth* = ms_ws2bth.AF_BTH + WSAEPROTONOSUPPORT = OSErrorCode(10043) +else: + const + nativePfBluetooth* = bz_bluetooth.PF_BLUETOOTH + nativeAfBluetooth* = bz_bluetooth.AF_BLUETOOTH + + +proc toInt*(family: ProtocolFamily): cint + ## Converts the ProtocolFamily enum to a platform-dependent ``cint``. + + +proc toInt*(domain: BluetoothDomain): cint + ## Converts the BluetoothDomain enum to a platform-dependent ``cint``. + + +proc toInt*(protocol: BluetoothProtocol): cint + ## Converts the BluetoothProtocol enum to a platform-dependent ``cint``. + + +when useWinVersion: + proc toInt*(family: ProtocolFamily): cint = + case family + of PF_BLUETOOTH: result = cint(ms_ws2bth.PF_BTH) + else: discard + + proc toInt*(domain: BluetoothDomain): cint = + case domain + of AF_BLUETOOTH: result = cint(ms_ws2bth.AF_BTH) + + + proc toInt*(protocol: BluetoothProtocol): cint = + case protocol + of BTPROTO_L2CAP: result = cint(ms_ws2bth.BTHPROTO_L2CAP) + of BTPROTO_RFCOMM: result = cint(ms_ws2bth.BTHPROTO_RFCOMM) + +else: + proc toInt*(family: ProtocolFamily): cint = + case family + of PF_BLUETOOTH: result = cint(bz_bluetooth.PF_BLUETOOTH) + + + proc toInt*(domain: BluetoothDomain): cint = + case domain + of AF_BLUETOOTH: result = cint(bz_bluetooth.AF_BLUETOOTH) + + + proc toInt*(protocol: BluetoothProtocol): cint = + case protocol + of BTPROTO_L2CAP: result = cint(bz_bluetooth.BTPROTO_L2CAP) + of BTPROTO_RFCOMM: result = cint(bz_bluetooth.BTPROTO_RFCOMM) + + +proc htobs*(d: int16): int16 = + ## Converts 16-bit integers from host to Bluetooth byte order. + ## On machines where the host byte order is the same as Bluetooth byte order, + ## this is a no-op; otherwise, it performs a 2-byte swap operation. + when cpuEndian == bigEndian: + swapEndian16(result, d) + else: + result = d + + +proc htobl*(d: int32): int32 = + ## Converts 32-bit integers from host to Bluetooth byte order. + ## On machines where the host byte order is the same as Bluetooth byte order, + ## this is a no-op; otherwise, it performs a 4-byte swap operation. + when cpuEndian == bigEndian: + swapEndian32(result, d) + else: + result = d + + +proc htobll*(d: int64): int64 = + ## Converts 64-bit integers from host to Bluetooth byte order. + ## On machines where the host byte order is the same as Bluetooth byte order, + ## this is a no-op; otherwise, it performs a 8-byte swap operation. + when cpuEndian == bigEndian: + swapEndian64(result, d) + else: + result = d + + +template btohs*(d: expr): expr = + ## Converts 16-bit integers from Bluetooth to host byte order. + ## On machines where the host byte order is the same as Bluetooth byte order, + ## this is a no-op; otherwise, it performs a 2-byte swap operation. + htobs(d) + + +template btohl*(d: expr): expr = + ## Converts 32-bit integers from Bluetooth to host byte order. + ## On machines where the host byte order is the same as Bluetooth byte order, + ## this is a no-op; otherwise, it performs a 4-byte swap operation. + htobl(d) + + +template btohll*(d: expr): expr = + ## Converts 64-bit integers from Bluetooth to host byte order. + ## On machines where the host byte order is the same as Bluetooth byte order, + ## this is a no-op; otherwise, it performs a 8-byte swap operation. + htobll(d) + + +when not useWinVersion: + proc htob_bdaddr*(d: bdaddr_t): bdaddr_t = + ## Converts bdaddr_t from host toBluetooth byte order. + ## On machines where the host byte order is the same as Bluetooth, + ## this is a no-op; otherwise, it performs a 6-byte swap operation. + when cpuEndian == bigEndian: + for i in countup(0, 5): + result[5 - i] = d[i] + else: + result = d + + template btoh_bdaddr*(d: expr): expr = + ## Converts bdaddr_t from Bluetooth to host byte order. + ## On machines where the host byte order is the same as Bluetooth, + ## this is a no-op; otherwise, it performs a 6-byte swap operation. + htob_bdaddr(d) + + +proc newBluetoothNativeSocket*(sockType: SockType = SOCK_STREAM, + protocol: BluetoothProtocol = BTPROTO_RFCOMM): + SocketHandle = + ## Creates a new Bluetooth socket; returns `InvalidSocket` if an error occurs. + result = + newNativeSocket(toInt(ProtocolFamily.PF_BLUETOOTH), + toInt(sockType), + toInt(protocol)) + + +proc getRfcommAddr*(port = RfcommPort(0), address = ""): RfcommAddr + ## Creates and fills Bluetooth address structure for RFCOMM protocol. + + +proc getL2capAddr*(port = L2capPort(0), address = ""): L2capAddr + ## Creates and fills Bluetooth address structure for L2CAP protocol. + + +proc getRfcommLocalName*(socket: SocketHandle): RfcommAddr + ## Returns the RFCOMM socket's associated port number. + + +proc getL2capLocalName*(socket: SocketHandle): L2capAddr + ## Returns the L2CAP socket's associated port number. + + +proc getRfcommPeerName*(socket: SocketHandle): RfcommAddr + ## Returns the RFCOMM socket's associated port number. + + +proc getL2capPeerName*(socket: SocketHandle): L2capAddr + ## Returns the L2CAP socket's associated port number. + + +proc getAddrString*(sockAddr: RfcommAddr): string + ## Returns the string representation of a Bluetooth address. + + +proc getAddrString*(sockAddr: L2capAddr): string + ## Returns the string representation of a Bluetooth address. + + +proc getAddrPort*(sockAddr: RfcommAddr): RfcommPort + ## Returns port of a Bluetooth address. + + +proc getAddrPort*(sockAddr: L2capAddr): L2capPort + ## Returns port of a Bluetooth address. + + +when useWinVersion: + proc getRfcommAddr*(port = RfcommPort(0), address = ""): RfcommAddr = + result.addressFamily = htobs( + toInt(BluetoothDomain.AF_BLUETOOTH).int16).uint16 + if address != nil and address != "": + result.btAddr = htobll( + parseBluetoothAddress(address).ano_116103095.ullLong.int32).uint32 + #result.serviceClassId = + #TODO: use htob... proc there. + result.port = htobl(if port == 0: -1'i32 else: int32(port)) + #result.port = htobl(ULONG(port)) + + + proc getL2capAddr*(port = L2capPort(0), address = ""): L2capAddr = + raiseOSError(WSAEPROTONOSUPPORT) + + + proc getRfcommLocalName*(socket: SocketHandle): RfcommAddr = + var name = getRfcommAddr() + var nameLen = sizeof(name).SockLen + if getsockname(socket, + cast[ptr SockAddr](addr(name)), + addr(nameLen)) == -1'i32: + raiseOSError(osLastError()) + result = name + + + proc getL2capLocalName*(socket: SocketHandle): L2capAddr = + raiseOSError(WSAEPROTONOSUPPORT) + + + proc getRfcommPeerName*(socket: SocketHandle): RfcommAddr = + var name = getRfcommAddr() + var nameLen = sizeof(name).SockLen + if getpeername(socket, + cast[ptr SockAddr](addr(name)), + addr(nameLen)) == -1'i32: + raiseOSError(osLastError()) + result = name + + + proc getL2capPeerName*(socket: SocketHandle): L2capAddr = + raiseOSError(WSAEPROTONOSUPPORT) + + + proc getAddrString*(sockAddr: RfcommAddr): string = + result = $cast[BLUETOOTH_ADDRESS](btohll(sockAddr.btAddr.int64)) + + + proc getAddrString*(sockAddr: L2capAddr): string = + raiseOSError(WSAEPROTONOSUPPORT) + + + proc getAddrPort*(sockAddr: RfcommAddr): RfcommPort = + result = btohl(sockAddr.port) + + + proc getAddrPort*(sockAddr: L2capAddr): L2capPort = + raiseOSError(WSAEPROTONOSUPPORT) + + +else: + proc getRfcommAddr*(port = RfcommPort(0), address = ""): RfcommAddr = + result.rc_family = htobs(toInt(BluetoothDomain.AF_BLUETOOTH).uint16) + if address != nil and address != "": + result.rc_bdaddr = htob_bdaddr(parseBluetoothAddress(address)) + if port != RfcommPort(0): + result.rc_channel = uint8(port) + + + proc getL2capAddr*(port = L2capPort(0), address = ""): L2capAddr = + result.l2_family = htobs(toInt(BluetoothDomain.AF_BLUETOOTH).uint16) + if address != nil and address != "": + result.l2_bdaddr = htob_bdaddr(parseBluetoothAddress(address)) + if port != L2capPort(0): + result.l2_psm = htobs(cushort(port)) + + + proc getRfcommLocalName*(socket: SocketHandle): RfcommAddr = + var name = getRfcommAddr() + var nameLen = sizeof(name).SockLen + if getsockname(socket, + cast[ptr SockAddr](addr(name)), + addr(namelen)) == -1'i32: + raiseOSError(osLastError()) + result = name + + + proc getL2capLocalName*(socket: SocketHandle): L2capAddr = + var name = getL2capAddr() + var nameLen = sizeof(name).SockLen + if getsockname(socket, + cast[ptr SockAddr](addr(name)), + addr(nameLen)) == -1'i32: + raiseOSError(osLastError()) + result = name + + + proc getRfcommPeerName*(socket: SocketHandle): RfcommAddr = + var name = getRfcommAddr() + var nameLen = sizeof(name).SockLen + if getpeername(socket, + cast[ptr SockAddr](addr(name)), + addr(nameLen)) == -1'i32: + raiseOSError(osLastError()) + result = name + + + proc getL2capPeerName*(socket: SocketHandle): L2capAddr = + var name = getL2capAddr() + var nameLen = sizeof(name).SockLen + if getpeername(socket, + cast[ptr SockAddr](addr(name)), + addr(nameLen)) == -1'i32: + raiseOSError(osLastError()) + result = name + + + proc getAddrString*(sockAddr: RfcommAddr): string = + result = $btoh_bdaddr(sockAddr.rc_bdaddr) + + + proc getAddrString*(sockAddr: L2capAddr): string = + result = $btoh_bdaddr(sockAddr.l2_bdaddr) + + + proc getAddrPort*(sockAddr: RfcommAddr): RfcommPort = + result = sockAddr.rc_channel + + + proc getAddrPort*(sockAddr: L2capAddr): L2capPort = + result = btohs(sockAddr.l2_psm) + + +proc getRfcommSockName*(socket: SocketHandle): RfcommPort = + ## Returns the RFCOMM socket's associated port number. + var name = getRfcommLocalName(socket) + result = getAddrPort(name) + + +proc getL2capSockName*(socket: SocketHandle): L2capPort = + ## Returns the L2CAP socket's associated port number. + var name = getL2capLocalName(socket) + result = getAddrPort(name) + + +proc getRfcommLocalAddr*(socket: SocketHandle): (string, RfcommPort) = + ## Returns the socket's local address and port number. + ## + ## Similar to POSIX's `getsockname`:idx:. + var name = getRfcommLocalName(socket) + result = (getAddrString(name), getAddrPort(name)) + + +proc getL2capLocalAddr*(socket: SocketHandle): (string, L2capPort) = + ## Returns the socket's local address and port number. + ## + ## Similar to POSIX's `getsockname`:idx:. + var name = getL2capLocalName(socket) + result = (getAddrString(name), getAddrPort(name)) + + +proc getRfcommPeerAddr*(socket: SocketHandle): (string, RfcommPort) = + ## Returns the socket's peer address and port number. + ## + ## Similar to POSIX's `getpeername`:idx: + var name = getRfcommAddr() + var nameLen = sizeof(name).SockLen + if getpeername(socket, + cast[ptr SockAddr](addr(name)), + addr(namelen)) == -1'i32: + raiseOSError(osLastError()) + result = (getAddrString(name), getAddrPort(name)) + + +proc getL2capPeerAddr*(socket: SocketHandle): (string, L2capPort) = + ## Returns the socket's peer address and port number. + ## + ## Similar to POSIX's `getpeername`:idx: + var name = getL2capAddr() + var nameLen = sizeof(name).SockLen + if getpeername(socket, + cast[ptr SockAddr](addr(name)), + addr(namelen)) == -1'i32: + raiseOSError(osLastError()) + result = (getAddrString(name), getAddrPort(name)) diff --git a/nimbluez/bluetoothnet.nim b/nimbluez/bluetoothnet.nim new file mode 100644 index 0000000..ac794fa --- /dev/null +++ b/nimbluez/bluetoothnet.nim @@ -0,0 +1,69 @@ +# Copyright (c) 2016, Maxim V. Abramov +# All rights reserved. +# Look at license.txt for more info. + +## This module implements a high-level cross-platform sockets interface for +## Bluetooth. +## This module is just a draft yet. + +import os +import bluetoothnativesockets + +proc bindAddr*(socket: SocketHandle, port = RfcommPort(0), address = ""): cint = + ## Binds a Bluetooth RFCOMM socket. + var name = getRfcommAddr(port, address) + result = bindAddr(socket, + cast[ptr SockAddr](addr(name)), + sizeof(name).SockLen) + + +proc bindAddr*(socket: SocketHandle, port: L2capPort, address = ""): cint = + ## Binds a Bluetooth L2CAP socket. + var name = getL2capAddr(port, address) + result = bindAddr(socket, + cast[ptr SockAddr](addr(name)), + sizeof(name).SockLen) + + +proc acceptRfcommAddr*(server: SocketHandle, + address: var string): SocketHandle = + ## Enables incoming connection attempts on a Bluetooth RFCOMM socket. + var sockAddr = getRfcommAddr() + var addrLen = sizeof(sockAddr).SockLen + result = accept(server, cast[ptr SockAddr](addr(sockAddr)), addr(addrLen)) + address = getAddrString(sockAddr) + + +proc acceptL2capAddr*(server: SocketHandle, address: var string): SocketHandle = + ## Enables incoming connection attempts on a Bluetooth L2CAP socket. + var sockAddr = getL2capAddr() + var addrLen = sizeof(sockAddr).SockLen + result = accept(server, cast[ptr SockAddr](addr(sockAddr)), addr(addrLen)) + address = getAddrString(sockAddr) + + +proc connect*(socket: SocketHandle, port: RfcommPort, address: string): cint = + ## Connects to a target Bluetooth device, using a previously created Bluetooth RFCOMM socket. + var name = getRfcommAddr(port, address) + result = connect(socket, cast[ptr SockAddr](addr(name)), sizeof(name).SockLen) + + +proc connect*(socket: SocketHandle, port: L2capPort, address: string): cint = + ## Connects to a target Bluetooth device, using a previously created Bluetooth L2CAP socket. + var name = getL2capAddr(port, address) + result = connect(socket, cast[ptr SockAddr](addr(name)), sizeof(name).SockLen) + + +proc send*(socket: SocketHandle, message: string): cint = + ## Sends data on a connected socket. + result = send(socket, cstring(message), cint(message.len), cint(0)).cint + + +proc recv*(socket: SocketHandle): string = + ## Receives data from a connected socket. + result = "" + result.setLen(1000) + let recvLen = recv(socket, cstring(result), cint(result.len), cint(0)) + if recvLen < 0'i32: + raiseOSError(osLastError()) + result.setLen(recvLen) diff --git a/nimbluez/bluez/bz_bluetooth.nim b/nimbluez/bluez/bz_bluetooth.nim new file mode 100644 index 0000000..8efe7d3 --- /dev/null +++ b/nimbluez/bluez/bz_bluetooth.nim @@ -0,0 +1,296 @@ +# +# +# BlueZ - Bluetooth protocol stack for Linux +# +# Copyright (C) 2000-2001 Qualcomm Incorporated +# Copyright (C) 2002-2003 Maxim Krasnyansky <maxk@qualcomm.com> +# Copyright (C) 2002-2010 Marcel Holtmann <marcel@holtmann.org> +# +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +# +# + +{.deadCodeElim: on.} + +import endians + +const + AF_BLUETOOTH* = 31 + PF_BLUETOOTH* = AF_BLUETOOTH + +const + BTPROTO_L2CAP* = 0 + BTPROTO_HCI* = 1 + BTPROTO_SCO* = 2 + BTPROTO_RFCOMM* = 3 + BTPROTO_BNEP* = 4 + BTPROTO_CMTP* = 5 + BTPROTO_HIDP* = 6 + BTPROTO_AVDTP* = 7 + SOL_HCI* = 0 + SOL_L2CAP* = 6 + SOL_SCO* = 17 + SOL_RFCOMM* = 18 + +const + BT_SECURITY* = 4 + +const + BLUETOOTH_MAX_NAME_SIZE* = (248) + +type + bt_security* = object + level*: uint8 + key_size*: uint8 + + +const + BT_SECURITY_SDP* = 0 + BT_SECURITY_LOW* = 1 + BT_SECURITY_MEDIUM* = 2 + BT_SECURITY_HIGH* = 3 + BT_DEFER_SETUP* = 7 + BT_FLUSHABLE* = 8 + BT_FLUSHABLE_OFF* = 0 + BT_FLUSHABLE_ON* = 1 + BT_CHANNEL_POLICY* = 10 + +# BR/EDR only (default policy) +# AMP controllers cannot be used. +# Channel move requests from the remote device are denied. +# If the L2CAP channel is currently using AMP, move the channel to BR/EDR. +# + +const + BT_CHANNEL_POLICY_BREDR_ONLY* = 0 + +# BR/EDR Preferred +# Allow use of AMP controllers. +# If the L2CAP channel is currently on AMP, move it to BR/EDR. +# Channel move requests from the remote device are allowed. +# + +const + BT_CHANNEL_POLICY_BREDR_PREFERRED* = 1 + +# AMP Preferred +# Allow use of AMP controllers +# If the L2CAP channel is currently on BR/EDR and AMP controller +# resources are available, initiate a channel move to AMP. +# Channel move requests from the remote device are allowed. +# If the L2CAP socket has not been connected yet, try to create +# and configure the channel directly on an AMP controller rather +# than BR/EDR. +# + +const + BT_CHANNEL_POLICY_AMP_PREFERRED* = 2 + +# Connection and socket states + +const + BT_CONNECTED* = 1 # Equal to TCP_ESTABLISHED to make net code happy + BT_OPEN* = 2 + BT_BOUND* = 3 + BT_LISTEN* = 4 + BT_CONNECT* = 5 + BT_CONNECT2* = 6 + BT_CONFIG* = 7 + BT_DISCONN* = 8 + BT_CLOSED* = 9 + +# Byte order conversions + +proc htobs*(d: uint16): uint16 = + when cpuEndian == bigEndian: + swapEndian16(result, d) + else: + result = d + +proc htobl*(d: uint32): uint32 = + when cpuEndian == bigEndian: + swapEndian32(result, d) + else: + result = d + +proc htobll*(d: uint64): uint64 = + when cpuEndian == bigEndian: + swapEndian64(result, d) + else: + result = d + +template btohs*(d: expr): expr = + htobs(d) + +template btohl*(d: expr): expr = + htobl(d) + +template btohll*(d: expr): expr = + htobll(d) + +type + uint128* = object + data*: array[16, uint8] + +proc btoh128*(src: ptr uint128; dst: ptr uint128) {.inline, cdecl.} = + when cpuEndian == bigEndian: + var i: cint + for i in countup(0, 15): + dst.data[15 - i] = src.data[i] + else: + copyMem(dst, src, sizeof((uint128))) + +template htob128*(x, y: expr): expr = + btoh128(x, y) + +# Bluetooth unaligned access +##def bt_get_unaligned(ptr) \ +#({ \ +# struct __attribute__((packed)) { \ +# __typeof__(*(ptr)) __v; \ +# } *__p = (__typeof__(__p)) (ptr); \ +# __p->__v; \ +#}) +# +##def bt_put_unaligned(val, ptr) \ +#do { \ +# struct __attribute__((packed)) { \ +# __typeof__(*(ptr)) __v; \ +# } *__p = (__typeof__(__p)) (ptr); \ +# __p->__v = (val); \ +#} while(0) +# +##if __BYTE_ORDER == __LITTLE_ENDIAN +#static inline uint64_t bt_get_le64(const void *ptr) +#{ +# return bt_get_unaligned((const uint64_t *) ptr); +#} +# +#static inline uint64_t bt_get_be64(const void *ptr) +#{ +# return bswap_64(bt_get_unaligned((const uint64_t *) ptr)); +#} +# +#static inline uint32_t bt_get_le32(const void *ptr) +#{ +# return bt_get_unaligned((const uint32_t *) ptr); +#} +# +#static inline uint32_t bt_get_be32(const void *ptr) +#{ +# return bswap_32(bt_get_unaligned((const uint32_t *) ptr)); +#} +# +#static inline uint16_t bt_get_le16(const void *ptr) +#{ +# return bt_get_unaligned((const uint16_t *) ptr); +#} +# +#static inline uint16_t bt_get_be16(const void *ptr) +#{ +# return bswap_16(bt_get_unaligned((const uint16_t *) ptr)); +#} +##elif __BYTE_ORDER == __BIG_ENDIAN +#static inline uint64_t bt_get_le64(const void *ptr) +#{ +# return bswap_64(bt_get_unaligned((const uint64_t *) ptr)); +#} +# +#static inline uint64_t bt_get_be64(const void *ptr) +#{ +# return bt_get_unaligned((const uint64_t *) ptr); +#} +# +#static inline uint32_t bt_get_le32(const void *ptr) +#{ +# return bswap_32(bt_get_unaligned((const uint32_t *) ptr)); +#} +# +#static inline uint32_t bt_get_be32(const void *ptr) +#{ +# return bt_get_unaligned((const uint32_t *) ptr); +#} +# +#static inline uint16_t bt_get_le16(const void *ptr) +#{ +# return bswap_16(bt_get_unaligned((const uint16_t *) ptr)); +#} +# +#static inline uint16_t bt_get_be16(const void *ptr) +#{ +# return bt_get_unaligned((const uint16_t *) ptr); +#} +##else +##error "Unknown byte order" +##endif + +# BD Address + +type + bdaddr_t* = object {.packed.} + b*: array[6, uint8] + + +# BD Address type + +const + BDADDR_BREDR* = 0x00000000 + BDADDR_LE_PUBLIC* = 0x00000001 + BDADDR_LE_RANDOM* = 0x00000002 + +let + BDADDR_ANY* = bdaddr_t(b: [0'u8, 0'u8, 0'u8, 0'u8, 0'u8, 0'u8]) + BDADDR_ALL* = bdaddr_t(b: [0xff'u8, 0xff'u8, 0xff'u8, 0xff'u8, 0xff'u8, 0xff'u8]) + BDADDR_LOCAL* = bdaddr_t(b: [0'u8, 0'u8, 0'u8, 0xff'u8, 0xff'u8, 0xff'u8]) + +# Copy, swap, convert BD Address + +proc bacmp*(ba1: ptr bdaddr_t; ba2: ptr bdaddr_t): cint {.inline, cdecl.} = + return cint(equalMem(ba1, ba2, sizeof(bdaddr_t))) + +proc bacpy*(dst: ptr bdaddr_t; src: ptr bdaddr_t) {.inline, cdecl.} = + copyMem(dst, src, sizeof(bdaddr_t)) + +proc baswap*(dst: ptr bdaddr_t; src: ptr bdaddr_t) {.cdecl, importc: "baswap", + dynlib: "libbluetooth.so".} +proc strtoba*(str: cstring): ptr bdaddr_t {.cdecl, importc: "strtoba", + dynlib: "libbluetooth.so".} +proc batostr*(ba: ptr bdaddr_t): cstring {.cdecl, importc: "batostr", + dynlib: "libbluetooth.so".} +proc ba2str*(ba: ptr bdaddr_t; str: cstring): cint {.cdecl, importc: "ba2str", + dynlib: "libbluetooth.so".} +proc str2ba*(str: cstring; ba: ptr bdaddr_t): cint {.cdecl, importc: "str2ba", + dynlib: "libbluetooth.so".} +proc ba2oui*(ba: ptr bdaddr_t; oui: cstring): cint {.cdecl, importc: "ba2oui", + dynlib: "libbluetooth.so".} +proc bachk*(str: cstring): cint {.cdecl, importc: "bachk", + dynlib: "libbluetooth.so".} +proc baprintf*(format: cstring): cint {.varargs, cdecl, importc: "baprintf", + dynlib: "libbluetooth.so".} +proc bafprintf*(stream: ptr FILE; format: cstring): cint {.varargs, cdecl, + importc: "bafprintf", dynlib: "libbluetooth.so".} +proc basprintf*(str: cstring; format: cstring): cint {.varargs, cdecl, + importc: "basprintf", dynlib: "libbluetooth.so".} +proc basnprintf*(str: cstring; size: csize; format: cstring): cint {.varargs, + cdecl, importc: "basnprintf", dynlib: "libbluetooth.so".} +proc bt_malloc*(size: csize): pointer {.cdecl, importc: "bt_malloc", + dynlib: "libbluetooth.so".} +proc bt_free*(`ptr`: pointer) {.cdecl, importc: "bt_free", + dynlib: "libbluetooth.so".} +proc bt_error*(code: uint16): cint {.cdecl, importc: "bt_error", + dynlib: "libbluetooth.so".} +proc bt_compidtostr*(id: cint): cstring {.cdecl, importc: "bt_compidtostr", + dynlib: "libbluetooth.so".} diff --git a/nimbluez/bluez/bz_hci.nim b/nimbluez/bluez/bz_hci.nim new file mode 100644 index 0000000..3b2d925 --- /dev/null +++ b/nimbluez/bluez/bz_hci.nim @@ -0,0 +1,2594 @@ +# +# +# BlueZ - Bluetooth protocol stack for Linux +# +# Copyright (C) 2000-2001 Qualcomm Incorporated +# Copyright (C) 2002-2003 Maxim Krasnyansky <maxk@qualcomm.com> +# Copyright (C) 2002-2010 Marcel Holtmann <marcel@holtmann.org> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +# +# + +{.deadCodeElim: on.} + +import ioctl +import bz_bluetooth + +const + HCI_MAX_DEV* = 16 + HCI_MAX_ACL_SIZE* = 1024 + HCI_MAX_SCO_SIZE* = 255 + HCI_MAX_EVENT_SIZE* = 260 + HCI_MAX_FRAME_SIZE* = (HCI_MAX_ACL_SIZE + 4) + +# HCI dev events + +const + HCI_DEV_REG_EV* = 1 + HCI_DEV_UNREG_EV* = 2 + HCI_DEV_UP_EV* = 3 + HCI_DEV_DOWN_EV* = 4 + HCI_DEV_SUSPEND_EV* = 5 + HCI_DEV_RESUME_EV* = 6 + +# HCI bus types + +const + HCI_VIRTUAL* = 0 + HCI_USB* = 1 + HCI_PCCARD* = 2 + HCI_UART* = 3 + HCI_RS232* = 4 + HCI_PCI* = 5 + HCI_SDIO* = 6 + +# HCI controller types + +const + HCI_BREDR* = 0x00000000 + HCI_AMP* = 0x00000001 + +# HCI device flags + +const + HCI_UP_FLAG* = 0 + HCI_INIT_FLAG* = 1 + HCI_RUNNING_FLAG* = 2 + HCI_PSCAN_FLAG* = 3 + HCI_ISCAN_FLAG* = 4 + HCI_AUTH_FLAG* = 5 + HCI_ENCRYPT_FLAG* = 6 + HCI_INQUIRY_FLAG* = 7 + HCI_RAW_FLAG* = 8 + +# LE address type + +const + LE_PUBLIC_ADDRESS* = 0x00000000 + LE_RANDOM_ADDRESS* = 0x00000001 + +# HCI ioctl defines + +const + HCIDEVUP* = IOW(ord('H'), 201, int) + HCIDEVDOWN* = IOW(ord('H'), 202, int) + HCIDEVRESET* = IOW(ord('H'), 203, int) + HCIDEVRESTAT* = IOW(ord('H'), 204, int) + HCIGETDEVLIST* = IOR(ord('H'), 210, int) + HCIGETDEVINFO* = IOR(ord('H'), 211, int) + HCIGETCONNLIST* = IOR(ord('H'), 212, int) + HCIGETCONNINFO* = IOR(ord('H'), 213, int) + HCIGETAUTHINFO* = IOR(ord('H'), 215, int) + HCISETRAW* = IOW(ord('H'), 220, int) + HCISETSCAN* = IOW(ord('H'), 221, int) + HCISETAUTH* = IOW(ord('H'), 222, int) + HCISETENCRYPT* = IOW(ord('H'), 223, int) + HCISETPTYPE* = IOW(ord('H'), 224, int) + HCISETLINKPOL* = IOW(ord('H'), 225, int) + HCISETLINKMODE* = IOW(ord('H'), 226, int) + HCISETACLMTU* = IOW(ord('H'), 227, int) + HCISETSCOMTU* = IOW(ord('H'), 228, int) + HCIBLOCKADDR* = IOW(ord('H'), 230, int) + HCIUNBLOCKADDR* = IOW(ord('H'), 231, int) + HCIINQUIRY* = IOR(ord('H'), 240, int) + +when not defined(NO_HCI_DEFS): + # HCI Packet types + const + HCI_COMMAND_PKT* = 0x00000001 + HCI_ACLDATA_PKT* = 0x00000002 + HCI_SCODATA_PKT* = 0x00000003 + HCI_EVENT_PKT* = 0x00000004 + HCI_VENDOR_PKT* = 0x000000FF + # HCI Packet types + const + HCI_2DH1* = 0x00000002 + HCI_3DH1* = 0x00000004 + HCI_DM1* = 0x00000008 + HCI_DH1* = 0x00000010 + HCI_2DH3* = 0x00000100 + HCI_3DH3* = 0x00000200 + HCI_DM3* = 0x00000400 + HCI_DH3* = 0x00000800 + HCI_2DH5* = 0x00001000 + HCI_3DH5* = 0x00002000 + HCI_DM5* = 0x00004000 + HCI_DH5* = 0x00008000 + HCI_HV1* = 0x00000020 + HCI_HV2* = 0x00000040 + HCI_HV3* = 0x00000080 + HCI_EV3* = 0x00000008 + HCI_EV4* = 0x00000010 + HCI_EV5* = 0x00000020 + HCI_2EV3* = 0x00000040 + HCI_3EV3* = 0x00000080 + HCI_2EV5* = 0x00000100 + HCI_3EV5* = 0x00000200 + SCO_PTYPE_MASK* = (HCI_HV1 or HCI_HV2 or HCI_HV3) + ACL_PTYPE_MASK* = ( + HCI_DM1 or HCI_DH1 or HCI_DM3 or HCI_DH3 or HCI_DM5 or HCI_DH5) + # HCI Error codes + const + HCI_UNKNOWN_COMMAND* = 0x00000001 + HCI_NO_CONNECTION* = 0x00000002 + HCI_HARDWARE_FAILURE* = 0x00000003 + HCI_PAGE_TIMEOUT* = 0x00000004 + HCI_AUTHENTICATION_FAILURE* = 0x00000005 + HCI_PIN_OR_KEY_MISSING* = 0x00000006 + HCI_MEMORY_FULL* = 0x00000007 + HCI_CONNECTION_TIMEOUT* = 0x00000008 + HCI_MAX_NUMBER_OF_CONNECTIONS* = 0x00000009 + HCI_MAX_NUMBER_OF_SCO_CONNECTIONS* = 0x0000000A + HCI_ACL_CONNECTION_EXISTS* = 0x0000000B + HCI_COMMAND_DISALLOWED* = 0x0000000C + HCI_REJECTED_LIMITED_RESOURCES* = 0x0000000D + HCI_REJECTED_SECURITY* = 0x0000000E + HCI_REJECTED_PERSONAL* = 0x0000000F + HCI_HOST_TIMEOUT* = 0x00000010 + HCI_UNSUPPORTED_FEATURE* = 0x00000011 + HCI_INVALID_PARAMETERS* = 0x00000012 + HCI_OE_USER_ENDED_CONNECTION* = 0x00000013 + HCI_OE_LOW_RESOURCES* = 0x00000014 + HCI_OE_POWER_OFF* = 0x00000015 + HCI_CONNECTION_TERMINATED* = 0x00000016 + HCI_REPEATED_ATTEMPTS* = 0x00000017 + HCI_PAIRING_NOT_ALLOWED* = 0x00000018 + HCI_UNKNOWN_LMP_PDU* = 0x00000019 + HCI_UNSUPPORTED_REMOTE_FEATURE* = 0x0000001A + HCI_SCO_OFFSET_REJECTED* = 0x0000001B + HCI_SCO_INTERVAL_REJECTED* = 0x0000001C + HCI_AIR_MODE_REJECTED* = 0x0000001D + HCI_INVALID_LMP_PARAMETERS* = 0x0000001E + HCI_UNSPECIFIED_ERROR* = 0x0000001F + HCI_UNSUPPORTED_LMP_PARAMETER_VALUE* = 0x00000020 + HCI_ROLE_CHANGE_NOT_ALLOWED* = 0x00000021 + HCI_LMP_RESPONSE_TIMEOUT* = 0x00000022 + HCI_LMP_ERROR_TRANSACTION_COLLISION* = 0x00000023 + HCI_LMP_PDU_NOT_ALLOWED* = 0x00000024 + HCI_ENCRYPTION_MODE_NOT_ACCEPTED* = 0x00000025 + HCI_UNIT_LINK_KEY_USED* = 0x00000026 + HCI_QOS_NOT_SUPPORTED* = 0x00000027 + HCI_INSTANT_PASSED* = 0x00000028 + HCI_PAIRING_NOT_SUPPORTED* = 0x00000029 + HCI_TRANSACTION_COLLISION* = 0x0000002A + HCI_QOS_UNACCEPTABLE_PARAMETER* = 0x0000002C + HCI_QOS_REJECTED* = 0x0000002D + HCI_CLASSIFICATION_NOT_SUPPORTED* = 0x0000002E + HCI_INSUFFICIENT_SECURITY* = 0x0000002F + HCI_PARAMETER_OUT_OF_RANGE* = 0x00000030 + HCI_ROLE_SWITCH_PENDING* = 0x00000032 + HCI_SLOT_VIOLATION* = 0x00000034 + HCI_ROLE_SWITCH_FAILED* = 0x00000035 + HCI_EIR_TOO_LARGE* = 0x00000036 + HCI_SIMPLE_PAIRING_NOT_SUPPORTED* = 0x00000037 + HCI_HOST_BUSY_PAIRING* = 0x00000038 + # ACL flags + const + ACL_START_NO_FLUSH* = 0x00000000 + ACL_CONT* = 0x00000001 + ACL_START* = 0x00000002 + ACL_ACTIVE_BCAST* = 0x00000004 + ACL_PICO_BCAST* = 0x00000008 + # Baseband links + const + SCO_LINK* = 0x00000000 + ACL_LINK* = 0x00000001 + ESCO_LINK* = 0x00000002 + # LMP features + const + LMP_3SLOT* = 0x00000001 + LMP_5SLOT* = 0x00000002 + LMP_ENCRYPT* = 0x00000004 + LMP_SOFFSET* = 0x00000008 + LMP_TACCURACY* = 0x00000010 + LMP_RSWITCH* = 0x00000020 + LMP_HOLD* = 0x00000040 + LMP_SNIFF* = 0x00000080 + LMP_PARK* = 0x00000001 + LMP_RSSI* = 0x00000002 + LMP_QUALITY* = 0x00000004 + LMP_SCO* = 0x00000008 + LMP_HV2* = 0x00000010 + LMP_HV3* = 0x00000020 + LMP_ULAW* = 0x00000040 + LMP_ALAW* = 0x00000080 + LMP_CVSD* = 0x00000001 + LMP_PSCHEME* = 0x00000002 + LMP_PCONTROL* = 0x00000004 + LMP_TRSP_SCO* = 0x00000008 + LMP_BCAST_ENC* = 0x00000080 + LMP_EDR_ACL_2M* = 0x00000002 + LMP_EDR_ACL_3M* = 0x00000004 + LMP_ENH_ISCAN* = 0x00000008 + LMP_ILACE_ISCAN* = 0x00000010 + LMP_ILACE_PSCAN* = 0x00000020 + LMP_RSSI_INQ* = 0x00000040 + LMP_ESCO* = 0x00000080 + LMP_EV4* = 0x00000001 + LMP_EV5* = 0x00000002 + LMP_AFH_CAP_SLV* = 0x00000008 + LMP_AFH_CLS_SLV* = 0x00000010 + LMP_NO_BREDR* = 0x00000020 + LMP_LE* = 0x00000040 + LMP_EDR_3SLOT* = 0x00000080 + LMP_EDR_5SLOT* = 0x00000001 + LMP_SNIFF_SUBR* = 0x00000002 + LMP_PAUSE_ENC* = 0x00000004 + LMP_AFH_CAP_MST* = 0x00000008 + LMP_AFH_CLS_MST* = 0x00000010 + LMP_EDR_ESCO_2M* = 0x00000020 + LMP_EDR_ESCO_3M* = 0x00000040 + LMP_EDR_3S_ESCO* = 0x00000080 + LMP_EXT_INQ* = 0x00000001 + LMP_LE_BREDR* = 0x00000002 + LMP_SIMPLE_PAIR* = 0x00000008 + LMP_ENCAPS_PDU* = 0x00000010 + LMP_ERR_DAT_REP* = 0x00000020 + LMP_NFLUSH_PKTS* = 0x00000040 + LMP_LSTO* = 0x00000001 + LMP_INQ_TX_PWR* = 0x00000002 + LMP_EPC* = 0x00000004 + LMP_EXT_FEAT* = 0x00000080 + # Extended LMP features + const + LMP_HOST_SSP* = 0x00000001 + LMP_HOST_LE* = 0x00000002 + LMP_HOST_LE_BREDR* = 0x00000004 + # Link policies + const + HCI_LP_RSWITCH* = 0x00000001 + HCI_LP_HOLD* = 0x00000002 + HCI_LP_SNIFF* = 0x00000004 + HCI_LP_PARK* = 0x00000008 + # Link mode + const + HCI_LM_ACCEPT* = 0x00008000 + HCI_LM_MASTER* = 0x00000001 + HCI_LM_AUTH* = 0x00000002 + HCI_LM_ENCRYPT* = 0x00000004 + HCI_LM_TRUSTED* = 0x00000008 + HCI_LM_RELIABLE* = 0x00000010 + HCI_LM_SECURE* = 0x00000020 + # Link Key types + const + HCI_LK_COMBINATION* = 0x00000000 + HCI_LK_LOCAL_UNIT* = 0x00000001 + HCI_LK_REMOTE_UNIT* = 0x00000002 + HCI_LK_DEBUG_COMBINATION* = 0x00000003 + HCI_LK_UNAUTH_COMBINATION* = 0x00000004 + HCI_LK_AUTH_COMBINATION* = 0x00000005 + HCI_LK_CHANGED_COMBINATION* = 0x00000006 + HCI_LK_INVALID* = 0x000000FF + # ----- HCI Commands ----- + # Link Control + const + OGF_LINK_CTL* = 0x00000001 + OCF_INQUIRY* = 0x00000001 + type + inquiry_cp* = object {.packed.} + lap*: array[3, uint8] + length*: uint8 # 1.28s units + num_rsp*: uint8 + + const + INQUIRY_CP_SIZE* = 5 + type + status_bdaddr_rp* = object {.packed.} + status*: uint8 + bdaddr*: bdaddr_t + + const + STATUS_BDADDR_RP_SIZE* = 7 + OCF_INQUIRY_CANCEL* = 0x00000002 + OCF_PERIODIC_INQUIRY* = 0x00000003 + type + periodic_inquiry_cp* = object {.packed.} + max_period*: uint16 # 1.28s units + min_period*: uint16 # 1.28s units + lap*: array[3, uint8] + length*: uint8 # 1.28s units + num_rsp*: uint8 + + const + PERIODIC_INQUIRY_CP_SIZE* = 9 + OCF_EXIT_PERIODIC_INQUIRY* = 0x00000004 + OCF_CREATE_CONN* = 0x00000005 + type + create_conn_cp* = object {.packed.} + bdaddr*: bdaddr_t + pkt_type*: uint16 + pscan_rep_mode*: uint8 + pscan_mode*: uint8 + clock_offset*: uint16 + role_switch*: uint8 + + const + CREATE_CONN_CP_SIZE* = 13 + OCF_DISCONNECT* = 0x00000006 + type + disconnect_cp* = object {.packed.} + handle*: uint16 + reason*: uint8 + + const + DISCONNECT_CP_SIZE* = 3 + OCF_ADD_SCO* = 0x00000007 + type + add_sco_cp* = object {.packed.} + handle*: uint16 + pkt_type*: uint16 + + const + ADD_SCO_CP_SIZE* = 4 + OCF_CREATE_CONN_CANCEL* = 0x00000008 + type + create_conn_cancel_cp* = object {.packed.} + bdaddr*: bdaddr_t + + const + CREATE_CONN_CANCEL_CP_SIZE* = 6 + OCF_ACCEPT_CONN_REQ* = 0x00000009 + type + accept_conn_req_cp* = object {.packed.} + bdaddr*: bdaddr_t + role*: uint8 + + const + ACCEPT_CONN_REQ_CP_SIZE* = 7 + OCF_REJECT_CONN_REQ* = 0x0000000A + type + reject_conn_req_cp* = object {.packed.} + bdaddr*: bdaddr_t + reason*: uint8 + + const + REJECT_CONN_REQ_CP_SIZE* = 7 + OCF_LINK_KEY_REPLY* = 0x0000000B + type + link_key_reply_cp* = object {.packed.} + bdaddr*: bdaddr_t + link_key*: array[16, uint8] + + const + LINK_KEY_REPLY_CP_SIZE* = 22 + OCF_LINK_KEY_NEG_REPLY* = 0x0000000C + OCF_PIN_CODE_REPLY* = 0x0000000D + type + pin_code_reply_cp* = object {.packed.} + bdaddr*: bdaddr_t + pin_len*: uint8 + pin_code*: array[16, uint8] + + const + PIN_CODE_REPLY_CP_SIZE* = 23 + OCF_PIN_CODE_NEG_REPLY* = 0x0000000E + OCF_SET_CONN_PTYPE* = 0x0000000F + type + set_conn_ptype_cp* = object {.packed.} + handle*: uint16 + pkt_type*: uint16 + + const + SET_CONN_PTYPE_CP_SIZE* = 4 + OCF_AUTH_REQUESTED* = 0x00000011 + type + auth_requested_cp* = object {.packed.} + handle*: uint16 + + const + AUTH_REQUESTED_CP_SIZE* = 2 + OCF_SET_CONN_ENCRYPT* = 0x00000013 + type + set_conn_encrypt_cp* = object {.packed.} + handle*: uint16 + encrypt*: uint8 + + const + SET_CONN_ENCRYPT_CP_SIZE* = 3 + OCF_CHANGE_CONN_LINK_KEY* = 0x00000015 + type + change_conn_link_key_cp* = object {.packed.} + handle*: uint16 + + const + CHANGE_CONN_LINK_KEY_CP_SIZE* = 2 + OCF_MASTER_LINK_KEY* = 0x00000017 + type + master_link_key_cp* = object {.packed.} + key_flag*: uint8 + + const + MASTER_LINK_KEY_CP_SIZE* = 1 + OCF_REMOTE_NAME_REQ* = 0x00000019 + type + remote_name_req_cp* = object {.packed.} + bdaddr*: bdaddr_t + pscan_rep_mode*: uint8 + pscan_mode*: uint8 + clock_offset*: uint16 + + const + REMOTE_NAME_REQ_CP_SIZE* = 10 + OCF_REMOTE_NAME_REQ_CANCEL* = 0x0000001A + type + remote_name_req_cancel_cp* = object {.packed.} + bdaddr*: bdaddr_t + + const + REMOTE_NAME_REQ_CANCEL_CP_SIZE* = 6 + OCF_READ_REMOTE_FEATURES* = 0x0000001B + type + read_remote_features_cp* = object {.packed.} + handle*: uint16 + + const + READ_REMOTE_FEATURES_CP_SIZE* = 2 + OCF_READ_REMOTE_EXT_FEATURES* = 0x0000001C + type + read_remote_ext_features_cp* = object {.packed.} + handle*: uint16 + page_num*: uint8 + + const + READ_REMOTE_EXT_FEATURES_CP_SIZE* = 3 + OCF_READ_REMOTE_VERSION* = 0x0000001D + type + read_remote_version_cp* = object {.packed.} + handle*: uint16 + + const + READ_REMOTE_VERSION_CP_SIZE* = 2 + OCF_READ_CLOCK_OFFSET* = 0x0000001F + type + read_clock_offset_cp* = object {.packed.} + handle*: uint16 + + const + READ_CLOCK_OFFSET_CP_SIZE* = 2 + OCF_READ_LMP_HANDLE* = 0x00000020 + OCF_SETUP_SYNC_CONN* = 0x00000028 + type + setup_sync_conn_cp* = object {.packed.} + handle*: uint16 + tx_bandwith*: uint32 + rx_bandwith*: uint32 + max_latency*: uint16 + voice_setting*: uint16 + retrans_effort*: uint8 + pkt_type*: uint16 + + const + SETUP_SYNC_CONN_CP_SIZE* = 17 + OCF_ACCEPT_SYNC_CONN_REQ* = 0x00000029 + type + accept_sync_conn_req_cp* = object {.packed.} + bdaddr*: bdaddr_t + tx_bandwith*: uint32 + rx_bandwith*: uint32 + max_latency*: uint16 + voice_setting*: uint16 + retrans_effort*: uint8 + pkt_type*: uint16 + + const + ACCEPT_SYNC_CONN_REQ_CP_SIZE* = 21 + OCF_REJECT_SYNC_CONN_REQ* = 0x0000002A + type + reject_sync_conn_req_cp* = object {.packed.} + bdaddr*: bdaddr_t + reason*: uint8 + + const + REJECT_SYNC_CONN_REQ_CP_SIZE* = 7 + OCF_IO_CAPABILITY_REPLY* = 0x0000002B + type + io_capability_reply_cp* = object {.packed.} + bdaddr*: bdaddr_t + capability*: uint8 + oob_data*: uint8 + authentication*: uint8 + + const + IO_CAPABILITY_REPLY_CP_SIZE* = 9 + OCF_USER_CONFIRM_REPLY* = 0x0000002C + type + user_confirm_reply_cp* = object {.packed.} + bdaddr*: bdaddr_t + + const + USER_CONFIRM_REPLY_CP_SIZE* = 6 + OCF_USER_CONFIRM_NEG_REPLY* = 0x0000002D + OCF_USER_PASSKEY_REPLY* = 0x0000002E + type + user_passkey_reply_cp* = object {.packed.} + bdaddr*: bdaddr_t + passkey*: uint32 + + const + USER_PASSKEY_REPLY_CP_SIZE* = 10 + OCF_USER_PASSKEY_NEG_REPLY* = 0x0000002F + OCF_REMOTE_OOB_DATA_REPLY* = 0x00000030 + type + remote_oob_data_reply_cp* = object {.packed.} + bdaddr*: bdaddr_t + hash*: array[16, uint8] + randomizer*: array[16, uint8] + + const + REMOTE_OOB_DATA_REPLY_CP_SIZE* = 38 + OCF_REMOTE_OOB_DATA_NEG_REPLY* = 0x00000033 + OCF_IO_CAPABILITY_NEG_REPLY* = 0x00000034 + type + io_capability_neg_reply_cp* = object {.packed.} + bdaddr*: bdaddr_t + reason*: uint8 + + const + IO_CAPABILITY_NEG_REPLY_CP_SIZE* = 7 + OCF_CREATE_PHYSICAL_LINK* = 0x00000035 + type + create_physical_link_cp* = object {.packed.} + handle*: uint8 + key_length*: uint8 + key_type*: uint8 + key*: array[32, uint8] + + const + CREATE_PHYSICAL_LINK_CP_SIZE* = 35 + OCF_ACCEPT_PHYSICAL_LINK* = 0x00000036 + OCF_DISCONNECT_PHYSICAL_LINK* = 0x00000037 + type + disconnect_physical_link_cp* = object {.packed.} + handle*: uint8 + reason*: uint8 + + const + DISCONNECT_PHYSICAL_LINK_CP_SIZE* = 2 + OCF_CREATE_LOGICAL_LINK* = 0x00000038 + type + create_logical_link_cp* = object {.packed.} + handle*: uint8 + tx_flow*: array[16, uint8] + rx_flow*: array[16, uint8] + + const + CREATE_LOGICAL_LINK_CP_SIZE* = 33 + OCF_ACCEPT_LOGICAL_LINK* = 0x00000039 + OCF_DISCONNECT_LOGICAL_LINK* = 0x0000003A + type + disconnect_logical_link_cp* = object {.packed.} + handle*: uint16 + + const + DISCONNECT_LOGICAL_LINK_CP_SIZE* = 2 + OCF_LOGICAL_LINK_CANCEL* = 0x0000003B + type + cancel_logical_link_cp* = object {.packed.} + handle*: uint8 + tx_flow_id*: uint8 + + const + LOGICAL_LINK_CANCEL_CP_SIZE* = 2 + type + cancel_logical_link_rp* = object {.packed.} + status*: uint8 + handle*: uint8 + tx_flow_id*: uint8 + + const + LOGICAL_LINK_CANCEL_RP_SIZE* = 3 + OCF_FLOW_SPEC_MODIFY* = 0x0000003C + # Link Policy + const + OGF_LINK_POLICY* = 0x00000002 + OCF_HOLD_MODE* = 0x00000001 + type + hold_mode_cp* = object {.packed.} + handle*: uint16 + max_interval*: uint16 + min_interval*: uint16 + + const + HOLD_MODE_CP_SIZE* = 6 + OCF_SNIFF_MODE* = 0x00000003 + type + sniff_mode_cp* = object {.packed.} + handle*: uint16 + max_interval*: uint16 + min_interval*: uint16 + attempt*: uint16 + timeout*: uint16 + + const + SNIFF_MODE_CP_SIZE* = 10 + OCF_EXIT_SNIFF_MODE* = 0x00000004 + type + exit_sniff_mode_cp* = object {.packed.} + handle*: uint16 + + const + EXIT_SNIFF_MODE_CP_SIZE* = 2 + OCF_PARK_MODE* = 0x00000005 + type + park_mode_cp* = object {.packed.} + handle*: uint16 + max_interval*: uint16 + min_interval*: uint16 + + const + PARK_MODE_CP_SIZE* = 6 + OCF_EXIT_PARK_MODE* = 0x00000006 + type + exit_park_mode_cp* = object {.packed.} + handle*: uint16 + + const + EXIT_PARK_MODE_CP_SIZE* = 2 + OCF_QOS_SETUP* = 0x00000007 + type + hci_qos* = object {.packed.} + service_type*: uint8 # 1 = best effort + token_rate*: uint32 # Byte per seconds + peak_bandwidth*: uint32 # Byte per seconds + latency*: uint32 # Microseconds + delay_variation*: uint32 # Microseconds + + const + HCI_QOS_CP_SIZE* = 17 + type + qos_setup_cp* = object {.packed.} + handle*: uint16 + flags*: uint8 # Reserved + qos*: hci_qos + + const + QOS_SETUP_CP_SIZE* = (3 + HCI_QOS_CP_SIZE) + OCF_ROLE_DISCOVERY* = 0x00000009 + type + role_discovery_cp* = object {.packed.} + handle*: uint16 + + const + ROLE_DISCOVERY_CP_SIZE* = 2 + type + role_discovery_rp* = object {.packed.} + status*: uint8 + handle*: uint16 + role*: uint8 + + const + ROLE_DISCOVERY_RP_SIZE* = 4 + OCF_SWITCH_ROLE* = 0x0000000B + type + switch_role_cp* = object {.packed.} + bdaddr*: bdaddr_t + role*: uint8 + + const + SWITCH_ROLE_CP_SIZE* = 7 + OCF_READ_LINK_POLICY* = 0x0000000C + type + read_link_policy_cp* = object {.packed.} + handle*: uint16 + + const + READ_LINK_POLICY_CP_SIZE* = 2 + type + read_link_policy_rp* = object {.packed.} + status*: uint8 + handle*: uint16 + policy*: uint16 + + const + READ_LINK_POLICY_RP_SIZE* = 5 + OCF_WRITE_LINK_POLICY* = 0x0000000D + type + write_link_policy_cp* = object {.packed.} + handle*: uint16 + policy*: uint16 + + const + WRITE_LINK_POLICY_CP_SIZE* = 4 + type + write_link_policy_rp* = object {.packed.} + status*: uint8 + handle*: uint16 + + const + WRITE_LINK_POLICY_RP_SIZE* = 3 + OCF_READ_DEFAULT_LINK_POLICY* = 0x0000000E + OCF_WRITE_DEFAULT_LINK_POLICY* = 0x0000000F + OCF_FLOW_SPECIFICATION* = 0x00000010 + OCF_SNIFF_SUBRATING* = 0x00000011 + type + sniff_subrating_cp* = object {.packed.} + handle*: uint16 + max_latency*: uint16 + min_remote_timeout*: uint16 + min_local_timeout*: uint16 + + const + SNIFF_SUBRATING_CP_SIZE* = 8 + # Host Controller and Baseband + const + OGF_HOST_CTL* = 0x00000003 + OCF_SET_EVENT_MASK* = 0x00000001 + type + set_event_mask_cp* = object {.packed.} + mask*: array[8, uint8] + + const + SET_EVENT_MASK_CP_SIZE* = 8 + OCF_RESET* = 0x00000003 + OCF_SET_EVENT_FLT* = 0x00000005 + type + set_event_flt_cp* = object {.packed.} + flt_type*: uint8 + cond_type*: uint8 + condition*: array[0, uint8] + + const + SET_EVENT_FLT_CP_SIZE* = 2 + # Filter types + const + FLT_CLEAR_ALL* = 0x00000000 + FLT_INQ_RESULT* = 0x00000001 + FLT_CONN_SETUP* = 0x00000002 + # INQ_RESULT Condition types + const + INQ_RESULT_RETURN_ALL* = 0x00000000 + INQ_RESULT_RETURN_CLASS* = 0x00000001 + INQ_RESULT_RETURN_BDADDR* = 0x00000002 + # CONN_SETUP Condition types + const + CONN_SETUP_ALLOW_ALL* = 0x00000000 + CONN_SETUP_ALLOW_CLASS* = 0x00000001 + CONN_SETUP_ALLOW_BDADDR* = 0x00000002 + # CONN_SETUP Conditions + const + CONN_SETUP_AUTO_OFF* = 0x00000001 + CONN_SETUP_AUTO_ON* = 0x00000002 + OCF_FLUSH* = 0x00000008 + OCF_READ_PIN_TYPE* = 0x00000009 + type + read_pin_type_rp* = object {.packed.} + status*: uint8 + pin_type*: uint8 + + const + READ_PIN_TYPE_RP_SIZE* = 2 + OCF_WRITE_PIN_TYPE* = 0x0000000A + type + write_pin_type_cp* = object {.packed.} + pin_type*: uint8 + + const + WRITE_PIN_TYPE_CP_SIZE* = 1 + OCF_CREATE_NEW_UNIT_KEY* = 0x0000000B + OCF_READ_STORED_LINK_KEY* = 0x0000000D + type + read_stored_link_key_cp* = object {.packed.} + bdaddr*: bdaddr_t + read_all*: uint8 + + const + READ_STORED_LINK_KEY_CP_SIZE* = 7 + type + read_stored_link_key_rp* = object {.packed.} + status*: uint8 + max_keys*: uint16 + num_keys*: uint16 + + const + READ_STORED_LINK_KEY_RP_SIZE* = 5 + OCF_WRITE_STORED_LINK_KEY* = 0x00000011 + type + write_stored_link_key_cp* = object {.packed.} + num_keys*: uint8 # variable length part + + const + WRITE_STORED_LINK_KEY_CP_SIZE* = 1 + type + write_stored_link_key_rp* = object {.packed.} + status*: uint8 + num_keys*: uint8 + + const + READ_WRITE_LINK_KEY_RP_SIZE* = 2 + OCF_DELETE_STORED_LINK_KEY* = 0x00000012 + type + delete_stored_link_key_cp* = object {.packed.} + bdaddr*: bdaddr_t + delete_all*: uint8 + + const + DELETE_STORED_LINK_KEY_CP_SIZE* = 7 + type + delete_stored_link_key_rp* = object {.packed.} + status*: uint8 + num_keys*: uint16 + + const + DELETE_STORED_LINK_KEY_RP_SIZE* = 3 + HCI_MAX_NAME_LENGTH* = 248 + OCF_CHANGE_LOCAL_NAME* = 0x00000013 + type + change_local_name_cp* = object {.packed.} + name*: array[HCI_MAX_NAME_LENGTH, uint8] + + const + CHANGE_LOCAL_NAME_CP_SIZE* = 248 + OCF_READ_LOCAL_NAME* = 0x00000014 + type + read_local_name_rp* = object {.packed.} + status*: uint8 + name*: array[HCI_MAX_NAME_LENGTH, uint8] + + const + READ_LOCAL_NAME_RP_SIZE* = 249 + OCF_READ_CONN_ACCEPT_TIMEOUT* = 0x00000015 + type + read_conn_accept_timeout_rp* = object {.packed.} + status*: uint8 + timeout*: uint16 + + const + READ_CONN_ACCEPT_TIMEOUT_RP_SIZE* = 3 + OCF_WRITE_CONN_ACCEPT_TIMEOUT* = 0x00000016 + type + write_conn_accept_timeout_cp* = object {.packed.} + timeout*: uint16 + + const + WRITE_CONN_ACCEPT_TIMEOUT_CP_SIZE* = 2 + OCF_READ_PAGE_TIMEOUT* = 0x00000017 + type + read_page_timeout_rp* = object {.packed.} + status*: uint8 + timeout*: uint16 + + const + READ_PAGE_TIMEOUT_RP_SIZE* = 3 + OCF_WRITE_PAGE_TIMEOUT* = 0x00000018 + type + write_page_timeout_cp* = object {.packed.} + timeout*: uint16 + + const + WRITE_PAGE_TIMEOUT_CP_SIZE* = 2 + OCF_READ_SCAN_ENABLE* = 0x00000019 + type + read_scan_enable_rp* = object {.packed.} + status*: uint8 + enable*: uint8 + + const + READ_SCAN_ENABLE_RP_SIZE* = 2 + OCF_WRITE_SCAN_ENABLE* = 0x0000001A + SCAN_DISABLED* = 0x00000000 + SCAN_INQUIRY* = 0x00000001 + SCAN_PAGE* = 0x00000002 + OCF_READ_PAGE_ACTIVITY* = 0x0000001B + type + read_page_activity_rp* = object {.packed.} + status*: uint8 + interval*: uint16 + window*: uint16 + + const + READ_PAGE_ACTIVITY_RP_SIZE* = 5 + OCF_WRITE_PAGE_ACTIVITY* = 0x0000001C + type + write_page_activity_cp* = object {.packed.} + interval*: uint16 + window*: uint16 + + const + WRITE_PAGE_ACTIVITY_CP_SIZE* = 4 + OCF_READ_INQ_ACTIVITY* = 0x0000001D + type + read_inq_activity_rp* = object {.packed.} + status*: uint8 + interval*: uint16 + window*: uint16 + + const + READ_INQ_ACTIVITY_RP_SIZE* = 5 + OCF_WRITE_INQ_ACTIVITY* = 0x0000001E + type + write_inq_activity_cp* = object {.packed.} + interval*: uint16 + window*: uint16 + + const + WRITE_INQ_ACTIVITY_CP_SIZE* = 4 + OCF_READ_AUTH_ENABLE* = 0x0000001F + OCF_WRITE_AUTH_ENABLE* = 0x00000020 + AUTH_DISABLED* = 0x00000000 + AUTH_ENABLED* = 0x00000001 + OCF_READ_ENCRYPT_MODE* = 0x00000021 + OCF_WRITE_ENCRYPT_MODE* = 0x00000022 + ENCRYPT_DISABLED* = 0x00000000 + ENCRYPT_P2P* = 0x00000001 + ENCRYPT_BOTH* = 0x00000002 + OCF_READ_CLASS_OF_DEV* = 0x00000023 + type + read_class_of_dev_rp* = object {.packed.} + status*: uint8 + dev_class*: array[3, uint8] + + const + READ_CLASS_OF_DEV_RP_SIZE* = 4 + OCF_WRITE_CLASS_OF_DEV* = 0x00000024 + type + write_class_of_dev_cp* = object {.packed.} + dev_class*: array[3, uint8] + + const + WRITE_CLASS_OF_DEV_CP_SIZE* = 3 + OCF_READ_VOICE_SETTING* = 0x00000025 + type + read_voice_setting_rp* = object {.packed.} + status*: uint8 + voice_setting*: uint16 + + const + READ_VOICE_SETTING_RP_SIZE* = 3 + OCF_WRITE_VOICE_SETTING* = 0x00000026 + type + write_voice_setting_cp* = object {.packed.} + voice_setting*: uint16 + + const + WRITE_VOICE_SETTING_CP_SIZE* = 2 + OCF_READ_AUTOMATIC_FLUSH_TIMEOUT* = 0x00000027 + OCF_WRITE_AUTOMATIC_FLUSH_TIMEOUT* = 0x00000028 + OCF_READ_NUM_BROADCAST_RETRANS* = 0x00000029 + OCF_WRITE_NUM_BROADCAST_RETRANS* = 0x0000002A + OCF_READ_HOLD_MODE_ACTIVITY* = 0x0000002B + OCF_WRITE_HOLD_MODE_ACTIVITY* = 0x0000002C + OCF_READ_TRANSMIT_POWER_LEVEL* = 0x0000002D + type + read_transmit_power_level_cp* = object {.packed.} + handle*: uint16 + `type`*: uint8 + + const + READ_TRANSMIT_POWER_LEVEL_CP_SIZE* = 3 + type + read_transmit_power_level_rp* = object {.packed.} + status*: uint8 + handle*: uint16 + level*: int8 + + const + READ_TRANSMIT_POWER_LEVEL_RP_SIZE* = 4 + OCF_READ_SYNC_FLOW_ENABLE* = 0x0000002E + OCF_WRITE_SYNC_FLOW_ENABLE* = 0x0000002F + OCF_SET_CONTROLLER_TO_HOST_FC* = 0x00000031 + OCF_HOST_BUFFER_SIZE* = 0x00000033 + type + host_buffer_size_cp* = object {.packed.} + acl_mtu*: uint16 + sco_mtu*: uint8 + acl_max_pkt*: uint16 + sco_max_pkt*: uint16 + + const + HOST_BUFFER_SIZE_CP_SIZE* = 7 + OCF_HOST_NUM_COMP_PKTS* = 0x00000035 + type + host_num_comp_pkts_cp* = object {.packed.} + num_hndl*: uint8 # variable length part + + const + HOST_NUM_COMP_PKTS_CP_SIZE* = 1 + OCF_READ_LINK_SUPERVISION_TIMEOUT* = 0x00000036 + type + read_link_supervision_timeout_rp* = object {.packed.} + status*: uint8 + handle*: uint16 + timeout*: uint16 + + const + READ_LINK_SUPERVISION_TIMEOUT_RP_SIZE* = 5 + OCF_WRITE_LINK_SUPERVISION_TIMEOUT* = 0x00000037 + type + write_link_supervision_timeout_cp* = object {.packed.} + handle*: uint16 + timeout*: uint16 + + const + WRITE_LINK_SUPERVISION_TIMEOUT_CP_SIZE* = 4 + type + write_link_supervision_timeout_rp* = object {.packed.} + status*: uint8 + handle*: uint16 + + const + WRITE_LINK_SUPERVISION_TIMEOUT_RP_SIZE* = 3 + OCF_READ_NUM_SUPPORTED_IAC* = 0x00000038 + MAX_IAC_LAP* = 0x00000040 + OCF_READ_CURRENT_IAC_LAP* = 0x00000039 + type + read_current_iac_lap_rp* = object {.packed.} + status*: uint8 + num_current_iac*: uint8 + lap*: array[MAX_IAC_LAP, array[3, uint8]] + + const + READ_CURRENT_IAC_LAP_RP_SIZE* = 2 + 3 * MAX_IAC_LAP + OCF_WRITE_CURRENT_IAC_LAP* = 0x0000003A + type + write_current_iac_lap_cp* = object {.packed.} + num_current_iac*: uint8 + lap*: array[MAX_IAC_LAP, array[3, uint8]] + + const + WRITE_CURRENT_IAC_LAP_CP_SIZE* = 1 + 3 * MAX_IAC_LAP + OCF_READ_PAGE_SCAN_PERIOD_MODE* = 0x0000003B + OCF_WRITE_PAGE_SCAN_PERIOD_MODE* = 0x0000003C + OCF_READ_PAGE_SCAN_MODE* = 0x0000003D + OCF_WRITE_PAGE_SCAN_MODE* = 0x0000003E + OCF_SET_AFH_CLASSIFICATION* = 0x0000003F + type + set_afh_classification_cp* = object {.packed.} + map*: array[10, uint8] + + const + SET_AFH_CLASSIFICATION_CP_SIZE* = 10 + type + set_afh_classification_rp* = object {.packed.} + status*: uint8 + + const + SET_AFH_CLASSIFICATION_RP_SIZE* = 1 + OCF_READ_INQUIRY_SCAN_TYPE* = 0x00000042 + type + read_inquiry_scan_type_rp* = object {.packed.} + status*: uint8 + `type`*: uint8 + + const + READ_INQUIRY_SCAN_TYPE_RP_SIZE* = 2 + OCF_WRITE_INQUIRY_SCAN_TYPE* = 0x00000043 + type + write_inquiry_scan_type_cp* = object {.packed.} + `type`*: uint8 + + const + WRITE_INQUIRY_SCAN_TYPE_CP_SIZE* = 1 + type + write_inquiry_scan_type_rp* = object {.packed.} + status*: uint8 + + const + WRITE_INQUIRY_SCAN_TYPE_RP_SIZE* = 1 + OCF_READ_INQUIRY_MODE* = 0x00000044 + type + read_inquiry_mode_rp* = object {.packed.} + status*: uint8 + mode*: uint8 + + const + READ_INQUIRY_MODE_RP_SIZE* = 2 + OCF_WRITE_INQUIRY_MODE* = 0x00000045 + type + write_inquiry_mode_cp* = object {.packed.} + mode*: uint8 + + const + WRITE_INQUIRY_MODE_CP_SIZE* = 1 + type + write_inquiry_mode_rp* = object {.packed.} + status*: uint8 + + const + WRITE_INQUIRY_MODE_RP_SIZE* = 1 + OCF_READ_PAGE_SCAN_TYPE* = 0x00000046 + OCF_WRITE_PAGE_SCAN_TYPE* = 0x00000047 + PAGE_SCAN_TYPE_STANDARD* = 0x00000000 + PAGE_SCAN_TYPE_INTERLACED* = 0x00000001 + OCF_READ_AFH_MODE* = 0x00000048 + type + read_afh_mode_rp* = object {.packed.} + status*: uint8 + mode*: uint8 + + const + READ_AFH_MODE_RP_SIZE* = 2 + OCF_WRITE_AFH_MODE* = 0x00000049 + type + write_afh_mode_cp* = object {.packed.} + mode*: uint8 + + const + WRITE_AFH_MODE_CP_SIZE* = 1 + type + write_afh_mode_rp* = object {.packed.} + status*: uint8 + + const + WRITE_AFH_MODE_RP_SIZE* = 1 + HCI_MAX_EIR_LENGTH* = 240 + OCF_READ_EXT_INQUIRY_RESPONSE* = 0x00000051 + type + read_ext_inquiry_response_rp* = object {.packed.} + status*: uint8 + fec*: uint8 + data*: array[HCI_MAX_EIR_LENGTH, uint8] + + const + READ_EXT_INQUIRY_RESPONSE_RP_SIZE* = 242 + OCF_WRITE_EXT_INQUIRY_RESPONSE* = 0x00000052 + type + write_ext_inquiry_response_cp* = object {.packed.} + fec*: uint8 + data*: array[HCI_MAX_EIR_LENGTH, uint8] + + const + WRITE_EXT_INQUIRY_RESPONSE_CP_SIZE* = 241 + type + write_ext_inquiry_response_rp* = object {.packed.} + status*: uint8 + + const + WRITE_EXT_INQUIRY_RESPONSE_RP_SIZE* = 1 + OCF_REFRESH_ENCRYPTION_KEY* = 0x00000053 + type + refresh_encryption_key_cp* = object {.packed.} + handle*: uint16 + + const + REFRESH_ENCRYPTION_KEY_CP_SIZE* = 2 + type + refresh_encryption_key_rp* = object {.packed.} + status*: uint8 + + const + REFRESH_ENCRYPTION_KEY_RP_SIZE* = 1 + OCF_READ_SIMPLE_PAIRING_MODE* = 0x00000055 + type + read_simple_pairing_mode_rp* = object {.packed.} + status*: uint8 + mode*: uint8 + + const + READ_SIMPLE_PAIRING_MODE_RP_SIZE* = 2 + OCF_WRITE_SIMPLE_PAIRING_MODE* = 0x00000056 + type + write_simple_pairing_mode_cp* = object {.packed.} + mode*: uint8 + + const + WRITE_SIMPLE_PAIRING_MODE_CP_SIZE* = 1 + type + write_simple_pairing_mode_rp* = object {.packed.} + status*: uint8 + + const + WRITE_SIMPLE_PAIRING_MODE_RP_SIZE* = 1 + OCF_READ_LOCAL_OOB_DATA* = 0x00000057 + type + read_local_oob_data_rp* = object {.packed.} + status*: uint8 + hash*: array[16, uint8] + randomizer*: array[16, uint8] + + const + READ_LOCAL_OOB_DATA_RP_SIZE* = 33 + OCF_READ_INQ_RESPONSE_TX_POWER_LEVEL* = 0x00000058 + type + read_inq_response_tx_power_level_rp* = object {.packed.} + status*: uint8 + level*: int8 + + const + READ_INQ_RESPONSE_TX_POWER_LEVEL_RP_SIZE* = 2 + OCF_READ_INQUIRY_TRANSMIT_POWER_LEVEL* = 0x00000058 + type + read_inquiry_transmit_power_level_rp* = object {.packed.} + status*: uint8 + level*: int8 + + const + READ_INQUIRY_TRANSMIT_POWER_LEVEL_RP_SIZE* = 2 + OCF_WRITE_INQUIRY_TRANSMIT_POWER_LEVEL* = 0x00000059 + type + write_inquiry_transmit_power_level_cp* = object {.packed.} + level*: int8 + + const + WRITE_INQUIRY_TRANSMIT_POWER_LEVEL_CP_SIZE* = 1 + type + write_inquiry_transmit_power_level_rp* = object {.packed.} + status*: uint8 + + const + WRITE_INQUIRY_TRANSMIT_POWER_LEVEL_RP_SIZE* = 1 + OCF_READ_DEFAULT_ERROR_DATA_REPORTING* = 0x0000005A + type + read_default_error_data_reporting_rp* = object {.packed.} + status*: uint8 + reporting*: uint8 + + const + READ_DEFAULT_ERROR_DATA_REPORTING_RP_SIZE* = 2 + OCF_WRITE_DEFAULT_ERROR_DATA_REPORTING* = 0x0000005B + type + write_default_error_data_reporting_cp* = object {.packed.} + reporting*: uint8 + + const + WRITE_DEFAULT_ERROR_DATA_REPORTING_CP_SIZE* = 1 + type + write_default_error_data_reporting_rp* = object {.packed.} + status*: uint8 + + const + WRITE_DEFAULT_ERROR_DATA_REPORTING_RP_SIZE* = 1 + OCF_ENHANCED_FLUSH* = 0x0000005F + type + enhanced_flush_cp* = object {.packed.} + handle*: uint16 + `type`*: uint8 + + const + ENHANCED_FLUSH_CP_SIZE* = 3 + OCF_SEND_KEYPRESS_NOTIFY* = 0x00000060 + type + send_keypress_notify_cp* = object {.packed.} + bdaddr*: bdaddr_t + `type`*: uint8 + + const + SEND_KEYPRESS_NOTIFY_CP_SIZE* = 7 + type + send_keypress_notify_rp* = object {.packed.} + status*: uint8 + + const + SEND_KEYPRESS_NOTIFY_RP_SIZE* = 1 + OCF_READ_LOGICAL_LINK_ACCEPT_TIMEOUT* = 0x00000061 + type + read_log_link_accept_timeout_rp* = object {.packed.} + status*: uint8 + timeout*: uint16 + + const + READ_LOGICAL_LINK_ACCEPT_TIMEOUT_RP_SIZE* = 3 + OCF_WRITE_LOGICAL_LINK_ACCEPT_TIMEOUT* = 0x00000062 + type + write_log_link_accept_timeout_cp* = object {.packed.} + timeout*: uint16 + + const + WRITE_LOGICAL_LINK_ACCEPT_TIMEOUT_CP_SIZE* = 2 + OCF_SET_EVENT_MASK_PAGE_2* = 0x00000063 + OCF_READ_LOCATION_DATA* = 0x00000064 + OCF_WRITE_LOCATION_DATA* = 0x00000065 + OCF_READ_FLOW_CONTROL_MODE* = 0x00000066 + OCF_WRITE_FLOW_CONTROL_MODE* = 0x00000067 + OCF_READ_ENHANCED_TRANSMIT_POWER_LEVEL* = 0x00000068 + type + read_enhanced_transmit_power_level_rp* = object {.packed.} + status*: uint8 + handle*: uint16 + level_gfsk*: int8 + level_dqpsk*: int8 + level_8dpsk*: int8 + + const + READ_ENHANCED_TRANSMIT_POWER_LEVEL_RP_SIZE* = 6 + OCF_READ_BEST_EFFORT_FLUSH_TIMEOUT* = 0x00000069 + type + read_best_effort_flush_timeout_rp* = object {.packed.} + status*: uint8 + timeout*: uint32 + + const + READ_BEST_EFFORT_FLUSH_TIMEOUT_RP_SIZE* = 5 + OCF_WRITE_BEST_EFFORT_FLUSH_TIMEOUT* = 0x0000006A + type + write_best_effort_flush_timeout_cp* = object {.packed.} + handle*: uint16 + timeout*: uint32 + + const + WRITE_BEST_EFFORT_FLUSH_TIMEOUT_CP_SIZE* = 6 + type + write_best_effort_flush_timeout_rp* = object {.packed.} + status*: uint8 + + const + WRITE_BEST_EFFORT_FLUSH_TIMEOUT_RP_SIZE* = 1 + OCF_READ_LE_HOST_SUPPORTED* = 0x0000006C + type + read_le_host_supported_rp* = object {.packed.} + status*: uint8 + le*: uint8 + simul*: uint8 + + const + READ_LE_HOST_SUPPORTED_RP_SIZE* = 3 + OCF_WRITE_LE_HOST_SUPPORTED* = 0x0000006D + type + write_le_host_supported_cp* = object {.packed.} + le*: uint8 + simul*: uint8 + + const + WRITE_LE_HOST_SUPPORTED_CP_SIZE* = 2 + # Informational Parameters + const + OGF_INFO_PARAM* = 0x00000004 + OCF_READ_LOCAL_VERSION* = 0x00000001 + type + read_local_version_rp* = object {.packed.} + status*: uint8 + hci_ver*: uint8 + hci_rev*: uint16 + lmp_ver*: uint8 + manufacturer*: uint16 + lmp_subver*: uint16 + + const + READ_LOCAL_VERSION_RP_SIZE* = 9 + OCF_READ_LOCAL_COMMANDS* = 0x00000002 + type + read_local_commands_rp* = object {.packed.} + status*: uint8 + commands*: array[64, uint8] + + const + READ_LOCAL_COMMANDS_RP_SIZE* = 65 + OCF_READ_LOCAL_FEATURES* = 0x00000003 + type + read_local_features_rp* = object {.packed.} + status*: uint8 + features*: array[8, uint8] + + const + READ_LOCAL_FEATURES_RP_SIZE* = 9 + OCF_READ_LOCAL_EXT_FEATURES* = 0x00000004 + type + read_local_ext_features_cp* = object {.packed.} + page_num*: uint8 + + const + READ_LOCAL_EXT_FEATURES_CP_SIZE* = 1 + type + read_local_ext_features_rp* = object {.packed.} + status*: uint8 + page_num*: uint8 + max_page_num*: uint8 + features*: array[8, uint8] + + const + READ_LOCAL_EXT_FEATURES_RP_SIZE* = 11 + OCF_READ_BUFFER_SIZE* = 0x00000005 + type + read_buffer_size_rp* = object {.packed.} + status*: uint8 + acl_mtu*: uint16 + sco_mtu*: uint8 + acl_max_pkt*: uint16 + sco_max_pkt*: uint16 + + const + READ_BUFFER_SIZE_RP_SIZE* = 8 + OCF_READ_COUNTRY_CODE* = 0x00000007 + OCF_READ_BD_ADDR* = 0x00000009 + type + read_bd_addr_rp* = object {.packed.} + status*: uint8 + bdaddr*: bdaddr_t + + const + READ_BD_ADDR_RP_SIZE* = 7 + # Status params + const + OGF_STATUS_PARAM* = 0x00000005 + OCF_READ_FAILED_CONTACT_COUNTER* = 0x00000001 + type + read_failed_contact_counter_rp* = object {.packed.} + status*: uint8 + handle*: uint16 + counter*: uint8 + + const + READ_FAILED_CONTACT_COUNTER_RP_SIZE* = 4 + OCF_RESET_FAILED_CONTACT_COUNTER* = 0x00000002 + type + reset_failed_contact_counter_rp* = object {.packed.} + status*: uint8 + handle*: uint16 + + const + RESET_FAILED_CONTACT_COUNTER_RP_SIZE* = 4 + OCF_READ_LINK_QUALITY* = 0x00000003 + type + read_link_quality_rp* = object {.packed.} + status*: uint8 + handle*: uint16 + link_quality*: uint8 + + const + READ_LINK_QUALITY_RP_SIZE* = 4 + OCF_READ_RSSI* = 0x00000005 + type + read_rssi_rp* = object {.packed.} + status*: uint8 + handle*: uint16 + rssi*: int8 + + const + READ_RSSI_RP_SIZE* = 4 + OCF_READ_AFH_MAP* = 0x00000006 + type + read_afh_map_rp* = object {.packed.} + status*: uint8 + handle*: uint16 + mode*: uint8 + map*: array[10, uint8] + + const + READ_AFH_MAP_RP_SIZE* = 14 + OCF_READ_CLOCK* = 0x00000007 + type + read_clock_cp* = object {.packed.} + handle*: uint16 + which_clock*: uint8 + + const + READ_CLOCK_CP_SIZE* = 3 + type + read_clock_rp* = object {.packed.} + status*: uint8 + handle*: uint16 + clock*: uint32 + accuracy*: uint16 + + const + READ_CLOCK_RP_SIZE* = 9 + OCF_READ_LOCAL_AMP_INFO* = 0x00000009 + type + read_local_amp_info_rp* = object {.packed.} + status*: uint8 + amp_status*: uint8 + total_bandwidth*: uint32 + max_guaranteed_bandwidth*: uint32 + min_latency*: uint32 + max_pdu_size*: uint32 + controller_type*: uint8 + pal_caps*: uint16 + max_amp_assoc_length*: uint16 + max_flush_timeout*: uint32 + best_effort_flush_timeout*: uint32 + + const + READ_LOCAL_AMP_INFO_RP_SIZE* = 31 + OCF_READ_LOCAL_AMP_ASSOC* = 0x0000000A + type + read_local_amp_assoc_cp* = object {.packed.} + handle*: uint8 + len_so_far*: uint16 + max_len*: uint16 + + read_local_amp_assoc_rp* = object {.packed.} + status*: uint8 + handle*: uint8 + rem_len*: uint16 + frag*: array[0, uint8] + + const + OCF_WRITE_REMOTE_AMP_ASSOC* = 0x0000000B + type + write_remote_amp_assoc_cp* = object {.packed.} + handle*: uint8 + length_so_far*: uint16 + assoc_length*: uint16 + fragment*: array[HCI_MAX_NAME_LENGTH, uint8] + + const + WRITE_REMOTE_AMP_ASSOC_CP_SIZE* = 253 + type + write_remote_amp_assoc_rp* = object {.packed.} + status*: uint8 + handle*: uint8 + + const + WRITE_REMOTE_AMP_ASSOC_RP_SIZE* = 2 + # Testing commands + const + OGF_TESTING_CMD* = 0x0000003E + OCF_READ_LOOPBACK_MODE* = 0x00000001 + OCF_WRITE_LOOPBACK_MODE* = 0x00000002 + OCF_ENABLE_DEVICE_UNDER_TEST_MODE* = 0x00000003 + OCF_WRITE_SIMPLE_PAIRING_DEBUG_MODE* = 0x00000004 + type + write_simple_pairing_debug_mode_cp* = object {.packed.} + mode*: uint8 + + const + WRITE_SIMPLE_PAIRING_DEBUG_MODE_CP_SIZE* = 1 + type + write_simple_pairing_debug_mode_rp* = object {.packed.} + status*: uint8 + + const + WRITE_SIMPLE_PAIRING_DEBUG_MODE_RP_SIZE* = 1 + # LE commands + const + OGF_LE_CTL* = 0x00000008 + OCF_LE_SET_EVENT_MASK* = 0x00000001 + type + le_set_event_mask_cp* = object {.packed.} + mask*: array[8, uint8] + + const + LE_SET_EVENT_MASK_CP_SIZE* = 8 + OCF_LE_READ_BUFFER_SIZE* = 0x00000002 + type + le_read_buffer_size_rp* = object {.packed.} + status*: uint8 + pkt_len*: uint16 + max_pkt*: uint8 + + const + LE_READ_BUFFER_SIZE_RP_SIZE* = 4 + OCF_LE_READ_LOCAL_SUPPORTED_FEATURES* = 0x00000003 + type + le_read_local_supported_features_rp* = object {.packed.} + status*: uint8 + features*: array[8, uint8] + + const + LE_READ_LOCAL_SUPPORTED_FEATURES_RP_SIZE* = 9 + OCF_LE_SET_RANDOM_ADDRESS* = 0x00000005 + type + le_set_random_address_cp* = object {.packed.} + bdaddr*: bdaddr_t + + const + LE_SET_RANDOM_ADDRESS_CP_SIZE* = 6 + OCF_LE_SET_ADVERTISING_PARAMETERS* = 0x00000006 + type + le_set_advertising_parameters_cp* = object {.packed.} + min_interval*: uint16 + max_interval*: uint16 + advtype*: uint8 + own_bdaddr_type*: uint8 + direct_bdaddr_type*: uint8 + direct_bdaddr*: bdaddr_t + chan_map*: uint8 + filter*: uint8 + + const + LE_SET_ADVERTISING_PARAMETERS_CP_SIZE* = 15 + OCF_LE_READ_ADVERTISING_CHANNEL_TX_POWER* = 0x00000007 + type + le_read_advertising_channel_tx_power_rp* = object {.packed.} + status*: uint8 + level*: uint8 + + const + LE_READ_ADVERTISING_CHANNEL_TX_POWER_RP_SIZE* = 2 + OCF_LE_SET_ADVERTISING_DATA* = 0x00000008 + type + le_set_advertising_data_cp* = object {.packed.} + length*: uint8 + data*: array[31, uint8] + + const + LE_SET_ADVERTISING_DATA_CP_SIZE* = 32 + OCF_LE_SET_SCAN_RESPONSE_DATA* = 0x00000009 + type + le_set_scan_response_data_cp* = object {.packed.} + length*: uint8 + data*: array[31, uint8] + + const + LE_SET_SCAN_RESPONSE_DATA_CP_SIZE* = 32 + OCF_LE_SET_ADVERTISE_ENABLE* = 0x0000000A + type + le_set_advertise_enable_cp* = object {.packed.} + enable*: uint8 + + const + LE_SET_ADVERTISE_ENABLE_CP_SIZE* = 1 + OCF_LE_SET_SCAN_PARAMETERS* = 0x0000000B + type + le_set_scan_parameters_cp* = object {.packed.} + `type`*: uint8 + interval*: uint16 + window*: uint16 + own_bdaddr_type*: uint8 + filter*: uint8 + + const + LE_SET_SCAN_PARAMETERS_CP_SIZE* = 7 + OCF_LE_SET_SCAN_ENABLE* = 0x0000000C + type + le_set_scan_enable_cp* = object {.packed.} + enable*: uint8 + filter_dup*: uint8 + + const + LE_SET_SCAN_ENABLE_CP_SIZE* = 2 + OCF_LE_CREATE_CONN* = 0x0000000D + type + le_create_connection_cp* = object {.packed.} + interval*: uint16 + window*: uint16 + initiator_filter*: uint8 + peer_bdaddr_type*: uint8 + peer_bdaddr*: bdaddr_t + own_bdaddr_type*: uint8 + min_interval*: uint16 + max_interval*: uint16 + latency*: uint16 + supervision_timeout*: uint16 + min_ce_length*: uint16 + max_ce_length*: uint16 + + const + LE_CREATE_CONN_CP_SIZE* = 25 + OCF_LE_CREATE_CONN_CANCEL* = 0x0000000E + OCF_LE_READ_WHITE_LIST_SIZE* = 0x0000000F + type + le_read_white_list_size_rp* = object {.packed.} + status*: uint8 + size*: uint8 + + const + LE_READ_WHITE_LIST_SIZE_RP_SIZE* = 2 + OCF_LE_CLEAR_WHITE_LIST* = 0x00000010 + OCF_LE_ADD_DEVICE_TO_WHITE_LIST* = 0x00000011 + type + le_add_device_to_white_list_cp* = object {.packed.} + bdaddr_type*: uint8 + bdaddr*: bdaddr_t + + const + LE_ADD_DEVICE_TO_WHITE_LIST_CP_SIZE* = 7 + OCF_LE_REMOVE_DEVICE_FROM_WHITE_LIST* = 0x00000012 + type + le_remove_device_from_white_list_cp* = object {.packed.} + bdaddr_type*: uint8 + bdaddr*: bdaddr_t + + const + LE_REMOVE_DEVICE_FROM_WHITE_LIST_CP_SIZE* = 7 + OCF_LE_CONN_UPDATE* = 0x00000013 + type + le_connection_update_cp* = object {.packed.} + handle*: uint16 + min_interval*: uint16 + max_interval*: uint16 + latency*: uint16 + supervision_timeout*: uint16 + min_ce_length*: uint16 + max_ce_length*: uint16 + + const + LE_CONN_UPDATE_CP_SIZE* = 14 + OCF_LE_SET_HOST_CHANNEL_CLASSIFICATION* = 0x00000014 + type + le_set_host_channel_classification_cp* = object {.packed.} + map*: array[5, uint8] + + const + LE_SET_HOST_CHANNEL_CLASSIFICATION_CP_SIZE* = 5 + OCF_LE_READ_CHANNEL_MAP* = 0x00000015 + type + le_read_channel_map_cp* = object {.packed.} + handle*: uint16 + + const + LE_READ_CHANNEL_MAP_CP_SIZE* = 2 + type + le_read_channel_map_rp* = object {.packed.} + status*: uint8 + handle*: uint16 + map*: array[5, uint8] + + const + LE_READ_CHANNEL_MAP_RP_SIZE* = 8 + OCF_LE_READ_REMOTE_USED_FEATURES* = 0x00000016 + type + le_read_remote_used_features_cp* = object {.packed.} + handle*: uint16 + + const + LE_READ_REMOTE_USED_FEATURES_CP_SIZE* = 2 + OCF_LE_ENCRYPT* = 0x00000017 + type + le_encrypt_cp* = object {.packed.} + key*: array[16, uint8] + plaintext*: array[16, uint8] + + const + LE_ENCRYPT_CP_SIZE* = 32 + type + le_encrypt_rp* = object {.packed.} + status*: uint8 + data*: array[16, uint8] + + const + LE_ENCRYPT_RP_SIZE* = 17 + OCF_LE_RAND* = 0x00000018 + type + le_rand_rp* = object {.packed.} + status*: uint8 + random*: uint64 + + const + LE_RAND_RP_SIZE* = 9 + OCF_LE_START_ENCRYPTION* = 0x00000019 + type + le_start_encryption_cp* = object {.packed.} + handle*: uint16 + random*: uint64 + diversifier*: uint16 + key*: array[16, uint8] + + const + LE_START_ENCRYPTION_CP_SIZE* = 28 + OCF_LE_LTK_REPLY* = 0x0000001A + type + le_ltk_reply_cp* = object {.packed.} + handle*: uint16 + key*: array[16, uint8] + + const + LE_LTK_REPLY_CP_SIZE* = 18 + type + le_ltk_reply_rp* = object {.packed.} + status*: uint8 + handle*: uint16 + + const + LE_LTK_REPLY_RP_SIZE* = 3 + OCF_LE_LTK_NEG_REPLY* = 0x0000001B + type + le_ltk_neg_reply_cp* = object {.packed.} + handle*: uint16 + + const + LE_LTK_NEG_REPLY_CP_SIZE* = 2 + type + le_ltk_neg_reply_rp* = object {.packed.} + status*: uint8 + handle*: uint16 + + const + LE_LTK_NEG_REPLY_RP_SIZE* = 3 + OCF_LE_READ_SUPPORTED_STATES* = 0x0000001C + type + le_read_supported_states_rp* = object {.packed.} + status*: uint8 + states*: uint64 + + const + LE_READ_SUPPORTED_STATES_RP_SIZE* = 9 + OCF_LE_RECEIVER_TEST* = 0x0000001D + type + le_receiver_test_cp* = object {.packed.} + frequency*: uint8 + + const + LE_RECEIVER_TEST_CP_SIZE* = 1 + OCF_LE_TRANSMITTER_TEST* = 0x0000001E + type + le_transmitter_test_cp* = object {.packed.} + frequency*: uint8 + length*: uint8 + payload*: uint8 + + const + LE_TRANSMITTER_TEST_CP_SIZE* = 3 + OCF_LE_TEST_END* = 0x0000001F + type + le_test_end_rp* = object {.packed.} + status*: uint8 + num_pkts*: uint16 + + const + LE_TEST_END_RP_SIZE* = 3 + # Vendor specific commands + const + OGF_VENDOR_CMD* = 0x0000003F + # ---- HCI Events ---- + const + EVT_INQUIRY_COMPLETE* = 0x00000001 + EVT_INQUIRY_RESULT* = 0x00000002 + type + inquiry_info* = object {.packed.} + bdaddr*: bdaddr_t + pscan_rep_mode*: uint8 + pscan_period_mode*: uint8 + pscan_mode*: uint8 + dev_class*: array[3, uint8] + clock_offset*: uint16 + + const + INQUIRY_INFO_SIZE* = 14 + EVT_CONN_COMPLETE* = 0x00000003 + type + evt_conn_complete* = object {.packed.} + status*: uint8 + handle*: uint16 + bdaddr*: bdaddr_t + link_type*: uint8 + encr_mode*: uint8 + + const + EVT_CONN_COMPLETE_SIZE* = 13 + EVT_CONN_REQUEST* = 0x00000004 + type + evt_conn_request* = object {.packed.} + bdaddr*: bdaddr_t + dev_class*: array[3, uint8] + link_type*: uint8 + + const + EVT_CONN_REQUEST_SIZE* = 10 + EVT_DISCONN_COMPLETE* = 0x00000005 + type + evt_disconn_complete* = object {.packed.} + status*: uint8 + handle*: uint16 + reason*: uint8 + + const + EVT_DISCONN_COMPLETE_SIZE* = 4 + EVT_AUTH_COMPLETE* = 0x00000006 + type + evt_auth_complete* = object {.packed.} + status*: uint8 + handle*: uint16 + + const + EVT_AUTH_COMPLETE_SIZE* = 3 + EVT_REMOTE_NAME_REQ_COMPLETE* = 0x00000007 + type + evt_remote_name_req_complete* = object {.packed.} + status*: uint8 + bdaddr*: bdaddr_t + name*: array[HCI_MAX_NAME_LENGTH, uint8] + + const + EVT_REMOTE_NAME_REQ_COMPLETE_SIZE* = 255 + EVT_ENCRYPT_CHANGE* = 0x00000008 + type + evt_encrypt_change* = object {.packed.} + status*: uint8 + handle*: uint16 + encrypt*: uint8 + + const + EVT_ENCRYPT_CHANGE_SIZE* = 5 + EVT_CHANGE_CONN_LINK_KEY_COMPLETE* = 0x00000009 + type + evt_change_conn_link_key_complete* = object {.packed.} + status*: uint8 + handle*: uint16 + + const + EVT_CHANGE_CONN_LINK_KEY_COMPLETE_SIZE* = 3 + EVT_MASTER_LINK_KEY_COMPLETE* = 0x0000000A + type + evt_master_link_key_complete* = object {.packed.} + status*: uint8 + handle*: uint16 + key_flag*: uint8 + + const + EVT_MASTER_LINK_KEY_COMPLETE_SIZE* = 4 + EVT_READ_REMOTE_FEATURES_COMPLETE* = 0x0000000B + type + evt_read_remote_features_complete* = object {.packed.} + status*: uint8 + handle*: uint16 + features*: array[8, uint8] + + const + EVT_READ_REMOTE_FEATURES_COMPLETE_SIZE* = 11 + EVT_READ_REMOTE_VERSION_COMPLETE* = 0x0000000C + type + evt_read_remote_version_complete* = object {.packed.} + status*: uint8 + handle*: uint16 + lmp_ver*: uint8 + manufacturer*: uint16 + lmp_subver*: uint16 + + const + EVT_READ_REMOTE_VERSION_COMPLETE_SIZE* = 8 + EVT_QOS_SETUP_COMPLETE* = 0x0000000D + type + evt_qos_setup_complete* = object {.packed.} + status*: uint8 + handle*: uint16 + flags*: uint8 # Reserved + qos*: hci_qos + + const + EVT_QOS_SETUP_COMPLETE_SIZE* = (4 + HCI_QOS_CP_SIZE) + EVT_CMD_COMPLETE* = 0x0000000E + type + evt_cmd_complete* = object {.packed.} + ncmd*: uint8 + opcode*: uint16 + + const + EVT_CMD_COMPLETE_SIZE* = 3 + EVT_CMD_STATUS* = 0x0000000F + type + evt_cmd_status* = object {.packed.} + status*: uint8 + ncmd*: uint8 + opcode*: uint16 + + const + EVT_CMD_STATUS_SIZE* = 4 + EVT_HARDWARE_ERROR* = 0x00000010 + type + evt_hardware_error* = object {.packed.} + code*: uint8 + + const + EVT_HARDWARE_ERROR_SIZE* = 1 + EVT_FLUSH_OCCURRED* = 0x00000011 + type + evt_flush_occured* = object {.packed.} + handle*: uint16 + + const + EVT_FLUSH_OCCURRED_SIZE* = 2 + EVT_ROLE_CHANGE* = 0x00000012 + type + evt_role_change* = object {.packed.} + status*: uint8 + bdaddr*: bdaddr_t + role*: uint8 + + const + EVT_ROLE_CHANGE_SIZE* = 8 + EVT_NUM_COMP_PKTS* = 0x00000013 + type + evt_num_comp_pkts* = object {.packed.} + num_hndl*: uint8 # variable length part + + const + EVT_NUM_COMP_PKTS_SIZE* = 1 + EVT_MODE_CHANGE* = 0x00000014 + type + evt_mode_change* = object {.packed.} + status*: uint8 + handle*: uint16 + mode*: uint8 + interval*: uint16 + + const + EVT_MODE_CHANGE_SIZE* = 6 + EVT_RETURN_LINK_KEYS* = 0x00000015 + type + evt_return_link_keys* = object {.packed.} + num_keys*: uint8 # variable length part + + const + EVT_RETURN_LINK_KEYS_SIZE* = 1 + EVT_PIN_CODE_REQ* = 0x00000016 + type + evt_pin_code_req* = object {.packed.} + bdaddr*: bdaddr_t + + const + EVT_PIN_CODE_REQ_SIZE* = 6 + EVT_LINK_KEY_REQ* = 0x00000017 + type + evt_link_key_req* = object {.packed.} + bdaddr*: bdaddr_t + + const + EVT_LINK_KEY_REQ_SIZE* = 6 + EVT_LINK_KEY_NOTIFY* = 0x00000018 + type + evt_link_key_notify* = object {.packed.} + bdaddr*: bdaddr_t + link_key*: array[16, uint8] + key_type*: uint8 + + const + EVT_LINK_KEY_NOTIFY_SIZE* = 23 + EVT_LOOPBACK_COMMAND* = 0x00000019 + EVT_DATA_BUFFER_OVERFLOW* = 0x0000001A + type + evt_data_buffer_overflow* = object {.packed.} + link_type*: uint8 + + const + EVT_DATA_BUFFER_OVERFLOW_SIZE* = 1 + EVT_MAX_SLOTS_CHANGE* = 0x0000001B + type + evt_max_slots_change* = object {.packed.} + handle*: uint16 + max_slots*: uint8 + + const + EVT_MAX_SLOTS_CHANGE_SIZE* = 3 + EVT_READ_CLOCK_OFFSET_COMPLETE* = 0x0000001C + type + evt_read_clock_offset_complete* = object {.packed.} + status*: uint8 + handle*: uint16 + clock_offset*: uint16 + + const + EVT_READ_CLOCK_OFFSET_COMPLETE_SIZE* = 5 + EVT_CONN_PTYPE_CHANGED* = 0x0000001D + type + evt_conn_ptype_changed* = object {.packed.} + status*: uint8 + handle*: uint16 + ptype*: uint16 + + const + EVT_CONN_PTYPE_CHANGED_SIZE* = 5 + EVT_QOS_VIOLATION* = 0x0000001E + type + evt_qos_violation* = object {.packed.} + handle*: uint16 + + const + EVT_QOS_VIOLATION_SIZE* = 2 + EVT_PSCAN_REP_MODE_CHANGE* = 0x00000020 + type + evt_pscan_rep_mode_change* = object {.packed.} + bdaddr*: bdaddr_t + pscan_rep_mode*: uint8 + + const + EVT_PSCAN_REP_MODE_CHANGE_SIZE* = 7 + EVT_FLOW_SPEC_COMPLETE* = 0x00000021 + type + evt_flow_spec_complete* = object {.packed.} + status*: uint8 + handle*: uint16 + flags*: uint8 + direction*: uint8 + qos*: hci_qos + + const + EVT_FLOW_SPEC_COMPLETE_SIZE* = (5 + HCI_QOS_CP_SIZE) + EVT_INQUIRY_RESULT_WITH_RSSI* = 0x00000022 + type + inquiry_info_with_rssi* = object {.packed.} + bdaddr*: bdaddr_t + pscan_rep_mode*: uint8 + pscan_period_mode*: uint8 + dev_class*: array[3, uint8] + clock_offset*: uint16 + rssi*: int8 + + const + INQUIRY_INFO_WITH_RSSI_SIZE* = 14 + type + inquiry_info_with_rssi_and_pscan_mode* = object {.packed.} + bdaddr*: bdaddr_t + pscan_rep_mode*: uint8 + pscan_period_mode*: uint8 + pscan_mode*: uint8 + dev_class*: array[3, uint8] + clock_offset*: uint16 + rssi*: int8 + + const + INQUIRY_INFO_WITH_RSSI_AND_PSCAN_MODE_SIZE* = 15 + EVT_READ_REMOTE_EXT_FEATURES_COMPLETE* = 0x00000023 + type + evt_read_remote_ext_features_complete* = object {.packed.} + status*: uint8 + handle*: uint16 + page_num*: uint8 + max_page_num*: uint8 + features*: array[8, uint8] + + const + EVT_READ_REMOTE_EXT_FEATURES_COMPLETE_SIZE* = 13 + EVT_SYNC_CONN_COMPLETE* = 0x0000002C + type + evt_sync_conn_complete* = object {.packed.} + status*: uint8 + handle*: uint16 + bdaddr*: bdaddr_t + link_type*: uint8 + trans_interval*: uint8 + retrans_window*: uint8 + rx_pkt_len*: uint16 + tx_pkt_len*: uint16 + air_mode*: uint8 + + const + EVT_SYNC_CONN_COMPLETE_SIZE* = 17 + EVT_SYNC_CONN_CHANGED* = 0x0000002D + type + evt_sync_conn_changed* = object {.packed.} + status*: uint8 + handle*: uint16 + trans_interval*: uint8 + retrans_window*: uint8 + rx_pkt_len*: uint16 + tx_pkt_len*: uint16 + + const + EVT_SYNC_CONN_CHANGED_SIZE* = 9 + EVT_SNIFF_SUBRATING* = 0x0000002E + type + evt_sniff_subrating* = object {.packed.} + status*: uint8 + handle*: uint16 + max_tx_latency*: uint16 + max_rx_latency*: uint16 + min_remote_timeout*: uint16 + min_local_timeout*: uint16 + + const + EVT_SNIFF_SUBRATING_SIZE* = 11 + EVT_EXTENDED_INQUIRY_RESULT* = 0x0000002F + type + extended_inquiry_info* = object {.packed.} + bdaddr*: bdaddr_t + pscan_rep_mode*: uint8 + pscan_period_mode*: uint8 + dev_class*: array[3, uint8] + clock_offset*: uint16 + rssi*: int8 + data*: array[HCI_MAX_EIR_LENGTH, uint8] + + const + EXTENDED_INQUIRY_INFO_SIZE* = 254 + EVT_ENCRYPTION_KEY_REFRESH_COMPLETE* = 0x00000030 + type + evt_encryption_key_refresh_complete* = object {.packed.} + status*: uint8 + handle*: uint16 + + const + EVT_ENCRYPTION_KEY_REFRESH_COMPLETE_SIZE* = 3 + EVT_IO_CAPABILITY_REQUEST* = 0x00000031 + type + evt_io_capability_request* = object {.packed.} + bdaddr*: bdaddr_t + + const + EVT_IO_CAPABILITY_REQUEST_SIZE* = 6 + EVT_IO_CAPABILITY_RESPONSE* = 0x00000032 + type + evt_io_capability_response* = object {.packed.} + bdaddr*: bdaddr_t + capability*: uint8 + oob_data*: uint8 + authentication*: uint8 + + const + EVT_IO_CAPABILITY_RESPONSE_SIZE* = 9 + EVT_USER_CONFIRM_REQUEST* = 0x00000033 + type + evt_user_confirm_request* = object {.packed.} + bdaddr*: bdaddr_t + passkey*: uint32 + + const + EVT_USER_CONFIRM_REQUEST_SIZE* = 10 + EVT_USER_PASSKEY_REQUEST* = 0x00000034 + type + evt_user_passkey_request* = object {.packed.} + bdaddr*: bdaddr_t + + const + EVT_USER_PASSKEY_REQUEST_SIZE* = 6 + EVT_REMOTE_OOB_DATA_REQUEST* = 0x00000035 + type + evt_remote_oob_data_request* = object {.packed.} + bdaddr*: bdaddr_t + + const + EVT_REMOTE_OOB_DATA_REQUEST_SIZE* = 6 + EVT_SIMPLE_PAIRING_COMPLETE* = 0x00000036 + type + evt_simple_pairing_complete* = object {.packed.} + status*: uint8 + bdaddr*: bdaddr_t + + const + EVT_SIMPLE_PAIRING_COMPLETE_SIZE* = 7 + EVT_LINK_SUPERVISION_TIMEOUT_CHANGED* = 0x00000038 + type + evt_link_supervision_timeout_changed* = object {.packed.} + handle*: uint16 + timeout*: uint16 + + const + EVT_LINK_SUPERVISION_TIMEOUT_CHANGED_SIZE* = 4 + EVT_ENHANCED_FLUSH_COMPLETE* = 0x00000039 + type + evt_enhanced_flush_complete* = object {.packed.} + handle*: uint16 + + const + EVT_ENHANCED_FLUSH_COMPLETE_SIZE* = 2 + EVT_USER_PASSKEY_NOTIFY* = 0x0000003B + type + evt_user_passkey_notify* = object {.packed.} + bdaddr*: bdaddr_t + passkey*: uint32 + entered*: uint8 + + const + EVT_USER_PASSKEY_NOTIFY_SIZE* = 11 + EVT_KEYPRESS_NOTIFY* = 0x0000003C + type + evt_keypress_notify* = object {.packed.} + bdaddr*: bdaddr_t + `type`*: uint8 + + const + EVT_KEYPRESS_NOTIFY_SIZE* = 7 + EVT_REMOTE_HOST_FEATURES_NOTIFY* = 0x0000003D + type + evt_remote_host_features_notify* = object {.packed.} + bdaddr*: bdaddr_t + features*: array[8, uint8] + + const + EVT_REMOTE_HOST_FEATURES_NOTIFY_SIZE* = 14 + EVT_LE_META_EVENT* = 0x0000003E + type + evt_le_meta_event* = object {.packed.} + subevent*: uint8 + data*: array[0, uint8] + + const + EVT_LE_META_EVENT_SIZE* = 1 + EVT_LE_CONN_COMPLETE* = 0x00000001 + type + evt_le_connection_complete* = object {.packed.} + status*: uint8 + handle*: uint16 + role*: uint8 + peer_bdaddr_type*: uint8 + peer_bdaddr*: bdaddr_t + interval*: uint16 + latency*: uint16 + supervision_timeout*: uint16 + master_clock_accuracy*: uint8 + + const + EVT_LE_CONN_COMPLETE_SIZE* = 18 + EVT_LE_ADVERTISING_REPORT* = 0x00000002 + type + le_advertising_info* = object {.packed.} + evt_type*: uint8 + bdaddr_type*: uint8 + bdaddr*: bdaddr_t + length*: uint8 + data*: array[0, uint8] + + const + LE_ADVERTISING_INFO_SIZE* = 9 + EVT_LE_CONN_UPDATE_COMPLETE* = 0x00000003 + type + evt_le_connection_update_complete* = object {.packed.} + status*: uint8 + handle*: uint16 + interval*: uint16 + latency*: uint16 + supervision_timeout*: uint16 + + const + EVT_LE_CONN_UPDATE_COMPLETE_SIZE* = 9 + EVT_LE_READ_REMOTE_USED_FEATURES_COMPLETE* = 0x00000004 + type + evt_le_read_remote_used_features_complete* = object {.packed.} + status*: uint8 + handle*: uint16 + features*: array[8, uint8] + + const + EVT_LE_READ_REMOTE_USED_FEATURES_COMPLETE_SIZE* = 11 + EVT_LE_LTK_REQUEST* = 0x00000005 + type + evt_le_long_term_key_request* = object {.packed.} + handle*: uint16 + random*: uint64 + diversifier*: uint16 + + const + EVT_LE_LTK_REQUEST_SIZE* = 12 + EVT_PHYSICAL_LINK_COMPLETE* = 0x00000040 + type + evt_physical_link_complete* = object {.packed.} + status*: uint8 + handle*: uint8 + + const + EVT_PHYSICAL_LINK_COMPLETE_SIZE* = 2 + EVT_CHANNEL_SELECTED* = 0x00000041 + EVT_DISCONNECT_PHYSICAL_LINK_COMPLETE* = 0x00000042 + type + evt_disconn_physical_link_complete* = object {.packed.} + status*: uint8 + handle*: uint8 + reason*: uint8 + + const + EVT_DISCONNECT_PHYSICAL_LINK_COMPLETE_SIZE* = 3 + EVT_PHYSICAL_LINK_LOSS_EARLY_WARNING* = 0x00000043 + type + evt_physical_link_loss_warning* = object {.packed.} + handle*: uint8 + reason*: uint8 + + const + EVT_PHYSICAL_LINK_LOSS_WARNING_SIZE* = 2 + EVT_PHYSICAL_LINK_RECOVERY* = 0x00000044 + type + evt_physical_link_recovery* = object {.packed.} + handle*: uint8 + + const + EVT_PHYSICAL_LINK_RECOVERY_SIZE* = 1 + EVT_LOGICAL_LINK_COMPLETE* = 0x00000045 + type + evt_logical_link_complete* = object {.packed.} + status*: uint8 + log_handle*: uint16 + handle*: uint8 + tx_flow_id*: uint8 + + const + EVT_LOGICAL_LINK_COMPLETE_SIZE* = 5 + EVT_DISCONNECT_LOGICAL_LINK_COMPLETE* = 0x00000046 + EVT_FLOW_SPEC_MODIFY_COMPLETE* = 0x00000047 + type + evt_flow_spec_modify_complete* = object {.packed.} + status*: uint8 + handle*: uint16 + + const + EVT_FLOW_SPEC_MODIFY_COMPLETE_SIZE* = 3 + EVT_NUMBER_COMPLETED_BLOCKS* = 0x00000048 + EVT_AMP_STATUS_CHANGE* = 0x0000004D + type + evt_amp_status_change* = object {.packed.} + status*: uint8 + amp_status*: uint8 + + const + EVT_AMP_STATUS_CHANGE_SIZE* = 2 + EVT_TESTING* = 0x000000FE + EVT_VENDOR* = 0x000000FF + # Internal events generated by BlueZ stack + const + EVT_STACK_INTERNAL* = 0x000000FD + type + evt_stack_internal* = object {.packed.} + `type`*: uint16 + data*: array[0, uint8] + + const + EVT_STACK_INTERNAL_SIZE* = 2 + EVT_SI_DEVICE* = 0x00000001 + type + evt_si_device* = object {.packed.} + event*: uint16 + dev_id*: uint16 + + const + EVT_SI_DEVICE_SIZE* = 4 + # -------- HCI Packet structures -------- + const + HCI_TYPE_LEN* = 1 + type + hci_command_hdr* = object {.packed.} + opcode*: uint16 # OCF & OGF + plen*: uint8 + + const + HCI_COMMAND_HDR_SIZE* = 3 + type + hci_event_hdr* = object {.packed.} + evt*: uint8 + plen*: uint8 + + const + HCI_EVENT_HDR_SIZE* = 2 + type + hci_acl_hdr* = object {.packed.} + handle*: uint16 # Handle & Flags(PB, BC) + dlen*: uint16 + + const + HCI_ACL_HDR_SIZE* = 4 + type + hci_sco_hdr* = object {.packed.} + handle*: uint16 + dlen*: uint8 + + const + HCI_SCO_HDR_SIZE* = 3 + type + hci_msg_hdr* = object {.packed.} + device*: uint16 + `type`*: uint16 + plen*: uint16 + + const + HCI_MSG_HDR_SIZE* = 6 + # Command opcode pack/unpack + template cmd_opcode_pack*(ogf, ocf: expr): expr = + (uint16)((ocf and 0x000003FF) or (ogf shl 10)) + + template cmd_opcode_ogf*(op: expr): expr = + (op shr 10) + + template cmd_opcode_ocf*(op: expr): expr = + (op and 0x000003FF) + + # ACL handle and flags pack/unpack + template acl_handle_pack*(h, f: expr): expr = + (uint16)((h and 0x00000FFF) or (f shl 12)) + + template acl_handle*(h: expr): expr = + (h and 0x00000FFF) + + template acl_flags*(h: expr): expr = + (h shr 12) + +# HCI Socket options + +const + HCI_DATA_DIR* = 1 + HCI_FILTER* = 2 + HCI_TIME_STAMP* = 3 + +# HCI CMSG flags + +const + HCI_CMSG_DIR* = 0x00000001 + HCI_CMSG_TSTAMP* = 0x00000002 + +type + sockaddr_hci* = object + hci_family*: cushort + hci_dev*: cushort + hci_channel*: cushort + + +const + HCI_DEV_NONE* = 0x0000FFFF + HCI_CHANNEL_RAW* = 0 + HCI_CHANNEL_MONITOR* = 2 + HCI_CHANNEL_CONTROL* = 3 + +type + hci_filter* = object + type_mask*: uint32 + event_mask*: array[2, uint32] + opcode*: uint16 + + +const + HCI_FLT_TYPE_BITS* = 31 + HCI_FLT_EVENT_BITS* = 63 + HCI_FLT_OGF_BITS* = 63 + HCI_FLT_OCF_BITS* = 127 + +# Ioctl requests structures + +type + hci_dev_stats* = object + err_rx*: uint32 + err_tx*: uint32 + cmd_tx*: uint32 + evt_rx*: uint32 + acl_tx*: uint32 + acl_rx*: uint32 + sco_tx*: uint32 + sco_rx*: uint32 + byte_rx*: uint32 + byte_tx*: uint32 + + hci_dev_info* = object + dev_id*: uint16 + name*: array[8, char] + bdaddr*: bdaddr_t + flags*: uint32 + `type`*: uint8 + features*: array[8, uint8] + pkt_type*: uint32 + link_policy*: uint32 + link_mode*: uint32 + acl_mtu*: uint16 + acl_pkts*: uint16 + sco_mtu*: uint16 + sco_pkts*: uint16 + stat*: hci_dev_stats + + hci_conn_info* = object + handle*: uint16 + bdaddr*: bdaddr_t + `type`*: uint8 + `out`*: uint8 + state*: uint16 + link_mode*: uint32 + + hci_dev_req* = object + dev_id*: uint16 + dev_opt*: uint32 + + hci_dev_list_req* = object + dev_num*: uint16 + # dev_req*: array[0, hci_dev_req] # hci_dev_req structures + dev_req*: array[HCI_MAX_DEV, hci_dev_req] # hci_dev_req structures + + hci_conn_list_req* = object + dev_id*: uint16 + conn_num*: uint16 + conn_info*: array[0, hci_conn_info] + + hci_conn_info_req* = object + bdaddr*: bdaddr_t + `type`*: uint8 + conn_info*: array[0, hci_conn_info] + + hci_auth_info_req* = object + bdaddr*: bdaddr_t + `type`*: uint8 + + hci_inquiry_req* = object + dev_id*: uint16 + flags*: uint16 + lap*: array[3, uint8] + length*: uint8 + num_rsp*: uint8 + + +const + IREQ_CACHE_FLUSH* = 0x00000001 diff --git a/nimbluez/bluez/bz_hci_lib.nim b/nimbluez/bluez/bz_hci_lib.nim new file mode 100644 index 0000000..0d6d8dc --- /dev/null +++ b/nimbluez/bluez/bz_hci_lib.nim @@ -0,0 +1,298 @@ +# +# +# BlueZ - Bluetooth protocol stack for Linux +# +# Copyright (C) 2000-2001 Qualcomm Incorporated +# Copyright (C) 2002-2003 Maxim Krasnyansky <maxk@qualcomm.com> +# Copyright (C) 2002-2010 Marcel Holtmann <marcel@holtmann.org> +# +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +# +# + +{.deadCodeElim: on.} + +import bz_bluetooth +import bz_hci + + +type + hci_request* = object + ogf*: uint16 + ocf*: uint16 + event*: cint + cparam*: pointer + clen*: cint + rparam*: pointer + rlen*: cint + + hci_version* = object + manufacturer*: uint16 + hci_ver*: uint8 + hci_rev*: uint16 + lmp_ver*: uint8 + lmp_subver*: uint16 + + +proc hci_open_dev*(dev_id: cint): cint {.cdecl, importc: "hci_open_dev", + dynlib: "libbluetooth.so".} +proc hci_close_dev*(dd: cint): cint {.cdecl, importc: "hci_close_dev", + dynlib: "libbluetooth.so".} +proc hci_send_cmd*(dd: cint; ogf: uint16; ocf: uint16; plen: uint8; + param: pointer): cint {.cdecl, importc: "hci_send_cmd", + dynlib: "libbluetooth.so".} +proc hci_send_req*(dd: cint; req: ptr hci_request; timeout: cint): cint {.cdecl, + importc: "hci_send_req", dynlib: "libbluetooth.so".} +proc hci_create_connection*(dd: cint; bdaddr: ptr bdaddr_t; ptype: uint16; + clkoffset: uint16; rswitch: uint8; + handle: ptr uint16; to: cint): cint {.cdecl, + importc: "hci_create_connection", dynlib: "libbluetooth.so".} +proc hci_disconnect*(dd: cint; handle: uint16; reason: uint8; to: cint): cint {. + cdecl, importc: "hci_disconnect", dynlib: "libbluetooth.so".} +proc hci_inquiry*(dev_id: cint; len: cint; num_rsp: cint; lap: ptr uint8; + ii: ptr ptr inquiry_info; flags: clong): cint {.cdecl, + importc: "hci_inquiry", dynlib: "libbluetooth.so".} +proc hci_devinfo*(dev_id: cint; di: ptr hci_dev_info): cint {.cdecl, + importc: "hci_devinfo", dynlib: "libbluetooth.so".} +proc hci_devba*(dev_id: cint; bdaddr: ptr bdaddr_t): cint {.cdecl, + importc: "hci_devba", dynlib: "libbluetooth.so".} +proc hci_devid*(str: cstring): cint {.cdecl, importc: "hci_devid", + dynlib: "libbluetooth.so".} +proc hci_read_local_name*(dd: cint; len: cint; name: cstring; to: cint): cint {. + cdecl, importc: "hci_read_local_name", dynlib: "libbluetooth.so".} +proc hci_write_local_name*(dd: cint; name: cstring; to: cint): cint {.cdecl, + importc: "hci_write_local_name", dynlib: "libbluetooth.so".} +proc hci_read_remote_name*(dd: cint; bdaddr: ptr bdaddr_t; len: cint; + name: cstring; to: cint): cint {.cdecl, + importc: "hci_read_remote_name", dynlib: "libbluetooth.so".} +proc hci_read_remote_name_with_clock_offset*(dd: cint; bdaddr: ptr bdaddr_t; + pscan_rep_mode: uint8; clkoffset: uint16; len: cint; name: cstring; + to: cint): cint {.cdecl, importc: "hci_read_remote_name_with_clock_offset", + dynlib: "libbluetooth.so".} +proc hci_read_remote_name_cancel*(dd: cint; bdaddr: ptr bdaddr_t; to: cint): cint {. + cdecl, importc: "hci_read_remote_name_cancel", dynlib: "libbluetooth.so".} +proc hci_read_remote_version*(dd: cint; handle: uint16; ver: ptr hci_version; + to: cint): cint {.cdecl, + importc: "hci_read_remote_version", dynlib: "libbluetooth.so".} +proc hci_read_remote_features*(dd: cint; handle: uint16; + features: ptr uint8; to: cint): cint {.cdecl, + importc: "hci_read_remote_features", dynlib: "libbluetooth.so".} +proc hci_read_remote_ext_features*(dd: cint; handle: uint16; page: uint8; + max_page: ptr uint8; features: ptr uint8; + to: cint): cint {.cdecl, + importc: "hci_read_remote_ext_features", dynlib: "libbluetooth.so".} +proc hci_read_clock_offset*(dd: cint; handle: uint16; clkoffset: ptr uint16; + to: cint): cint {.cdecl, + importc: "hci_read_clock_offset", dynlib: "libbluetooth.so".} +proc hci_read_local_version*(dd: cint; ver: ptr hci_version; to: cint): cint {. + cdecl, importc: "hci_read_local_version", dynlib: "libbluetooth.so".} +proc hci_read_local_commands*(dd: cint; commands: ptr uint8; to: cint): cint {. + cdecl, importc: "hci_read_local_commands", dynlib: "libbluetooth.so".} +proc hci_read_local_features*(dd: cint; features: ptr uint8; to: cint): cint {. + cdecl, importc: "hci_read_local_features", dynlib: "libbluetooth.so".} +proc hci_read_local_ext_features*(dd: cint; page: uint8; + max_page: ptr uint8; features: ptr uint8; + to: cint): cint {.cdecl, + importc: "hci_read_local_ext_features", dynlib: "libbluetooth.so".} +proc hci_read_bd_addr*(dd: cint; bdaddr: ptr bdaddr_t; to: cint): cint {.cdecl, + importc: "hci_read_bd_addr", dynlib: "libbluetooth.so".} +proc hci_read_class_of_dev*(dd: cint; cls: ptr uint8; to: cint): cint {.cdecl, + importc: "hci_read_class_of_dev", dynlib: "libbluetooth.so".} +proc hci_write_class_of_dev*(dd: cint; cls: uint32; to: cint): cint {.cdecl, + importc: "hci_write_class_of_dev", dynlib: "libbluetooth.so".} +proc hci_read_voice_setting*(dd: cint; vs: ptr uint16; to: cint): cint {. + cdecl, importc: "hci_read_voice_setting", dynlib: "libbluetooth.so".} +proc hci_write_voice_setting*(dd: cint; vs: uint16; to: cint): cint {.cdecl, + importc: "hci_write_voice_setting", dynlib: "libbluetooth.so".} +proc hci_read_current_iac_lap*(dd: cint; num_iac: ptr uint8; lap: ptr uint8; + to: cint): cint {.cdecl, + importc: "hci_read_current_iac_lap", dynlib: "libbluetooth.so".} +proc hci_write_current_iac_lap*(dd: cint; num_iac: uint8; lap: ptr uint8; + to: cint): cint {.cdecl, + importc: "hci_write_current_iac_lap", dynlib: "libbluetooth.so".} +proc hci_read_stored_link_key*(dd: cint; bdaddr: ptr bdaddr_t; all: uint8; + to: cint): cint {.cdecl, + importc: "hci_read_stored_link_key", dynlib: "libbluetooth.so".} +proc hci_write_stored_link_key*(dd: cint; bdaddr: ptr bdaddr_t; + key: ptr uint8; to: cint): cint {.cdecl, + importc: "hci_write_stored_link_key", dynlib: "libbluetooth.so".} +proc hci_delete_stored_link_key*(dd: cint; bdaddr: ptr bdaddr_t; all: uint8; + to: cint): cint {.cdecl, + importc: "hci_delete_stored_link_key", dynlib: "libbluetooth.so".} +proc hci_authenticate_link*(dd: cint; handle: uint16; to: cint): cint {.cdecl, + importc: "hci_authenticate_link", dynlib: "libbluetooth.so".} +proc hci_encrypt_link*(dd: cint; handle: uint16; encrypt: uint8; to: cint): cint {. + cdecl, importc: "hci_encrypt_link", dynlib: "libbluetooth.so".} +proc hci_change_link_key*(dd: cint; handle: uint16; to: cint): cint {.cdecl, + importc: "hci_change_link_key", dynlib: "libbluetooth.so".} +proc hci_switch_role*(dd: cint; bdaddr: ptr bdaddr_t; role: uint8; to: cint): cint {. + cdecl, importc: "hci_switch_role", dynlib: "libbluetooth.so".} +proc hci_park_mode*(dd: cint; handle: uint16; max_interval: uint16; + min_interval: uint16; to: cint): cint {.cdecl, + importc: "hci_park_mode", dynlib: "libbluetooth.so".} +proc hci_exit_park_mode*(dd: cint; handle: uint16; to: cint): cint {.cdecl, + importc: "hci_exit_park_mode", dynlib: "libbluetooth.so".} +proc hci_read_inquiry_scan_type*(dd: cint; `type`: ptr uint8; to: cint): cint {. + cdecl, importc: "hci_read_inquiry_scan_type", dynlib: "libbluetooth.so".} +proc hci_write_inquiry_scan_type*(dd: cint; `type`: uint8; to: cint): cint {. + cdecl, importc: "hci_write_inquiry_scan_type", dynlib: "libbluetooth.so".} +proc hci_read_inquiry_mode*(dd: cint; mode: ptr uint8; to: cint): cint {. + cdecl, importc: "hci_read_inquiry_mode", dynlib: "libbluetooth.so".} +proc hci_write_inquiry_mode*(dd: cint; mode: uint8; to: cint): cint {.cdecl, + importc: "hci_write_inquiry_mode", dynlib: "libbluetooth.so".} +proc hci_read_afh_mode*(dd: cint; mode: ptr uint8; to: cint): cint {.cdecl, + importc: "hci_read_afh_mode", dynlib: "libbluetooth.so".} +proc hci_write_afh_mode*(dd: cint; mode: uint8; to: cint): cint {.cdecl, + importc: "hci_write_afh_mode", dynlib: "libbluetooth.so".} +proc hci_read_ext_inquiry_response*(dd: cint; fec: ptr uint8; + data: ptr uint8; to: cint): cint {.cdecl, + importc: "hci_read_ext_inquiry_response", dynlib: "libbluetooth.so".} +proc hci_write_ext_inquiry_response*(dd: cint; fec: uint8; data: ptr uint8; + to: cint): cint {.cdecl, + importc: "hci_write_ext_inquiry_response", dynlib: "libbluetooth.so".} +proc hci_read_simple_pairing_mode*(dd: cint; mode: ptr uint8; to: cint): cint {. + cdecl, importc: "hci_read_simple_pairing_mode", dynlib: "libbluetooth.so".} +proc hci_write_simple_pairing_mode*(dd: cint; mode: uint8; to: cint): cint {. + cdecl, importc: "hci_write_simple_pairing_mode", dynlib: "libbluetooth.so".} +proc hci_read_local_oob_data*(dd: cint; hash: ptr uint8; + randomizer: ptr uint8; to: cint): cint {.cdecl, + importc: "hci_read_local_oob_data", dynlib: "libbluetooth.so".} +proc hci_read_inquiry_transmit_power_level*(dd: cint; level: ptr int8; + to: cint): cint {.cdecl, importc: "hci_read_inquiry_transmit_power_level", + dynlib: "libbluetooth.so".} +proc hci_write_inquiry_transmit_power_level*(dd: cint; level: int8; to: cint): cint {. + cdecl, importc: "hci_write_inquiry_transmit_power_level", + dynlib: "libbluetooth.so".} +proc hci_read_transmit_power_level*(dd: cint; handle: uint16; `type`: uint8; + level: ptr int8; to: cint): cint {.cdecl, + importc: "hci_read_transmit_power_level", dynlib: "libbluetooth.so".} +proc hci_read_link_policy*(dd: cint; handle: uint16; policy: ptr uint16; + to: cint): cint {.cdecl, + importc: "hci_read_link_policy", dynlib: "libbluetooth.so".} +proc hci_write_link_policy*(dd: cint; handle: uint16; policy: uint16; + to: cint): cint {.cdecl, + importc: "hci_write_link_policy", dynlib: "libbluetooth.so".} +proc hci_read_link_supervision_timeout*(dd: cint; handle: uint16; + timeout: ptr uint16; to: cint): cint {. + cdecl, importc: "hci_read_link_supervision_timeout", dynlib: "libbluetooth.so".} +proc hci_write_link_supervision_timeout*(dd: cint; handle: uint16; + timeout: uint16; to: cint): cint {.cdecl, + importc: "hci_write_link_supervision_timeout", dynlib: "libbluetooth.so".} +proc hci_set_afh_classification*(dd: cint; map: ptr uint8; to: cint): cint {. + cdecl, importc: "hci_set_afh_classification", dynlib: "libbluetooth.so".} +proc hci_read_link_quality*(dd: cint; handle: uint16; + link_quality: ptr uint8; to: cint): cint {.cdecl, + importc: "hci_read_link_quality", dynlib: "libbluetooth.so".} +proc hci_read_rssi*(dd: cint; handle: uint16; rssi: ptr int8; to: cint): cint {. + cdecl, importc: "hci_read_rssi", dynlib: "libbluetooth.so".} +proc hci_read_afh_map*(dd: cint; handle: uint16; mode: ptr uint8; + map: ptr uint8; to: cint): cint {.cdecl, + importc: "hci_read_afh_map", dynlib: "libbluetooth.so".} +proc hci_read_clock*(dd: cint; handle: uint16; which: uint8; + clock: ptr uint32; accuracy: ptr uint16; to: cint): cint {. + cdecl, importc: "hci_read_clock", dynlib: "libbluetooth.so".} +proc hci_for_each_dev*(flag: cint; `func`: proc (dd: cint; dev_id: cint; + arg: clong): cint {.cdecl.}; arg: clong): cint {.cdecl, + importc: "hci_for_each_dev", dynlib: "libbluetooth.so".} +proc hci_get_route*(bdaddr: ptr bdaddr_t): cint {.cdecl, + importc: "hci_get_route", dynlib: "libbluetooth.so".} +proc hci_dtypetostr*(`type`: cint): cstring {.cdecl, importc: "hci_dtypetostr", + dynlib: "libbluetooth.so".} +proc hci_dflagstostr*(flags: uint32): cstring {.cdecl, + importc: "hci_dflagstostr", dynlib: "libbluetooth.so".} +proc hci_ptypetostr*(ptype: cuint): cstring {.cdecl, importc: "hci_ptypetostr", + dynlib: "libbluetooth.so".} +proc hci_strtoptype*(str: cstring; val: ptr cuint): cint {.cdecl, + importc: "hci_strtoptype", dynlib: "libbluetooth.so".} +proc hci_scoptypetostr*(ptype: cuint): cstring {.cdecl, + importc: "hci_scoptypetostr", dynlib: "libbluetooth.so".} +proc hci_strtoscoptype*(str: cstring; val: ptr cuint): cint {.cdecl, + importc: "hci_strtoscoptype", dynlib: "libbluetooth.so".} +proc hci_lptostr*(ptype: cuint): cstring {.cdecl, importc: "hci_lptostr", + dynlib: "libbluetooth.so".} +proc hci_strtolp*(str: cstring; val: ptr cuint): cint {.cdecl, + importc: "hci_strtolp", dynlib: "libbluetooth.so".} +proc hci_lmtostr*(ptype: cuint): cstring {.cdecl, importc: "hci_lmtostr", + dynlib: "libbluetooth.so".} +proc hci_strtolm*(str: cstring; val: ptr cuint): cint {.cdecl, + importc: "hci_strtolm", dynlib: "libbluetooth.so".} +proc hci_cmdtostr*(cmd: cuint): cstring {.cdecl, importc: "hci_cmdtostr", + dynlib: "libbluetooth.so".} +proc hci_commandstostr*(commands: ptr uint8; pref: cstring; width: cint): cstring {. + cdecl, importc: "hci_commandstostr", dynlib: "libbluetooth.so".} +proc hci_vertostr*(ver: cuint): cstring {.cdecl, importc: "hci_vertostr", + dynlib: "libbluetooth.so".} +proc hci_strtover*(str: cstring; ver: ptr cuint): cint {.cdecl, + importc: "hci_strtover", dynlib: "libbluetooth.so".} +proc lmp_vertostr*(ver: cuint): cstring {.cdecl, importc: "lmp_vertostr", + dynlib: "libbluetooth.so".} +proc lmp_strtover*(str: cstring; ver: ptr cuint): cint {.cdecl, + importc: "lmp_strtover", dynlib: "libbluetooth.so".} +proc lmp_featurestostr*(features: ptr uint8; pref: cstring; width: cint): cstring {. + cdecl, importc: "lmp_featurestostr", dynlib: "libbluetooth.so".} +proc hci_set_bit*(nr: cint; `addr`: pointer) {.inline, cdecl.} = + cast[ptr uint32](cast[int](`addr`) + (nr shr 5))[] = + uint32(int(cast[ptr uint32](cast[int](`addr`) + (nr shr 5))[]) or (1 shl (nr and 31))) + +proc hci_clear_bit*(nr: cint; `addr`: pointer) {.inline, cdecl.} = + cast[ptr uint32](cast[int](`addr`) + (nr shr 5))[] = + uint32(int(cast[ptr uint32](cast[int](`addr`) + (nr shr 5))[]) and not (1 shl (nr and 31))) + +proc hci_test_bit*(nr: cint; `addr`: pointer): cint {.inline, cdecl.} = + return cint(int(cast[ptr uint32](cast[int](`addr`) + (nr shr 5))[]) and (1 shl (nr and 31))) + +# HCI filter tools + +proc hci_filter_clear*(f: ptr hci_filter) {.inline, cdecl.} = + zeroMem(f, sizeof((f[]))) + +proc hci_filter_set_ptype*(t: cint; f: ptr hci_filter) {.inline, cdecl.} = + hci_set_bit(if (t == HCI_VENDOR_PKT): 0 else: (t and HCI_FLT_TYPE_BITS), + addr(f.type_mask)) + +proc hci_filter_clear_ptype*(t: cint; f: ptr hci_filter) {.inline, cdecl.} = + hci_clear_bit(if (t == HCI_VENDOR_PKT): 0 else: (t and HCI_FLT_TYPE_BITS), + addr(f.type_mask)) + +proc hci_filter_test_ptype*(t: cint; f: ptr hci_filter): cint {.inline, cdecl.} = + return hci_test_bit(if (t == HCI_VENDOR_PKT): 0 else: (t and + HCI_FLT_TYPE_BITS), addr(f.type_mask)) + +proc hci_filter_all_ptypes*(f: ptr hci_filter) {.inline, cdecl.} = + f.type_mask = 0x000000FF + +proc hci_filter_set_event*(e: cint; f: ptr hci_filter) {.inline, cdecl.} = + hci_set_bit((e and HCI_FLT_EVENT_BITS), addr(f.event_mask)) + +proc hci_filter_clear_event*(e: cint; f: ptr hci_filter) {.inline, cdecl.} = + hci_clear_bit((e and HCI_FLT_EVENT_BITS), addr(f.event_mask)) + +proc hci_filter_test_event*(e: cint; f: ptr hci_filter): cint {.inline, cdecl.} = + return hci_test_bit((e and HCI_FLT_EVENT_BITS), addr(f.event_mask)) + +proc hci_filter_all_events*(f: ptr hci_filter) {.inline, cdecl.} = + for i in low(f.event_mask)..high(f.event_mask): + f.event_mask[i] = 0x000000FF + +proc hci_filter_set_opcode*(opcode: uint16; f: ptr hci_filter) {.inline, cdecl.} = + f.opcode = opcode + +proc hci_filter_clear_opcode*(f: ptr hci_filter) {.inline, cdecl.} = + f.opcode = 0 + +proc hci_filter_test_opcode*(opcode: uint16; f: ptr hci_filter): bool {.inline, + cdecl.} = + return int16(f.opcode) == int16(opcode) diff --git a/nimbluez/bluez/bz_l2cap.nim b/nimbluez/bluez/bz_l2cap.nim new file mode 100644 index 0000000..a819b13 --- /dev/null +++ b/nimbluez/bluez/bz_l2cap.nim @@ -0,0 +1,344 @@ +# +# +# BlueZ - Bluetooth protocol stack for Linux +# +# Copyright (C) 2000-2001 Qualcomm Incorporated +# Copyright (C) 2002-2003 Maxim Krasnyansky <maxk@qualcomm.com> +# Copyright (C) 2002-2010 Marcel Holtmann <marcel@holtmann.org> +# Copyright (c) 2012 Code Aurora Forum. All rights reserved. +# +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +# +# + +{.deadCodeElim: on.} + +import bz_bluetooth + +# L2CAP defaults + +const + L2CAP_DEFAULT_MTU* = 672 + L2CAP_DEFAULT_FLUSH_TO* = 0x0000FFFF + +# L2CAP socket address + +type + sockaddr_l2* = object + l2_family*: cushort + l2_psm*: cushort + l2_bdaddr*: bdaddr_t + l2_cid*: cushort + l2_bdaddr_type*: uint8 + + +# L2CAP socket options + +const + L2CAP_OPTIONS* = 0x00000001 + +type + l2cap_options* = object + omtu*: uint16 + imtu*: uint16 + flush_to*: uint16 + mode*: uint8 + fcs*: uint8 + max_tx*: uint8 + txwin_size*: uint16 + + +const + L2CAP_CONNINFO* = 0x00000002 + +type + l2cap_conninfo* = object + hci_handle*: uint16 + dev_class*: array[3, uint8] + + +const + L2CAP_LM* = 0x00000003 + L2CAP_LM_MASTER* = 0x00000001 + L2CAP_LM_AUTH* = 0x00000002 + L2CAP_LM_ENCRYPT* = 0x00000004 + L2CAP_LM_TRUSTED* = 0x00000008 + L2CAP_LM_RELIABLE* = 0x00000010 + L2CAP_LM_SECURE* = 0x00000020 + +# L2CAP command codes + +const + L2CAP_COMMAND_REJ* = 0x00000001 + L2CAP_CONN_REQ* = 0x00000002 + L2CAP_CONN_RSP* = 0x00000003 + L2CAP_CONF_REQ* = 0x00000004 + L2CAP_CONF_RSP* = 0x00000005 + L2CAP_DISCONN_REQ* = 0x00000006 + L2CAP_DISCONN_RSP* = 0x00000007 + L2CAP_ECHO_REQ* = 0x00000008 + L2CAP_ECHO_RSP* = 0x00000009 + L2CAP_INFO_REQ* = 0x0000000A + L2CAP_INFO_RSP* = 0x0000000B + L2CAP_CREATE_REQ* = 0x0000000C + L2CAP_CREATE_RSP* = 0x0000000D + L2CAP_MOVE_REQ* = 0x0000000E + L2CAP_MOVE_RSP* = 0x0000000F + L2CAP_MOVE_CFM* = 0x00000010 + L2CAP_MOVE_CFM_RSP* = 0x00000011 + +# L2CAP extended feature mask + +const + L2CAP_FEAT_FLOWCTL* = 0x00000001 + L2CAP_FEAT_RETRANS* = 0x00000002 + L2CAP_FEAT_BIDIR_QOS* = 0x00000004 + L2CAP_FEAT_ERTM* = 0x00000008 + L2CAP_FEAT_STREAMING* = 0x00000010 + L2CAP_FEAT_FCS* = 0x00000020 + L2CAP_FEAT_EXT_FLOW* = 0x00000040 + L2CAP_FEAT_FIXED_CHAN* = 0x00000080 + L2CAP_FEAT_EXT_WINDOW* = 0x00000100 + L2CAP_FEAT_UCD* = 0x00000200 + +# L2CAP fixed channels + +const + L2CAP_FC_L2CAP* = 0x00000002 + L2CAP_FC_CONNLESS* = 0x00000004 + L2CAP_FC_A2MP* = 0x00000008 + +# L2CAP structures + +type + l2cap_hdr* = object {.packed.} + len*: uint16 + cid*: uint16 + + +const + L2CAP_HDR_SIZE* = 4 + +type + l2cap_cmd_hdr* = object {.packed.} + code*: uint8 + ident*: uint8 + len*: uint16 + + +const + L2CAP_CMD_HDR_SIZE* = 4 + +type + l2cap_cmd_rej* = object {.packed.} + reason*: uint16 + + +const + L2CAP_CMD_REJ_SIZE* = 2 + +type + l2cap_conn_req* = object {.packed.} + psm*: uint16 + scid*: uint16 + + +const + L2CAP_CONN_REQ_SIZE* = 4 + +type + l2cap_conn_rsp* = object {.packed.} + dcid*: uint16 + scid*: uint16 + result*: uint16 + status*: uint16 + + +const + L2CAP_CONN_RSP_SIZE* = 8 + +# connect result + +const + L2CAP_CR_SUCCESS* = 0x00000000 + L2CAP_CR_PEND* = 0x00000001 + L2CAP_CR_BAD_PSM* = 0x00000002 + L2CAP_CR_SEC_BLOCK* = 0x00000003 + L2CAP_CR_NO_MEM* = 0x00000004 + +# connect status + +const + L2CAP_CS_NO_INFO* = 0x00000000 + L2CAP_CS_AUTHEN_PEND* = 0x00000001 + L2CAP_CS_AUTHOR_PEND* = 0x00000002 + +type + l2cap_conf_req* = object {.packed.} + dcid*: uint16 + flags*: uint16 + data*: array[0, uint8] + + +const + L2CAP_CONF_REQ_SIZE* = 4 + +type + l2cap_conf_rsp* = object {.packed.} + scid*: uint16 + flags*: uint16 + result*: uint16 + data*: array[0, uint8] + + +const + L2CAP_CONF_RSP_SIZE* = 6 + L2CAP_CONF_SUCCESS* = 0x00000000 + L2CAP_CONF_UNACCEPT* = 0x00000001 + L2CAP_CONF_REJECT* = 0x00000002 + L2CAP_CONF_UNKNOWN* = 0x00000003 + L2CAP_CONF_PENDING* = 0x00000004 + L2CAP_CONF_EFS_REJECT* = 0x00000005 + +type + l2cap_conf_opt* = object {.packed.} + `type`*: uint8 + len*: uint8 + val*: array[0, uint8] + + +const + L2CAP_CONF_OPT_SIZE* = 2 + L2CAP_CONF_MTU* = 0x00000001 + L2CAP_CONF_FLUSH_TO* = 0x00000002 + L2CAP_CONF_QOS* = 0x00000003 + L2CAP_CONF_RFC* = 0x00000004 + L2CAP_CONF_FCS* = 0x00000005 + L2CAP_CONF_EFS* = 0x00000006 + L2CAP_CONF_EWS* = 0x00000007 + L2CAP_CONF_MAX_SIZE* = 22 + L2CAP_MODE_BASIC* = 0x00000000 + L2CAP_MODE_RETRANS* = 0x00000001 + L2CAP_MODE_FLOWCTL* = 0x00000002 + L2CAP_MODE_ERTM* = 0x00000003 + L2CAP_MODE_STREAMING* = 0x00000004 + L2CAP_SERVTYPE_NOTRAFFIC* = 0x00000000 + L2CAP_SERVTYPE_BESTEFFORT* = 0x00000001 + L2CAP_SERVTYPE_GUARANTEED* = 0x00000002 + +type + l2cap_disconn_req* = object {.packed.} + dcid*: uint16 + scid*: uint16 + + +const + L2CAP_DISCONN_REQ_SIZE* = 4 + +type + l2cap_disconn_rsp* = object {.packed.} + dcid*: uint16 + scid*: uint16 + + +const + L2CAP_DISCONN_RSP_SIZE* = 4 + +type + l2cap_info_req* = object {.packed.} + `type`*: uint16 + + +const + L2CAP_INFO_REQ_SIZE* = 2 + +type + l2cap_info_rsp* = object {.packed.} + `type`*: uint16 + result*: uint16 + data*: array[0, uint8] + + +const + L2CAP_INFO_RSP_SIZE* = 4 + +# info type + +const + L2CAP_IT_CL_MTU* = 0x00000001 + L2CAP_IT_FEAT_MASK* = 0x00000002 + +# info result + +const + L2CAP_IR_SUCCESS* = 0x00000000 + L2CAP_IR_NOTSUPP* = 0x00000001 + +type + l2cap_create_req* = object {.packed.} + psm*: uint16 + scid*: uint16 + id*: uint8 + + +const + L2CAP_CREATE_REQ_SIZE* = 5 + +type + l2cap_create_rsp* = object {.packed.} + dcid*: uint16 + scid*: uint16 + result*: uint16 + status*: uint16 + + +const + L2CAP_CREATE_RSP_SIZE* = 8 + +type + l2cap_move_req* = object {.packed.} + icid*: uint16 + id*: uint8 + + +const + L2CAP_MOVE_REQ_SIZE* = 3 + +type + l2cap_move_rsp* = object {.packed.} + icid*: uint16 + result*: uint16 + + +const + L2CAP_MOVE_RSP_SIZE* = 4 + +type + l2cap_move_cfm* = object {.packed.} + icid*: uint16 + result*: uint16 + + +const + L2CAP_MOVE_CFM_SIZE* = 4 + +type + l2cap_move_cfm_rsp* = object {.packed.} + icid*: uint16 + + +const + L2CAP_MOVE_CFM_RSP_SIZE* = 2 diff --git a/nimbluez/bluez/bz_rfcomm.nim b/nimbluez/bluez/bz_rfcomm.nim new file mode 100644 index 0000000..38984ba --- /dev/null +++ b/nimbluez/bluez/bz_rfcomm.nim @@ -0,0 +1,100 @@ +# +# +# BlueZ - Bluetooth protocol stack for Linux +# +# Copyright (C) 2002-2003 Maxim Krasnyansky <maxk@qualcomm.com> +# Copyright (C) 2002-2010 Marcel Holtmann <marcel@holtmann.org> +# +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +# +# + +{.deadCodeElim: on.} + +import ioctl, bz_bluetooth + +# RFCOMM defaults + +const + RFCOMM_DEFAULT_MTU* = 127 + RFCOMM_PSM* = 3 + +# RFCOMM socket address + +type + sockaddr_rc* = object + rc_family*: uint16 + rc_bdaddr*: bdaddr_t + rc_channel*: uint8 + + +# RFCOMM socket options + +const + RFCOMM_CONNINFO* = 0x00000002 + +type + rfcomm_conninfo* = object + hci_handle*: uint16 + dev_class*: array[3, uint8] + + +const + RFCOMM_LM* = 0x00000003 + RFCOMM_LM_MASTER* = 0x00000001 + RFCOMM_LM_AUTH* = 0x00000002 + RFCOMM_LM_ENCRYPT* = 0x00000004 + RFCOMM_LM_TRUSTED* = 0x00000008 + RFCOMM_LM_RELIABLE* = 0x00000010 + RFCOMM_LM_SECURE* = 0x00000020 + +# RFCOMM TTY support + +const + RFCOMM_MAX_DEV* = 256 + RFCOMMCREATEDEV* = IOW(ord('R'), 200, int) + RFCOMMRELEASEDEV* = IOW(ord('R'), 201, int) + RFCOMMGETDEVLIST* = IOR(ord('R'), 210, int) + RFCOMMGETDEVINFO* = IOR(ord('R'), 211, int) + +type + rfcomm_dev_req* = object + dev_id*: int16 + flags*: uint32 + src*: bdaddr_t + dst*: bdaddr_t + channel*: uint8 + + +const + RFCOMM_REUSE_DLC* = 0 + RFCOMM_RELEASE_ONHUP* = 1 + RFCOMM_HANGUP_NOW* = 2 + RFCOMM_TTY_ATTACHED* = 3 + +type + rfcomm_dev_info* = object + id*: int16 + flags*: uint32 + state*: uint16 + src*: bdaddr_t + dst*: bdaddr_t + channel*: uint8 + + rfcomm_dev_list_req* = object + dev_num*: uint16 + dev_info*: array[0, rfcomm_dev_info] + diff --git a/nimbluez/bluez/ioctl.nim b/nimbluez/bluez/ioctl.nim new file mode 100644 index 0000000..dc57ae6 --- /dev/null +++ b/nimbluez/bluez/ioctl.nim @@ -0,0 +1,110 @@ +# ioctl command encoding: 32 bits total, command in lower 16 bits, +# size of the parameter structure in the lower 14 bits of the +# upper 16 bits. +# Encoding the size of the parameter structure in the ioctl request +# is useful for catching programs compiled with old versions +# and to avoid overwriting user space outside the user buffer area. +# The highest 2 bits are reserved for indicating the ``access mode''. +# NOTE: This limits the max parameter size to 16kB -1 ! +# +# +# The following is for compatibility across the various Linux +# platforms. The generic ioctl numbering scheme doesn't really enforce +# a type field. De facto, however, the top 8 bits of the lower 16 +# bits are indeed used as a type field, so we might just as well make +# this explicit here. Please be sure to use the decoding macros +# below from now on. +# + +{.deadCodeElim: on.} + +const + IOC_NRBITS* = 8 + IOC_TYPEBITS* = 8 + +# +# Let any architecture override either of the following before +# including this file. +# + +const + IOC_SIZEBITS* = 14 + IOC_DIRBITS* = 2 + +const + IOC_NRMASK* = ((1 shl IOC_NRBITS) - 1) + IOC_TYPEMASK* = ((1 shl IOC_TYPEBITS) - 1) + IOC_SIZEMASK* = ((1 shl IOC_SIZEBITS) - 1) + IOC_DIRMASK* = ((1 shl IOC_DIRBITS) - 1) + IOC_NRSHIFT* = 0 + IOC_TYPESHIFT* = (IOC_NRSHIFT + IOC_NRBITS) + IOC_SIZESHIFT* = (IOC_TYPESHIFT + IOC_TYPEBITS) + IOC_DIRSHIFT* = (IOC_SIZESHIFT + IOC_SIZEBITS) + +# +# Direction bits, which any architecture can choose to override +# before including this file. +# + +const + IOC_NONE* = 0 + IOC_WRITE* = 1 + IOC_READ* = 2 + +template IOC_TYPECHECK*(t: expr): expr = + (sizeof((t))) + +# used to create numbers + +template IO*(`type`, nr: expr): expr = + (((IOC_NONE) shl IOC_DIRSHIFT) or (((`type`)) shl IOC_TYPESHIFT) or + (((nr)) shl IOC_NRSHIFT) or ((0) shl IOC_SIZESHIFT)) + +template IOR*(`type`, nr, size: expr): expr = + (((IOC_READ) shl IOC_DIRSHIFT) or (((`type`)) shl IOC_TYPESHIFT) or + (((nr)) shl IOC_NRSHIFT) or (((IOC_TYPECHECK(size))) shl IOC_SIZESHIFT)) + +template IOW*(`type`, nr, size: expr): expr = + (((IOC_WRITE) shl IOC_DIRSHIFT) or (((`type`)) shl IOC_TYPESHIFT) or + (((nr)) shl IOC_NRSHIFT) or (((IOC_TYPECHECK(size))) shl IOC_SIZESHIFT)) + +template IOWR*(`type`, nr, size: expr): expr = + (((IOC_READ or IOC_WRITE) shl IOC_DIRSHIFT) or + (((`type`)) shl IOC_TYPESHIFT) or (((nr)) shl IOC_NRSHIFT) or + (((IOC_TYPECHECK(size))) shl IOC_SIZESHIFT)) + +template IOR_BAD*(`type`, nr, size: expr): expr = + (((IOC_READ) shl IOC_DIRSHIFT) or (((`type`)) shl IOC_TYPESHIFT) or + (((nr)) shl IOC_NRSHIFT) or ((sizeof((size))) shl IOC_SIZESHIFT)) + +template IOW_BAD*(`type`, nr, size: expr): expr = + (((IOC_WRITE) shl IOC_DIRSHIFT) or (((`type`)) shl IOC_TYPESHIFT) or + (((nr)) shl IOC_NRSHIFT) or ((sizeof((size))) shl IOC_SIZESHIFT)) + +template IOWR_BAD*(`type`, nr, size: expr): expr = + (((IOC_READ or IOC_WRITE) shl IOC_DIRSHIFT) or + (((`type`)) shl IOC_TYPESHIFT) or (((nr)) shl IOC_NRSHIFT) or + ((sizeof((size))) shl IOC_SIZESHIFT)) + +# used to decode ioctl numbers.. + +template IOC_DIR*(nr: expr): expr = + (((nr) shr IOC_DIRSHIFT) and IOC_DIRMASK) + +template IOC_TYPE*(nr: expr): expr = + (((nr) shr IOC_TYPESHIFT) and IOC_TYPEMASK) + +template IOC_NR*(nr: expr): expr = + (((nr) shr IOC_NRSHIFT) and IOC_NRMASK) + +template IOC_SIZE*(nr: expr): expr = + (((nr) shr IOC_SIZESHIFT) and IOC_SIZEMASK) + +# ...and for the drivers/sound files... + +const + IOC_IN* = (IOC_WRITE shl IOC_DIRSHIFT) + IOC_OUT* = (IOC_READ shl IOC_DIRSHIFT) + IOC_INOUT* = ((IOC_WRITE or IOC_READ) shl IOC_DIRSHIFT) + IOCSIZE_MASK_S* = (IOC_SIZEMASK shl IOC_SIZESHIFT) + IOCSIZE_SHIFT_S* = (IOC_SIZESHIFT) diff --git a/nimbluez/msbt/ms_bluetoothapis.nim b/nimbluez/msbt/ms_bluetoothapis.nim new file mode 100644 index 0000000..c895128 --- /dev/null +++ b/nimbluez/msbt/ms_bluetoothapis.nim @@ -0,0 +1,1653 @@ +# +# Copyright 2002 - 2004, Microsoft Corporation +# +#//////////////////////////////////////////////////////////////////////////// + +{.deadCodeElim: on.} +when not defined(windows): + {.error: "MSBT is supported by windows".} + + +const + libbluetooth* = "bthprops.cpl" + +import winlean +import ms_bthdef, ms_bthsdpdef + +const + BTH_MAX_PIN_SIZE = 16 + +const + BLUETOOTH_MAX_NAME_SIZE* = (248) + BLUETOOTH_MAX_PASSKEY_SIZE* = (16) + BLUETOOTH_MAX_PASSKEY_BUFFER_SIZE* = (BLUETOOTH_MAX_PASSKEY_SIZE + 1) + BLUETOOTH_MAX_SERVICE_NAME_SIZE* = (256) + BLUETOOTH_DEVICE_NAME_SIZE* = (256) + +# *************************************************************************** +# +# Bluetooth Address +# +# *************************************************************************** +type + INNER_C_UNION_1866013399* = object {.union.} + ullLong*: BTH_ADDR # easier to compare again BLUETOOTH_NULL_ADDRESS + rgBytes*: array[6, BYTE] # easier to format when broken out + BLUETOOTH_ADDRESS_STRUCT* = object + ano_116103095*: INNER_C_UNION_1866013399 + BLUETOOTH_ADDRESS* = BLUETOOTH_ADDRESS_STRUCT + +const + BLUETOOTH_NULL_ADDRESS* = 0x0'i64 +type + BLUETOOTH_LOCAL_SERVICE_INFO_STRUCT* = object + Enabled*: BOOL # If TRUE, the enable the services + btAddr*: BLUETOOTH_ADDRESS # If service is to be advertised for a particular remote device + szName*: array[BLUETOOTH_MAX_SERVICE_NAME_SIZE, WCHAR] # SDP Service Name to be advertised. + szDeviceString*: array[BLUETOOTH_DEVICE_NAME_SIZE, WCHAR] # Local device name (if any) like COM4 or LPT1 + BLUETOOTH_LOCAL_SERVICE_INFO* = BLUETOOTH_LOCAL_SERVICE_INFO_STRUCT + PBLUETOOTH_LOCAL_SERVICE_INFO* = ptr BLUETOOTH_LOCAL_SERVICE_INFO +# *************************************************************************** +# +# Radio Enumeration +# +# Description: +# This group of APIs enumerates the installed Bluetooth radios. +# +# Sample Usage: +# HANDLE hRadio; +# BLUETOOTH_FIND_RADIO_PARAMS btfrp = { sizeof(btfrp) }; +# +# HBLUETOOTH_RADIO_FIND hFind = BluetoothFindFirstRadio( &btfrp, &hRadio ); +# if ( NULL != hFind ) +# { +# do +# { +# // +# // TODO: Do something with the radio handle. +# // +# +# CloseHandle( hRadio ); +# +# } while( BluetoothFindNextRadio( hFind, &hRadio ) ); +# +# BluetoothFindRadioClose( hFind ); +# } +# +# *************************************************************************** +type + BLUETOOTH_FIND_RADIO_PARAMS* = object + dwSize*: DWORD # IN sizeof this structure + + HBLUETOOTH_RADIO_FIND* = HANDLE +# +# Description: +# Begins the enumeration of local Bluetooth radios. +# +# Parameters: +# pbtfrp +# A pointer to a BLUETOOTH_FIND_RADIO_PARAMS structure. The dwSize +# member of this structure must match the sizeof the of the structure. +# +# phRadio +# A pointer where the first radio HANDLE enumerated will be returned. +# +# Return Values: +# NULL +# Error opening radios or no devices found. Use GetLastError() for +# more info. +# +# ERROR_INVALID_PARAMETER +# pbtfrp parameter is NULL. +# +# ERROR_REVISION_MISMATCH +# The pbtfrp structure is not the right length. +# +# ERROR_OUTOFMEMORY +# Out of memory. +# +# other Win32 errors. +# +# any other +# Success. The return handle is valid and phRadio points to a valid handle. +# +proc BluetoothFindFirstRadio*(pbtfrp: ptr BLUETOOTH_FIND_RADIO_PARAMS; + phRadio: ptr HANDLE): HBLUETOOTH_RADIO_FIND {. + stdcall, importc: "BluetoothFindFirstRadio", dynlib: libbluetooth.} +# +# Description: +# Finds the next installed Bluetooth radio. +# +# Parameters: +# hFind +# The handle returned by BluetoothFindFirstRadio(). +# +# phRadio +# A pointer where the next radio HANDLE enumerated will be returned. +# +# Return Values: +# TRUE +# Next device succesfully found. pHandleOut points to valid handle. +# +# FALSE +# No device found. pHandleOut points to an invalid handle. Call +# GetLastError() for more details. +# +# ERROR_INVALID_HANDLE +# The handle is NULL. +# +# ERROR_NO_MORE_ITEMS +# No more radios found. +# +# ERROR_OUTOFMEMORY +# Out of memory. +# +# other Win32 errors +# +proc BluetoothFindNextRadio*(hFind: HBLUETOOTH_RADIO_FIND; + phRadio: ptr HANDLE): BOOL {.stdcall, + importc: "BluetoothFindNextRadio", dynlib: libbluetooth.} +# +# Description: +# Closes the enumeration handle. +# +# Parameters +# hFind +# The handle returned by BluetoothFindFirstRadio(). +# +# Return Values: +# TRUE +# Handle succesfully closed. +# +# FALSE +# Failure. Check GetLastError() for details. +# +# ERROR_INVALID_HANDLE +# The handle is NULL. +# +proc BluetoothFindRadioClose*(hFind: HBLUETOOTH_RADIO_FIND): BOOL {.stdcall, + importc: "BluetoothFindRadioClose", dynlib: libbluetooth.} +# *************************************************************************** +# +# Radio Information +# +# *************************************************************************** +type + BLUETOOTH_RADIO_INFO* = object + dwSize*: DWORD # Size, in bytes, of this entire data structure + address*: BLUETOOTH_ADDRESS # Address of the local radio + szName*: array[BLUETOOTH_MAX_NAME_SIZE, WCHAR] # Name of the local radio + ulClassofDevice*: ULONG # Class of device for the local radio + lmpSubversion*: USHORT # lmpSubversion, manufacturer specifc. + manufacturer*: USHORT # Manufacturer of the radio, BTH_MFG_Xxx value. For the most up to date + # list, goto the Bluetooth specification website and get the Bluetooth + # assigned numbers document. + + PBLUETOOTH_RADIO_INFO* = ptr BLUETOOTH_RADIO_INFO +# +# Description: +# Retrieves the information about the radio represented by the handle. +# +# Parameters: +# hRadio +# Handle to a local radio retrieved through BluetoothFindFirstRadio() +# et al or SetupDiEnumerateDeviceInterfaces() +# +# pRadioInfo +# Radio information to be filled in. The dwSize member must match the +# size of the structure. +# +# Return Values: +# ERROR_SUCCESS +# The information was retrieved successfully. +# +# ERROR_INVALID_PARAMETER +# pRadioInfo or hRadio is NULL. +# +# ERROR_REVISION_MISMATCH +# pRadioInfo->dwSize is invalid. +# +# other Win32 error codes. +# +proc BluetoothGetRadioInfo*(hRadio: HANDLE; + pRadioInfo: PBLUETOOTH_RADIO_INFO): DWORD {. + stdcall, importc: "BluetoothGetRadioInfo", dynlib: libbluetooth.} +# *************************************************************************** +# +# Device Information Stuctures +# +# *************************************************************************** +type + BLUETOOTH_DEVICE_INFO_STRUCT* = object + dwSize*: DWORD # size, in bytes, of this structure - must be the sizeof(BLUETOOTH_DEVICE_INFO) + Address*: BLUETOOTH_ADDRESS # Bluetooth address + ulClassofDevice*: ULONG # Bluetooth "Class of Device" + fConnected*: BOOL # Device connected/in use + fRemembered*: BOOL # Device remembered + fAuthenticated*: BOOL # Device authenticated/paired/bonded + stLastSeen*: SYSTEMTIME # Last time the device was seen + stLastUsed*: SYSTEMTIME # Last time the device was used for other than RNR, inquiry, or SDP + szName*: array[BLUETOOTH_MAX_NAME_SIZE, WCHAR] # Name of the device + + BLUETOOTH_DEVICE_INFO* = BLUETOOTH_DEVICE_INFO_STRUCT + PBLUETOOTH_DEVICE_INFO* = ptr BLUETOOTH_DEVICE_INFO +# +# Support added after KB942567 +# +type + INNER_C_UNION_2689769052* = object {.union.} + Numeric_Value*: ULONG + Passkey*: ULONG + +type + BLUETOOTH_AUTHENTICATION_METHOD* {.size: sizeof(cint).} = enum + BLUETOOTH_AUTHENTICATION_METHOD_LEGACY = 0x00000001, + BLUETOOTH_AUTHENTICATION_METHOD_OOB, + BLUETOOTH_AUTHENTICATION_METHOD_NUMERIC_COMPARISON, + BLUETOOTH_AUTHENTICATION_METHOD_PASSKEY_NOTIFICATION, + BLUETOOTH_AUTHENTICATION_METHOD_PASSKEY + PBLUETOOTH_AUTHENTICATION_METHOD* = ptr BLUETOOTH_AUTHENTICATION_METHOD + BLUETOOTH_IO_CAPABILITY* {.size: sizeof(cint).} = enum + BLUETOOTH_IO_CAPABILITY_DISPLAYONLY = 0x00000000, + BLUETOOTH_IO_CAPABILITY_DISPLAYYESNO = 0x00000001, + BLUETOOTH_IO_CAPABILITY_KEYBOARDONLY = 0x00000002, + BLUETOOTH_IO_CAPABILITY_NOINPUTNOOUTPUT = 0x00000003, + BLUETOOTH_IO_CAPABILITY_UNDEFINED = 0x000000FF + BLUETOOTH_AUTHENTICATION_REQUIREMENTS* {.size: sizeof(cint).} = enum + BLUETOOTH_MITM_ProtectionNotRequired = 0, + BLUETOOTH_MITM_ProtectionRequired = 0x00000001, + BLUETOOTH_MITM_ProtectionNotRequiredBonding = 0x00000002, + BLUETOOTH_MITM_ProtectionRequiredBonding = 0x00000003, + BLUETOOTH_MITM_ProtectionNotRequiredGeneralBonding = 0x00000004, + BLUETOOTH_MITM_ProtectionRequiredGeneralBonding = 0x00000005, + BLUETOOTH_MITM_ProtectionNotDefined = 0x000000FF + BLUETOOTH_AUTHENTICATION_CALLBACK_PARAMS* = object + deviceInfo*: BLUETOOTH_DEVICE_INFO + authenticationMethod*: BLUETOOTH_AUTHENTICATION_METHOD + ioCapability*: BLUETOOTH_IO_CAPABILITY + authenticationRequirements*: BLUETOOTH_AUTHENTICATION_REQUIREMENTS + ano_869376366*: INNER_C_UNION_2689769052 + + PBLUETOOTH_AUTHENTICATION_CALLBACK_PARAMS* = ptr BLUETOOTH_AUTHENTICATION_CALLBACK_PARAMS +# *************************************************************************** +# +# Device Enumeration +# +# Description: +# Enumerates the Bluetooth devices. The types of returned device depends +# on the flags set in the BLUETOOTH_DEVICE_SEARCH_PARAMS (see structure +# definition for details). +# +# Sample Usage: +# HBLUETOOTH_DEVICE_FIND hFind; +# BLUETOOTH_DEVICE_SEARCH_PARAMS btsp = { sizeof(btsp) }; +# BLUETOOTH_DEVICE_INFO btdi = { sizeof(btdi) }; +# +# btsp.fReturnAuthenticated = TRUE; +# btsp.fReturnRemembered = TRUE; +# +# hFind = BluetoothFindFirstDevice( &btsp, &btdi ); +# if ( NULL != hFind ) +# { +# do +# { +# // +# // TODO: Do something useful with the device info. +# // +# +# } while( BluetoothFindNextDevice( hFind, &btdi ) ); +# +# BluetoothFindDeviceClose( hFind ); +# } +# +# *************************************************************************** +type + BLUETOOTH_DEVICE_SEARCH_PARAMS* = object + dwSize*: DWORD # IN sizeof this structure + fReturnAuthenticated*: BOOL # IN return authenticated devices + fReturnRemembered*: BOOL # IN return remembered devices + fReturnUnknown*: BOOL # IN return unknown devices + fReturnConnected*: BOOL # IN return connected devices + fIssueInquiry*: BOOL # IN issue a new inquiry + cTimeoutMultiplier*: UCHAR # IN timeout for the inquiry + hRadio*: HANDLE # IN handle to radio to enumerate - NULL == all radios will be searched + + HBLUETOOTH_DEVICE_FIND* = HANDLE +# +# Description: +# Begins the enumeration of Bluetooth devices. +# +# Parameters: +# pbtsp +# A pointer to a BLUETOOTH_DEVICE_SEARCH_PARAMS structure. This +# structure contains the flags and inputs used to conduct the search. +# See BLUETOOTH_DEVICE_SEARCH_PARAMS for details. +# +# pbtdi +# A pointer to a BLUETOOTH_DEVICE_INFO structure to return information +# about the first Bluetooth device found. Note that the dwSize member +# of the structure must be the sizeof(BLUETOOTH_DEVICE_INFO) before +# calling because the APIs hast to know the size of the buffer being +# past in. The dwSize member must also match the exact +# sizeof(BLUETOOTH_DEVICE_INFO) or the call will fail. +# +# Return Values: +# NULL +# Error opening radios or not devices found. Use GetLastError for more info. +# +# ERROR_INVALID_PARAMETER +# pbtsp parameter or pbtdi parameter is NULL. +# +# ERROR_REVISION_MISMATCH +# The pbtfrp structure is not the right length. +# +# other Win32 errors +# +# any other value +# Success. The return handle is valid and pbtdi points to valid data. +# +proc BluetoothFindFirstDevice*(pbtsp: ptr BLUETOOTH_DEVICE_SEARCH_PARAMS; + pbtdi: ptr BLUETOOTH_DEVICE_INFO): HBLUETOOTH_DEVICE_FIND {. + stdcall, importc: "BluetoothFindFirstDevice", dynlib: libbluetooth.} +# +# Description: +# Finds the next Bluetooth device in the enumeration. +# +# Parameters: +# hFind +# The handle returned from BluetoothFindFirstDevice(). +# +# pbtdi +# A pointer to a BLUETOOTH_DEVICE_INFO structure to return information +# about the first Bluetooth device found. Note that the dwSize member +# of the structure must be the sizeof(BLUETOOTH_DEVICE_INFO) before +# calling because the APIs hast to know the size of the buffer being +# past in. The dwSize member must also match the exact +# sizeof(BLUETOOTH_DEVICE_INFO) or the call will fail. +# +# Return Values: +# TRUE +# Next device succesfully found. pHandleOut points to valid handle. +# +# FALSE +# No device found. pHandleOut points to an invalid handle. Call +# GetLastError() for more details. +# +# ERROR_INVALID_HANDLE +# The handle is NULL. +# +# ERROR_NO_MORE_ITEMS +# No more radios found. +# +# ERROR_OUTOFMEMORY +# Out of memory. +# +# other Win32 errors +# +proc BluetoothFindNextDevice*(hFind: HBLUETOOTH_DEVICE_FIND; + pbtdi: ptr BLUETOOTH_DEVICE_INFO): BOOL {. + stdcall, importc: "BluetoothFindNextDevice", dynlib: libbluetooth.} +# +# Description: +# Closes the enumeration handle. +# +# Parameters: +# hFind +# The handle returned from BluetoothFindFirstDevice(). +# +# Return Values: +# TRUE +# Handle succesfully closed. +# +# FALSE +# Failure. Check GetLastError() for details. +# +# ERROR_INVALID_HANDLE +# The handle is NULL. +# +proc BluetoothFindDeviceClose*(hFind: HBLUETOOTH_DEVICE_FIND): BOOL {. + stdcall, importc: "BluetoothFindDeviceClose", dynlib: libbluetooth.} +# +# Description: +# Retrieves information about a remote device. +# +# Fill in the dwSize and the Address members of the pbtdi structure +# being passed in. On success, the rest of the members will be filled +# out with the information that the system knows. +# +# Parameters: +# hRadio +# Handle to a local radio retrieved through BluetoothFindFirstRadio() +# et al or SetupDiEnumerateDeviceInterfaces() +# +# pbtdi +# A pointer to a BLUETOOTH_DEVICE_INFO structure to return information +# about the first Bluetooth device found. The dwSize member of the +# structure must be the sizeof the structure in bytes. The Address +# member must be filled out with the Bluetooth address of the remote +# device. +# +# Return Values: +# ERROR_SUCCESS +# Success. Information returned. +# +# ERROR_REVISION_MISMATCH +# The size of the BLUETOOTH_DEVICE_INFO isn't compatible. Check +# the dwSize member of the BLUETOOTH_DEVICE_INFO structure you +# passed in. +# +# ERROR_NOT_FOUND +# The radio is not known by the system or the Address field of +# the BLUETOOTH_DEVICE_INFO structure is all zeros. +# +# ERROR_INVALID_PARAMETER +# pbtdi is NULL. +# +# other error codes +# +proc BluetoothGetDeviceInfo*(hRadio: HANDLE; + pbtdi: ptr BLUETOOTH_DEVICE_INFO): DWORD {. + stdcall, importc: "BluetoothGetDeviceInfo", dynlib: libbluetooth.} +# +# Description: +# Updates the computer local cache about the device. +# +# Parameters: +# pbtdi +# A pointer to the BLUETOOTH_DEVICE_INFO structure to be updated. +# The following members must be valid: +# dwSize +# Must match the size of the structure. +# Address +# Must be a previously found radio address. +# szName +# New name to be stored. +# +# Return Values: +# ERROR_SUCCESS +# The device information was updated successfully. +# +# ERROR_INVALID_PARAMETER +# pbtdi is NULL. +# +# ERROR_REVISION_MISMATCH +# pbtdi->dwSize is invalid. +# +# other Win32 error codes. +# +proc BluetoothUpdateDeviceRecord*(pbtdi: ptr BLUETOOTH_DEVICE_INFO): DWORD {. + stdcall, importc: "BluetoothUpdateDeviceRecord", dynlib: libbluetooth.} +# +# Description: +# Delete the authentication (aka "bond") between the computer and the +# device. Also purges any cached information about the device. +# +# Return Values: +# ERROR_SUCCESS +# The device was removed successfully. +# +# ERROR_NOT_FOUND +# The device was not found. If no Bluetooth radio is installed, +# the devices could not be enumerated or removed. +# +proc BluetoothRemoveDevice*(pAddress: ptr BLUETOOTH_ADDRESS): DWORD {. + stdcall, importc: "BluetoothRemoveDevice", dynlib: libbluetooth.} +when not (hostCPU == "arm"): + # + # *************************************************************************** + # + # Device Picker Dialog + # + # Description: + # Invokes a common dialog for selecting Bluetooth devices. The list + # of devices displayed to the user is determined by the flags and + # settings the caller specifies in the BLUETOOTH_SELECT_DEVICE_PARAMS + # (see structure definition for more details). + # + # If BluetoothSelectDevices() returns TRUE, the caller must call + # BluetoothSelectDevicesFree() or memory will be leaked within the + # process. + # + # Sample Usage: + # + # BLUETOOTH_SELECT_DEVICE_PARAMS btsdp = { sizeof(btsdp) }; + # + # btsdp.hwndParent = hDlg; + # btsdp.fShowUnknown = TRUE; + # btsdp.fAddNewDeviceWizard = TRUE; + # + # BOOL b = BluetoothSelectDevices( &btsdp ); + # if ( b ) + # { + # BLUETOOTH_DEVICE_INFO * pbtdi = btsdp.pDevices; + # for ( ULONG cDevice = 0; cDevice < btsdp.cNumDevices; cDevice ++ ) + # { + # if ( pbtdi->fAuthenticated || pbtdi->fRemembered ) + # { + # // + # // TODO: Do something usefull with the device info + # // + # } + # + # pbtdi = (BLUETOOTH_DEVICE_INFO *) ((LPBYTE)pbtdi + pbtdi->dwSize); + # } + # + # BluetoothSelectDevicesFree( &btsdp ); + # } + # + # + # *************************************************************************** + type + BLUETOOTH_COD_PAIRS* = object + ulCODMask*: ULONG # ClassOfDevice mask to compare + pcszDescription*: LPCWSTR # Descriptive string of mask + + PFN_DEVICE_CALLBACK* = proc (pvParam: LPVOID; + pDevice: ptr BLUETOOTH_DEVICE_INFO): BOOL {. + stdcall.} + BLUETOOTH_SELECT_DEVICE_PARAMS* = object + dwSize*: DWORD # IN sizeof this structure + cNumOfClasses*: ULONG # IN Number in prgClassOfDevice - if ZERO search for all devices + prgClassOfDevices*: ptr BLUETOOTH_COD_PAIRS # IN Array of CODs to find. + pszInfo*: LPWSTR # IN If not NULL, sets the "information" text + hwndParent*: HWND # IN parent window - NULL == no parent + fForceAuthentication*: BOOL # IN If TRUE, authenication will be forced before returning + fShowAuthenticated*: BOOL # IN If TRUE, authenticated devices will be shown in the picker + fShowRemembered*: BOOL # IN If TRUE, remembered devices will be shown in the picker + fShowUnknown*: BOOL # IN If TRUE, unknown devices that are not authenticated or "remember" will be shown. + fAddNewDeviceWizard*: BOOL # IN If TRUE, invokes the add new device wizard. + fSkipServicesPage*: BOOL # IN If TRUE, skips the "Services" page in the wizard. + pfnDeviceCallback*: PFN_DEVICE_CALLBACK # IN If non-NULL, a callback that will be called for each device. If the + # the callback returns TRUE, the item will be added. If the callback is + # is FALSE, the item will not be shown. + pvParam*: LPVOID # IN Parameter to be passed to pfnDeviceCallback as the pvParam. + cNumDevices*: DWORD # IN number calles wants - ZERO == no limit. + # OUT the number of devices returned. + pDevices*: PBLUETOOTH_DEVICE_INFO # OUT pointer to an array for BLUETOOTH_DEVICE_INFOs. + # call BluetoothSelectDevicesFree() to free + + # + # Description: + # (See header above) + # + # Return Values: + # TRUE + # User selected a device. pbtsdp->pDevices points to valid data. + # Caller should check the fAuthenticated && fRemembered flags to + # determine which devices we successfuly authenticated or valid + # selections by the user. + # + # Use BluetoothSelectDevicesFree() to free the nessecary data + # such as pDevices only if this function returns TRUE. + # + # FALSE + # No valid data returned. Call GetLastError() for possible details + # of the failure. If GLE() is: + # + # ERROR_CANCELLED + # The user cancelled the request. + # + # ERROR_INVALID_PARAMETER + # The pbtsdp is NULL. + # + # ERROR_REVISION_MISMATCH + # The structure passed in as pbtsdp is of an unknown size. + # + # other WIN32 errors + # + proc BluetoothSelectDevices*(pbtsdp: ptr BLUETOOTH_SELECT_DEVICE_PARAMS): BOOL {. + stdcall, importc: "BluetoothSelectDevices", dynlib: libbluetooth.} + # + # Description: + # This function should only be called if BluetoothSelectDevices() returns + # TRUE. This function will free any memory and resource returned by the + # BluetoothSelectDevices() in the BLUETOOTH_SELECT_DEVICE_PARAMS + # structure. + # + # Return Values: + # TRUE + # Success. + # + # FALSE + # Nothing to free. + # + proc BluetoothSelectDevicesFree*(pbtsdp: ptr BLUETOOTH_SELECT_DEVICE_PARAMS): BOOL {. + stdcall, importc: "BluetoothSelectDevicesFree", dynlib: libbluetooth.} +# *************************************************************************** +# +# Device Property Sheet +# +# *************************************************************************** +# +# Description: +# Invokes the CPLs device info property sheet. +# +# Parameters: +# hwndParent +# HWND to parent the property sheet. +# +# pbtdi +# A pointer to a BLUETOOTH_DEVICE_INFO structure of the device +# to be displayed. +# +# Return Values: +# TRUE +# The property page was successfully displayed. +# +# FALSE +# Failure. The property page was not displayed. Check GetLastError +# for more details. +# +proc BluetoothDisplayDeviceProperties*(hwndParent: HWND; + pbtdi: ptr BLUETOOTH_DEVICE_INFO): BOOL {.stdcall, + importc: "BluetoothDisplayDeviceProperties", dynlib: libbluetooth.} +# *************************************************************************** +# +# Radio Authentication +# +# *************************************************************************** +# +# Description: +# Sends an authentication request to a remote device. +# +# There are two modes of operation. "Wizard mode" and "Blind mode." +# +# "Wizard mode" is invoked when the pszPasskey is NULL. This will cause +# the "Bluetooth Connection Wizard" to be invoked. The user will be +# prompted to enter a passkey during the wizard after which the +# authentication request will be sent. The user will see the success +# or failure of the authentication attempt. The user will also be +# given the oppurtunity to try to fix a failed authentication. +# +# "Blind mode" is invoked when the pszPasskey is non-NULL. This will +# cause the computer to send a authentication request to the remote +# device. No UI is ever displayed. The Bluetooth status code will be +# mapped to a Win32 Error code. +# +# Parameters: +# +# hwndParent +# The window to parent the authentication wizard. If NULL, the +# wizard will be parented off the desktop. +# +# hRadio +# A valid local radio handle or NULL. If NULL, then all radios will +# be tired. If any of the radios succeed, then the call will +# succeed. +# +# pbtdi +# BLUETOOTH_DEVICE_INFO record of the device to be authenticated. +# +# pszPasskey +# PIN to be used to authenticate the device. If NULL, then UI is +# displayed and the user steps through the authentication process. +# If not NULL, no UI is shown. The passkey is NOT NULL terminated. +# +# ulPasskeyLength +# Length of szPassKey in bytes. The length must be less than or +# equal to BLUETOOTH_MAX_PASSKEY_SIZE * sizeof(WCHAR). +# +# Return Values: +# +# ERROR_SUCCESS +# Success. +# +# ERROR_CANCELLED +# User aborted the operation. +# +# ERROR_INVALID_PARAMETER +# The device structure in pbtdi is invalid. +# +# ERROR_NO_MORE_ITEMS +# The device in pbtdi is already been marked as authenticated. +# +# other WIN32 error +# Failure. Return value is the error code. +# +# For "Blind mode," here is the current mapping of Bluetooth status +# code to Win32 error codes: +# +# { BTH_ERROR_SUCCESS, ERROR_SUCCESS }, +# { BTH_ERROR_NO_CONNECTION, ERROR_DEVICE_NOT_CONNECTED }, +# { BTH_ERROR_PAGE_TIMEOUT, WAIT_TIMEOUT }, +# { BTH_ERROR_HARDWARE_FAILURE, ERROR_GEN_FAILURE }, +# { BTH_ERROR_AUTHENTICATION_FAILURE, ERROR_NOT_AUTHENTICATED }, +# { BTH_ERROR_MEMORY_FULL, ERROR_NOT_ENOUGH_MEMORY }, +# { BTH_ERROR_CONNECTION_TIMEOUT, WAIT_TIMEOUT }, +# { BTH_ERROR_LMP_RESPONSE_TIMEOUT, WAIT_TIMEOUT }, +# { BTH_ERROR_MAX_NUMBER_OF_CONNECTIONS, ERROR_REQ_NOT_ACCEP }, +# { BTH_ERROR_PAIRING_NOT_ALLOWED, ERROR_ACCESS_DENIED }, +# { BTH_ERROR_UNSPECIFIED_ERROR, ERROR_NOT_READY }, +# { BTH_ERROR_LOCAL_HOST_TERMINATED_CONNECTION, ERROR_VC_DISCONNECTED }, +# +proc BluetoothAuthenticateDevice*(hwndParent: HWND; hRadio: HANDLE; + pbtbi: ptr BLUETOOTH_DEVICE_INFO; + pszPasskey: PWSTR; ulPasskeyLength: ULONG): DWORD {. + stdcall, importc: "BluetoothAuthenticateDevice", dynlib: libbluetooth, + deprecated.} +# +# Support added after KB942567 +# +# +# Replaces previous API +# +# +# Common header for all PIN related structures +# +type + BLUETOOTH_PIN_INFO* = object + pin*: array[BTH_MAX_PIN_SIZE, UCHAR] + pinLength*: UCHAR + + PBLUETOOTH_PIN_INFO* = ptr BLUETOOTH_PIN_INFO + BLUETOOTH_OOB_DATA_INFO* = object + C*: array[16, UCHAR] + R*: array[16, UCHAR] + + PBLUETOOTH_OOB_DATA_INFO* = ptr BLUETOOTH_OOB_DATA_INFO + BLUETOOTH_NUMERIC_COMPARISON_INFO* = object + NumericValue*: ULONG + + PBLUETOOTH_NUMERIC_COMPARISON_INFO* = ptr BLUETOOTH_NUMERIC_COMPARISON_INFO + BLUETOOTH_PASSKEY_INFO* = object + passkey*: ULONG + + PBLUETOOTH_PASSKEY_INFO* = ptr BLUETOOTH_PASSKEY_INFO +# +# Description: +# Sends an authentication request to a remote device. +# +# There are two modes of operation. "Wizard mode" and "Blind mode." +# +# "Wizard mode" is invoked when the pbtOobData is NULL. This will cause +# the "Bluetooth Connection Wizard" to be invoked. The user will be +# prompted to respond to the device authentication during the wizard +# after which the authentication request will be sent. The user will see the success +# or failure of the authentication attempt. The user will also be +# given the oppurtunity to try to fix a failed authentication. +# +# "Blind mode" is invoked when the pbtOobData is non-NULL. This will +# cause the computer to send a authentication request to the remote +# device. No UI is ever displayed. The Bluetooth status code will be +# mapped to a Win32 Error code. +# +# Parameters: +# +# hwndParent +# The window to parent the authentication wizard. If NULL, the +# wizard will be parented off the desktop. +# +# hRadio +# A valid local radio handle or NULL. If NULL, then all radios will +# be tired. If any of the radios succeed, then the call will +# succeed. +# +# pbtdi +# BLUETOOTH_DEVICE_INFO record of the device to be authenticated. +# +# pbtOobData +# Out of band data to be used to authenticate the device. If NULL, then UI is +# displayed and the user steps through the authentication process. +# If not NULL, no UI is shown. +# +# authenticationRequirement +# The Authentication Requirement of the caller. MITMProtection* +# +# +# Return Values: +# +# ERROR_SUCCESS +# Success. +# +# ERROR_CANCELLED +# User aborted the operation. +# +# ERROR_INVALID_PARAMETER +# The device structure in pbtdi is invalid. +# +# ERROR_NO_MORE_ITEMS +# The device in pbtdi is already been marked as authenticated. +# +# other WIN32 error +# Failure. Return value is the error code. +# +# For "Blind mode," here is the current mapping of Bluetooth status +# code to Win32 error codes: +# +# { BTH_ERROR_SUCCESS, ERROR_SUCCESS }, +# { BTH_ERROR_NO_CONNECTION, ERROR_DEVICE_NOT_CONNECTED }, +# { BTH_ERROR_PAGE_TIMEOUT, WAIT_TIMEOUT }, +# { BTH_ERROR_HARDWARE_FAILURE, ERROR_GEN_FAILURE }, +# { BTH_ERROR_AUTHENTICATION_FAILURE, ERROR_NOT_AUTHENTICATED }, +# { BTH_ERROR_MEMORY_FULL, ERROR_NOT_ENOUGH_MEMORY }, +# { BTH_ERROR_CONNECTION_TIMEOUT, WAIT_TIMEOUT }, +# { BTH_ERROR_LMP_RESPONSE_TIMEOUT, WAIT_TIMEOUT }, +# { BTH_ERROR_MAX_NUMBER_OF_CONNECTIONS, ERROR_REQ_NOT_ACCEP }, +# { BTH_ERROR_PAIRING_NOT_ALLOWED, ERROR_ACCESS_DENIED }, +# { BTH_ERROR_UNSPECIFIED_ERROR, ERROR_NOT_READY }, +# { BTH_ERROR_LOCAL_HOST_TERMINATED_CONNECTION, ERROR_VC_DISCONNECTED }, +# +proc BluetoothAuthenticateDeviceEx*(hwndParentIn: HWND; hRadioIn: HANDLE; + pbtdiInout: ptr BLUETOOTH_DEVICE_INFO; + pbtOobData: PBLUETOOTH_OOB_DATA_INFO; + authenticationRequirement: BLUETOOTH_AUTHENTICATION_REQUIREMENTS): DWORD {. + stdcall, importc: "BluetoothAuthenticateDeviceEx", + dynlib: libbluetooth.} +# +# Description: +# Allows the caller to prompt for multiple devices to be authenticated +# within a single instance of the "Bluetooth Connection Wizard." +# +# Parameters: +# +# hwndParent +# The window to parent the authentication wizard. If NULL, the +# wizard will be parented off the desktop. +# +# hRadio +# A valid local radio handle or NULL. If NULL, then all radios will +# be tired. If any of the radios succeed, then the call will +# succeed. +# +# cDevices +# Number of devices in the rgbtdi array. +# +# rgbtdi +# An array BLUETOOTH_DEVICE_INFO records of the devices to be +# authenticated. +# +# Return Values: +# +# ERROR_SUCCESS +# Success. Check the fAuthenticate flag on each of the devices. +# +# ERROR_CANCELLED +# User aborted the operation. Check the fAuthenticate flags on +# each device to determine if any of the devices were authenticated +# before the user cancelled the operation. +# +# ERROR_INVALID_PARAMETER +# One of the items in the array of devices is invalid. +# +# ERROR_NO_MORE_ITEMS +# All the devices in the array of devices are already been marked as +# being authenticated. +# +# other WIN32 error +# Failure. Return value is the error code. +# +proc BluetoothAuthenticateMultipleDevices*(hwndParent: HWND; hRadio: HANDLE; + cDevices: DWORD; rgbtdi: ptr BLUETOOTH_DEVICE_INFO): DWORD {.stdcall, + importc: "BluetoothAuthenticateMultipleDevices", dynlib: libbluetooth, + deprecated.} +# +# Deprecated after Vista SP1 and KB942567 +# + +# *************************************************************************** +# +# Bluetooth Services +# +# *************************************************************************** +const + BLUETOOTH_SERVICE_DISABLE* = 0x00000000 + BLUETOOTH_SERVICE_ENABLE* = 0x00000001 + BLUETOOTH_SERVICE_MASK* = ( + BLUETOOTH_SERVICE_DISABLE or BLUETOOTH_SERVICE_ENABLE) +# +# Description: +# Enables/disables the services for a particular device. +# +# The system maintains a mapping of service guids to supported drivers for +# Bluetooth-enabled devices. Enabling a service installs the corresponding +# device driver. Disabling a service removes the corresponding device driver. +# +# If a non-supported service is enabled, a driver will not be installed. +# +# Parameters +# hRadio +# Handle of the local Bluetooth radio device. +# +# pbtdi +# Pointer to a BLUETOOTH_DEVICE_INFO record. +# +# pGuidService +# The service GUID on the remote device. +# +# dwServiceFlags +# Flags to adjust the service. +# BLUETOOTH_SERVICE_DISABLE - disable the service +# BLUETOOTH_SERVICE_ENABLE - enables the service +# +# Return Values: +# ERROR_SUCCESS +# The call was successful. +# +# ERROR_INVALID_PARAMETER +# dwServiceFlags are invalid. +# +# ERROR_SERVICE_DOES_NOT_EXIST +# The GUID in pGuidService is not supported. +# +# other WIN32 error +# The call failed. +# +proc BluetoothSetServiceState*(hRadio: HANDLE; + pbtdi: ptr BLUETOOTH_DEVICE_INFO; + pGuidService: ptr GUID; dwServiceFlags: DWORD): DWORD {. + stdcall, importc: "BluetoothSetServiceState", dynlib: libbluetooth.} +# +# Description: +# Enumerates the services guids enabled on a particular device. If hRadio +# is NULL, all device will be searched for the device and all the services +# enabled will be returned. +# +# Parameters: +# hRadio +# Handle of the local Bluetooth radio device. If NULL, it will search +# all the radios for the address in the pbtdi. +# +# pbtdi +# Pointer to a BLUETOOTH_DEVICE_INFO record. +# +# pcService +# On input, the number of records pointed to by pGuidServices. +# On output, the number of valid records return in pGuidServices. +# +# pGuidServices +# Pointer to memory that is at least *pcService in length. +# +# Return Values: +# ERROR_SUCCESS +# The call succeeded. pGuidServices is valid. +# +# ERROR_MORE_DATA +# The call succeeded. pGuidService contains an incomplete list of +# enabled service GUIDs. +# +# other WIN32 errors +# The call failed. +# +proc BluetoothEnumerateInstalledServices*(hRadio: HANDLE; + pbtdi: ptr BLUETOOTH_DEVICE_INFO; pcServiceInout: ptr DWORD; + pGuidServices: ptr GUID): DWORD {.stdcall, + importc: "BluetoothEnumerateInstalledServices", dynlib: libbluetooth.} +# +# Description: +# Change the discovery state of the local radio(s). +# If hRadio is NULL, all the radios will be set. +# +# Use BluetoothIsDiscoverable() to determine the radios current state. +# +# The system ensures that a discoverable system is connectable, thus +# the radio must allow incoming connections (see +# BluetoothEnableIncomingConnections) prior to making a radio +# discoverable. Failure to do so will result in this call failing +# (returns FALSE). +# +# Parameters: +# hRadio +# If not NULL, changes the state of a specific radio. +# If NULL, the API will interate through all the radios. +# +# fEnabled +# If FALSE, discovery will be disabled. +# +# Return Values +# TRUE +# State was successfully changed. If the caller specified NULL for +# hRadio, at least of the radios accepted the state change. +# +# FALSE +# State was not changed. If the caller specified NULL for hRadio, all +# of the radios did not accept the state change. +# +proc BluetoothEnableDiscovery*(hRadio: HANDLE; fEnabled: BOOL): BOOL {. + stdcall, importc: "BluetoothEnableDiscovery", dynlib: libbluetooth.} +# +# Description: +# Determines if the Bluetooth radios are discoverable. If there are +# multiple radios, the first one to say it is discoverable will cause +# this function to return TRUE. +# +# Parameters: +# hRadio +# Handle of the radio to check. If NULL, it will check all local +# radios. +# +# Return Values: +# TRUE +# A least one radio is discoverable. +# +# FALSE +# No radios are discoverable. +# +proc BluetoothIsDiscoverable*(hRadio: HANDLE): BOOL {.stdcall, + importc: "BluetoothIsDiscoverable", dynlib: libbluetooth.} +# +# Description: +# Enables/disables the state of a radio to accept incoming connections. +# If hRadio is NULL, all the radios will be set. +# +# Use BluetoothIsConnectable() to determine the radios current state. +# +# The system enforces that a radio that is not connectable is not +# discoverable too. The radio must be made non-discoverable (see +# BluetoothEnableDiscovery) prior to making a radio non-connectionable. +# Failure to do so will result in this call failing (returns FALSE). +# +# Parameters: +# hRadio +# If not NULL, changes the state of a specific radio. +# If NULL, the API will interate through all the radios. +# +# fEnabled +# If FALSE, incoming connection will be disabled. +# +# Return Values +# TRUE +# State was successfully changed. If the caller specified NULL for +# hRadio, at least of the radios accepted the state change. +# +# FALSE +# State was not changed. If the caller specified NULL for hRadio, all +# of the radios did not accept the state change. +# +proc BluetoothEnableIncomingConnections*(hRadio: HANDLE; fEnabled: BOOL): BOOL {. + stdcall, importc: "BluetoothEnableIncomingConnections", + dynlib: libbluetooth.} +# +# Description: +# Determines if the Bluetooth radios are connectable. If there are +# multiple radios, the first one to say it is connectable will cause +# this function to return TRUE. +# +# Parameters: +# hRadio +# Handle of the radio to check. If NULL, it will check all local +# radios. +# +# Return Values: +# TRUE +# A least one radio is allowing incoming connections. +# +# FALSE +# No radios are allowing incoming connections. +# +proc BluetoothIsConnectable*(hRadio: HANDLE): BOOL {.stdcall, + importc: "BluetoothIsConnectable", dynlib: libbluetooth.} +# *************************************************************************** +# +# Authentication Registration +# +# *************************************************************************** +type + HBLUETOOTH_AUTHENTICATION_REGISTRATION* = HANDLE + PFN_AUTHENTICATION_CALLBACK* = proc (pvParam: LPVOID; + pDevice: PBLUETOOTH_DEVICE_INFO): BOOL {.stdcall.} +# +# Description: +# Registers a callback function to be called when a particular device +# requests authentication. The request is sent to the last application +# that requested authentication for a particular device. +# +# Parameters: +# pbtdi +# A pointer to a BLUETOOTH_DEVICE_INFO structure. The Bluetooth +# address will be used for comparision. +# +# phRegHandle +# A pointer to where the registration HANDLE value will be +# stored. Call BluetoothUnregisterAuthentication() to close +# the handle. +# +# pfnCallback +# The function that will be called when the authentication event +# occurs. This function should match PFN_AUTHENTICATION_CALLBACK's +# prototype. +# +# pvParam +# Optional parameter to be past through to the callback function. +# This can be anything the application was to define. +# +# Return Values: +# ERROR_SUCCESS +# Success. A valid registration handle was returned. +# +# ERROR_OUTOFMEMORY +# Out of memory. +# +# other Win32 error. +# Failure. The registration handle is invalid. +# +proc BluetoothRegisterForAuthentication*(pbtdi: ptr BLUETOOTH_DEVICE_INFO; + phRegHandle: ptr HBLUETOOTH_AUTHENTICATION_REGISTRATION; + pfnCallback: PFN_AUTHENTICATION_CALLBACK; pvParam: PVOID): DWORD {. + stdcall, importc: "BluetoothRegisterForAuthentication", + dynlib: libbluetooth, + deprecated.} +# +# Support added in KB942567 +# +# +# Replaces previous API +# +type + PFN_AUTHENTICATION_CALLBACK_EX* = proc (pvParam: LPVOID; + pAuthCallbackParams: PBLUETOOTH_AUTHENTICATION_CALLBACK_PARAMS): BOOL {. + stdcall.} +# +# Description: +# Registers a callback function to be called when a particular device +# requests authentication. The request is sent to the last application +# that requested authentication for a particular device. +# +# Parameters: +# pbtdi +# A pointer to a BLUETOOTH_DEVICE_INFO structure. The Bluetooth +# address will be used for comparision. +# +# phRegHandle +# A pointer to where the registration HANDLE value will be +# stored. Call BluetoothUnregisterAuthentication() to close +# the handle. +# +# pfnCallback +# The function that will be called when the authentication event +# occurs. This function should match PFN_AUTHENTICATION_CALLBACK_EX's +# prototype. +# +# pvParam +# Optional parameter to be past through to the callback function. +# This can be anything the application was to define. +# +# Return Values: +# ERROR_SUCCESS +# Success. A valid registration handle was returned. +# +# ERROR_OUTOFMEMORY +# Out of memory. +# +# other Win32 error. +# Failure. The registration handle is invalid. +# +proc BluetoothRegisterForAuthenticationEx*( + pbtdiIn: ptr BLUETOOTH_DEVICE_INFO; + phRegHandleOut: ptr HBLUETOOTH_AUTHENTICATION_REGISTRATION; + pfnCallbackIn: PFN_AUTHENTICATION_CALLBACK_EX; pvParam: PVOID): DWORD {. + stdcall, importc: "BluetoothRegisterForAuthenticationEx", + dynlib: libbluetooth.} +# +# Description: +# Unregisters an authentication callback and closes the handle. See +# BluetoothRegisterForAuthentication() for more information about +# authentication registration. +# +# Parameters: +# hRegHandle +# Handle returned by BluetoothRegisterForAuthentication(). +# +# Return Value: +# TRUE +# The handle was successfully closed. +# +# FALSE +# The handle was not successfully closed. Check GetLastError for +# more details. +# +# ERROR_INVALID_HANDLE +# The handle is NULL. +# +# other Win32 errors. +# +proc BluetoothUnregisterAuthentication*( + hRegHandle: HBLUETOOTH_AUTHENTICATION_REGISTRATION): BOOL {.stdcall, + importc: "BluetoothUnregisterAuthentication", dynlib: libbluetooth.} +# +# Description: +# This function should be called after receiving an authentication request +# to send the passkey response. +# +# Parameters: +# +# hRadio +# Optional handle to the local radio. If NULL, the function will try +# each radio until one succeeds. +# +# pbtdi +# A pointer to a BLUETOOTH_DEVICE_INFO structure describing the device +# being authenticated. This can be the same structure passed to the +# callback function. +# +# pszPasskey +# A pointer to UNICODE zero-terminated string of the passkey response +# that should be sent back to the authenticating device. +# +# Return Values: +# ERROR_SUCESS +# The device accepted the passkey response. The device is authenticated. +# +# ERROR_CANCELED +# The device denied the passkey reponse. This also will returned if there +# is a communications problem with the local radio. +# +# E_FAIL +# The device returned a failure code during authentication. +# +# other Win32 error codes +# +proc BluetoothSendAuthenticationResponse*(hRadio: HANDLE; + pbtdi: ptr BLUETOOTH_DEVICE_INFO; pszPasskey: LPCWSTR): DWORD {.stdcall, + importc: "BluetoothSendAuthenticationResponse", dynlib: libbluetooth, + deprecated.} +# +# Support added in KB942567 +# +# +# Replaces previous API +# +# +# Structure used when responding to BTH_REMOTE_AUTHENTICATE_REQUEST event +# +type + INNER_C_UNION_1965546500* = object {.union.} + pinInfo*: BLUETOOTH_PIN_INFO + oobInfo*: BLUETOOTH_OOB_DATA_INFO + numericCompInfo*: BLUETOOTH_NUMERIC_COMPARISON_INFO + passkeyInfo*: BLUETOOTH_PASSKEY_INFO + +type + BLUETOOTH_AUTHENTICATE_RESPONSE* = object + bthAddressRemote*: BLUETOOTH_ADDRESS + authMethod*: BLUETOOTH_AUTHENTICATION_METHOD + ano_660658457*: INNER_C_UNION_1965546500 + negativeResponse*: UCHAR + + PBLUETOOTH_AUTHENTICATE_RESPONSE* = ptr BLUETOOTH_AUTHENTICATE_RESPONSE +# +# Description: +# This function should be called after receiving an authentication request +# to send the authentication response. (Bluetooth 2.1 and above) +# +# Parameters: +# +# hRadio +# Optional handle to the local radio. If NULL, the function will try +# each radio until one succeeds. +# +# pbtdi +# A pointer to a BLUETOOTH_DEVICE_INFO structure describing the device +# being authenticated. This can be the same structure passed to the +# callback function. +# +# pauthResponse +# A pointer to a BTH_AUTHENTICATION_RESPONSE structure. +# +# Return Values: +# ERROR_SUCESS +# The device accepted the passkey response. The device is authenticated. +# +# ERROR_CANCELED +# The device denied the passkey reponse. This also will returned if there +# is a communications problem with the local radio. +# +# E_FAIL +# The device returned a failure code during authentication. +# +# other Win32 error codes +# +proc BluetoothSendAuthenticationResponseEx*(hRadioIn: HANDLE; + pauthResponse: PBLUETOOTH_AUTHENTICATE_RESPONSE): DWORD {.stdcall, + importc: "BluetoothSendAuthenticationResponseEx", dynlib: libbluetooth.} +# *************************************************************************** +# +# SDP Parsing Functions +# +# *************************************************************************** +type + INNER_C_STRUCT_3139021411* = object + value*: LPBYTE # raw string buffer, may not be encoded as ANSI, use + # BluetoothSdpGetString to convert the value if it is described + # by the base language attribute ID list + # raw length of the string, may not be NULL terminuated + length*: ULONG + +type + INNER_C_STRUCT_467337881* = object + value*: LPBYTE + length*: ULONG + +type + INNER_C_STRUCT_4155600511* = object + value*: LPBYTE # raw sequence, starts at sequence element header + # raw sequence length + length*: ULONG + +type + INNER_C_STRUCT_1234813489* = object + value*: LPBYTE # raw alternative, starts at alternative element header + # raw alternative length + length*: ULONG + +type + INNER_C_UNION_122694421* = object {.union.} + int128*: SDP_LARGE_INTEGER_16 # type == SDP_TYPE_INT + # specificType == SDP_ST_INT128 + int64*: LONGLONG # specificType == SDP_ST_INT64 + int32*: LONG # specificType == SDP_ST_INT32 + int16*: SHORT # specificType == SDP_ST_INT16 + int8*: CHAR # specificType == SDP_ST_INT8 + # type == SDP_TYPE_UINT + uint128*: SDP_ULARGE_INTEGER_16 # specificType == SDP_ST_UINT128 + uint64*: ULONGLONG # specificType == SDP_ST_UINT64 + uint32*: ULONG # specificType == SDP_ST_UINT32 + uint16*: USHORT # specificType == SDP_ST_UINT16 + uint8*: UCHAR # specificType == SDP_ST_UINT8 + # type == SDP_TYPE_BOOLEAN + booleanVal*: UCHAR # type == SDP_TYPE_UUID + uuid128*: GUID # specificType == SDP_ST_UUID128 + uuid32*: ULONG # specificType == SDP_ST_UUID32 + uuid16*: USHORT # specificType == SDP_ST_UUID32 + # type == SDP_TYPE_STRING + string*: INNER_C_STRUCT_3139021411 # type == SDP_TYPE_URL + url*: INNER_C_STRUCT_467337881 # type == SDP_TYPE_SEQUENCE + sequence*: INNER_C_STRUCT_4155600511 # type == SDP_TYPE_ALTERNATIVE + alternative*: INNER_C_STRUCT_1234813489 + +type + SDP_ELEMENT_DATA* = object + `type`*: SDP_TYPE # + # Enumeration of SDP element types. Generic element types will have a + # specificType value other then SDP_ST_NONE. The generic types are: + # o SDP_TYPE_UINT + # o SDP_TYPE_INT + # o SDP_TYPE_UUID + # + # + # Specific types for the generic SDP element types. + # + specificType*: SDP_SPECIFICTYPE # + # Union of all possible data types. type and specificType will indicate + # which field is valid. For types which do not have a valid specificType, + # specific type will be SDP_ST_NONE. + # + data*: INNER_C_UNION_122694421 + + PSDP_ELEMENT_DATA* = ptr SDP_ELEMENT_DATA +# +# Description: +# Retrieves and parses the element found at pSdpStream +# +# Parameters: +# IN pSdpStream +# pointer to valid SDP stream +# +# IN cbSdpStreamLength +# length of pSdpStream in bytes +# +# OUT pData +# pointer to be filled in with the data of the SDP element at the +# beginning of pSdpStream +# +# Return Values: +# ERROR_INVALID_PARAMETER +# one of required parameters is NULL or the pSdpStream is invalid +# +# ERROR_SUCCESS +# the sdp element was parsed correctly +# +proc BluetoothSdpGetElementData*(pSdpStream: LPBYTE; + cbSdpStreamLength: ULONG; + pData: PSDP_ELEMENT_DATA): DWORD {.stdcall, + importc: "BluetoothSdpGetElementData", dynlib: libbluetooth.} +type + HBLUETOOTH_CONTAINER_ELEMENT* = HANDLE +# +# Description: +# Iterates over a container stream, returning each elemetn contained with +# in the container element at the beginning of pContainerStream +# +# Parameters: +# IN pContainerStream +# pointer to valid SDP stream whose first element is either a sequence +# or alternative +# +# IN cbContainerlength +# length in bytes of pContainerStream +# +# IN OUT pElement +# Value used to keep track of location within the stream. The first +# time this function is called for a particular container, *pElement +# should equal NULL. Upon subsequent calls, the value should be +# unmodified. +# +# OUT pData +# pointer to be filled in with the data of the SDP element at the +# current element of pContainerStream +# +# Return Values: +# ERROR_SUCCESS +# The call succeeded, pData contains the data +# +# ERROR_NO_MORE_ITEMS +# There are no more items in the list, the caller should cease calling +# BluetoothSdpGetContainerElementData for this container. +# +# ERROR_INVALID_PARAMETER +# A required pointer is NULL or the container is not a valid SDP +# stream +# +# Usage example: +# +# HBLUETOOTH_CONTAINER_ELEMENT element; +# SDP_ELEMENT_DATA data; +# ULONG result; +# +# element = NULL; +# +# while (TRUE) { +# result = BluetoothSdpGetContainerElementData( +# pContainer, ulContainerLength, &element, &data); +# +# if (result == ERROR_NO_MORE_ITEMS) { +# // We are done +# break; +# } +# else if (result != ERROR_SUCCESS) { +# // error +# } +# +# // do something with data ... +# } +# +# +proc BluetoothSdpGetContainerElementData*(pContainerStream: LPBYTE; + cbContainerLength: ULONG; pElement: ptr HBLUETOOTH_CONTAINER_ELEMENT; + pData: PSDP_ELEMENT_DATA): DWORD {.stdcall, + importc: "BluetoothSdpGetContainerElementData", dynlib: libbluetooth.} +# +# Description: +# Retrieves the attribute value for the given attribute ID. pRecordStream +# must be an SDP stream that is formatted as an SDP record, a SEQUENCE +# containing UINT16 + element pairs. +# +# Parameters: +# IN pRecordStream +# pointer to a valid SDP stream which is formatted as a singl SDP +# record +# +# IN cbRecordlnegh +# length of pRecordStream in bytes +# +# IN usAttributeId +# the attribute ID to search for. see bthdef.h for SDP_ATTRIB_Xxx +# values. +# +# OUT pAttributeData +# pointer that will contain the attribute ID's value +# +# Return Values: +# ERRROR_SUCCESS +# Call succeeded, pAttributeData contains the attribute value +# +# ERROR_INVALID_PARAMETER +# One of the required pointers was NULL, pRecordStream was not a valid +# SDP stream, or pRecordStream was not a properly formatted SDP record +# +# ERROR_FILE_NOT_FOUND +# usAttributeId was not found in the record +# +# Usage: +# +# ULONG result; +# SDP_DATA_ELEMENT data; +# +# result = BluetoothSdpGetAttributeValue( +# pRecordStream, cbRecordLength, SDP_ATTRIB_RECORD_HANDLE, &data); +# if (result == ERROR_SUCCESS) { +# printf("record handle is 0x%x\n", data.data.uint32); +# } +# +proc BluetoothSdpGetAttributeValue*(pRecordStream: LPBYTE; + cbRecordLength: ULONG; + usAttributeId: USHORT; + pAttributeData: PSDP_ELEMENT_DATA): DWORD {. + stdcall, importc: "BluetoothSdpGetAttributeValue", dynlib: libbluetooth.} +# +# These three fields correspond one to one with the triplets defined in the +# SDP specification for the language base attribute ID list. +# +type + SDP_STRING_TYPE_DATA* = object + encoding*: USHORT # + # How the string is encoded according to ISO 639:1988 (E/F): "Code + # for the representation of names of languages". + # + # + # MIBE number from IANA database + # + mibeNum*: USHORT # + # The base attribute where the string is to be found in the record + # + attributeId*: USHORT + + PSDP_STRING_TYPE_DATA* = ptr SDP_STRING_TYPE_DATA +# +# Description: +# Converts a raw string embedded in the SDP record into a UNICODE string +# +# Parameters: +# IN pRecordStream +# a valid SDP stream which is formatted as an SDP record +# +# IN cbRecordLength +# length of pRecordStream in bytes +# +# IN pStringData +# if NULL, then the calling thread's locale will be used to search +# for a matching string in the SDP record. If not NUL, the mibeNum +# and attributeId will be used to find the string to convert. +# +# IN usStringOffset +# the SDP string type offset to convert. usStringOffset is added to +# the base attribute id of the string. SDP specification defined +# offsets are: STRING_NAME_OFFSET, STRING_DESCRIPTION_OFFSET, and +# STRING_PROVIDER_NAME_OFFSET (found in bthdef.h). +# +# OUT pszString +# if NULL, pcchStringLength will be filled in with the required number +# of characters (not bytes) to retrieve the converted string. +# +# IN OUT pcchStringLength +# Upon input, if pszString is not NULL, will contain the length of +# pszString in characters. Upon output, it will contain either the +# number of required characters including NULL if an error is returned +# or the number of characters written to pszString (including NULL). +# +# Return Values: +# ERROR_SUCCES +# Call was successful and pszString contains the converted string +# +# ERROR_MORE_DATA +# pszString was NULL or too small to contain the converted string, +# pccxhStringLength contains the required length in characters +# +# ERROR_INVALID_DATA +# Could not perform the conversion +# +# ERROR_NO_SYSTEM_RESOURCES +# Could not allocate memory internally to perform the conversion +# +# ERROR_INVALID_PARAMETER +# One of the rquired pointers was NULL, pRecordStream was not a valid +# SDP stream, pRecordStream was not a properly formatted record, or +# the desired attribute + offset was not a string. +# +# Other HRESULTs returned by COM +# +proc BluetoothSdpGetString*(pRecordStream: LPBYTE; cbRecordLength: ULONG; + pStringData: PSDP_STRING_TYPE_DATA; + usStringOffset: USHORT; pszString: PWSTR; + pcchStringLength: PULONG): DWORD {.stdcall, + importc: "BluetoothSdpGetString", dynlib: libbluetooth.} +# *************************************************************************** +# +# Raw Attribute Enumeration +# +# *************************************************************************** +type + PFN_BLUETOOTH_ENUM_ATTRIBUTES_CALLBACK* = proc (uAttribId: ULONG; + pValueStream: LPBYTE; cbStreamSize: ULONG; pvParam: LPVOID): BOOL {. + stdcall.} +# +# Description: +# Enumerates through the SDP record stream calling the Callback function +# for each attribute in the record. If the Callback function returns +# FALSE, the enumeration is stopped. +# +# Return Values: +# TRUE +# Success! Something was enumerated. +# +# FALSE +# Failure. GetLastError() could be one of the following: +# +# ERROR_INVALID_PARAMETER +# pSDPStream or pfnCallback is NULL. +# +# ERROR_INVALID_DATA +# The SDP stream is corrupt. +# +# other Win32 errors. +# +proc BluetoothSdpEnumAttributes*(pSDPStream: LPBYTE; cbStreamSize: ULONG; + pfnCallback: PFN_BLUETOOTH_ENUM_ATTRIBUTES_CALLBACK; pvParam: LPVOID): BOOL {. + stdcall, importc: "BluetoothSdpEnumAttributes", dynlib: libbluetooth.} +const + BluetoothEnumAttributes* = BluetoothSdpEnumAttributes +# +# The following APIs are only available on Vista or later +# +proc BluetoothSetLocalServiceInfo*(hRadioIn: HANDLE; pClassGuid: ptr GUID; + ulInstance: ULONG; pServiceInfoIn: ptr BLUETOOTH_LOCAL_SERVICE_INFO): DWORD {. + stdcall, importc: "BluetoothSetLocalServiceInfo", dynlib: libbluetooth.} + +# +# Support added in KB942567 +# + +# +# IsBluetoothVersionAvailable +# +# Description: +# Indicate if the installed Bluetooth binary set supports +# the requested version +# +# Return Values: +# TRUE if the installed bluetooth binaries support the given +# Major & Minor versions +# +# Note this function is only exported in version 2.1 and later. +# +proc BluetoothIsVersionAvailable*(MajorVersion: UCHAR; MinorVersion: UCHAR): BOOL {. + stdcall, importc: "BluetoothIsVersionAvailable", dynlib: libbluetooth.} diff --git a/nimbluez/msbt/ms_bthdef.nim b/nimbluez/msbt/ms_bthdef.nim new file mode 100644 index 0000000..96be91d --- /dev/null +++ b/nimbluez/msbt/ms_bthdef.nim @@ -0,0 +1,1279 @@ +#++ +# +#Copyright (c) 2000 Microsoft Corporation +# +#Module Name: +# +# bthdef.h +# +#Abstract: +# +# This module contains the Bluetooth common structures and definitions +# +#Author: +# +#Notes: +# +#Environment: +# +# Kernel mode only +# +# +#Revision History: +# +# -- +import winlean +import ms_bthsdpdef + +template DEFINE_GUID*(name: expr; p1: int32; p2, p3: int16; + p41, p42, p43, p44, p45, p46, p47, p48: int8): stmt {.immediate.} = + const + name* = GUID(D1: int32(p1), D2: int16(p2), D3: int16(p3), + D4: [int8(p41), int8(p42), int8(p43), int8(p44), + int8(p45), int8(p46), int8(p47), int8(p48)]) +# +# Bluetooth 2.1 support added in KB942567 +# + +# {0850302A-B344-4fda-9BE9-90576B8D46F0} +DEFINE_GUID(GUID_BTHPORT_DEVICE_INTERFACE, 0x0850302A, 0x0000B344, + 0x00004FDA, 0x0000009B, 0x000000E9, 0x00000090, 0x00000057, + 0x0000006B, 0x0000008D, 0x00000046, 0x000000F0) +# RFCOMM device interface GUID for RFCOMM services +# {b142fc3e-fa4e-460b-8abc-072b628b3c70} +DEFINE_GUID(GUID_BTH_RFCOMM_SERVICE_DEVICE_INTERFACE, 0xB142FC3E, + 0x0000FA4E, 0x0000460B, 0x0000008A, 0x000000BC, 0x00000007, + 0x0000002B, 0x00000062, 0x0000008B, 0x0000003C, 0x00000070) +# {EA3B5B82-26EE-450E-B0D8-D26FE30A3869} +DEFINE_GUID(GUID_BLUETOOTH_RADIO_IN_RANGE, 0xEA3B5B82, 0x000026EE, + 0x0000450E, 0x000000B0, 0x000000D8, 0x000000D2, 0x0000006F, + 0x000000E3, 0x0000000A, 0x00000038, 0x00000069) +# {E28867C9-C2AA-4CED-B969-4570866037C4} +DEFINE_GUID(GUID_BLUETOOTH_RADIO_OUT_OF_RANGE, 0xE28867C9, 0x0000C2AA, + 0x00004CED, 0x000000B9, 0x00000069, 0x00000045, 0x00000070, + 0x00000086, 0x00000060, 0x00000037, 0x000000C4) +# {7EAE4030-B709-4AA8-AC55-E953829C9DAA} +DEFINE_GUID(GUID_BLUETOOTH_L2CAP_EVENT, 0x7EAE4030, 0x0000B709, + 0x00004AA8, 0x000000AC, 0x00000055, 0x000000E9, 0x00000053, + 0x00000082, 0x0000009C, 0x0000009D, 0x000000AA) +# {FC240062-1541-49BE-B463-84C4DCD7BF7F} +DEFINE_GUID(GUID_BLUETOOTH_HCI_EVENT, 0xFC240062, 0x00001541, 0x000049BE, + 0x000000B4, 0x00000063, 0x00000084, 0x000000C4, 0x000000DC, + 0x000000D7, 0x000000BF, 0x0000007F) +# +# Support added in KB942567 +# +# {5DC9136D-996C-46DB-84F5-32C0A3F47352} +DEFINE_GUID(GUID_BLUETOOTH_AUTHENTICATION_REQUEST, 0x5DC9136D, + 0x0000996C, 0x000046DB, 0x00000084, 0x000000F5, 0x00000032, + 0x000000C0, 0x000000A3, 0x000000F4, 0x00000073, 0x00000052) +# {D668DFCD-0F4E-4EFC-BFE0-392EEEC5109C} +DEFINE_GUID(GUID_BLUETOOTH_KEYPRESS_EVENT, 0xD668DFCD, 0x00000F4E, + 0x00004EFC, 0x000000BF, 0x000000E0, 0x00000039, 0x0000002E, + 0x000000EE, 0x000000C5, 0x00000010, 0x0000009C) +# {547247e6-45bb-4c33-af8c-c00efe15a71d} +DEFINE_GUID(GUID_BLUETOOTH_HCI_VENDOR_EVENT, 0x547247E6, 0x000045BB, + 0x00004C33, 0x000000AF, 0x0000008C, 0x000000C0, 0x0000000E, + 0x000000FE, 0x00000015, 0x000000A7, 0x0000001D) +# +# Bluetooth base UUID for service discovery +# +DEFINE_GUID(Bluetooth_Base_UUID, 0x00000000, 0x00000000, 0x00001000, + 0x00000080, 0x00000000, 0x00000000, 0x00000080, 0x0000005F, + 0x0000009B, 0x00000034, 0x000000FB) +# +# UUID for the root of the browse group list +# +DEFINE_GUID(SDP_PROTOCOL_UUID, 0x00000001, 0x00000000, 0x00001000, + 0x00000080, 0x00000000, 0x00000000, 0x00000080, 0x0000005F, + 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(UDP_PROTOCOL_UUID, 0x00000002, 0x00000000, 0x00001000, + 0x00000080, 0x00000000, 0x00000000, 0x00000080, 0x0000005F, + 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(RFCOMM_PROTOCOL_UUID, 0x00000003, 0x00000000, 0x00001000, + 0x00000080, 0x00000000, 0x00000000, 0x00000080, 0x0000005F, + 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(TCP_PROTOCOL_UUID, 0x00000004, 0x00000000, 0x00001000, + 0x00000080, 0x00000000, 0x00000000, 0x00000080, 0x0000005F, + 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(TCSBIN_PROTOCOL_UUID, 0x00000005, 0x00000000, 0x00001000, + 0x00000080, 0x00000000, 0x00000000, 0x00000080, 0x0000005F, + 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(TCSAT_PROTOCOL_UUID, 0x00000006, 0x00000000, 0x00001000, + 0x00000080, 0x00000000, 0x00000000, 0x00000080, 0x0000005F, + 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(OBEX_PROTOCOL_UUID, 0x00000008, 0x00000000, 0x00001000, + 0x00000080, 0x00000000, 0x00000000, 0x00000080, 0x0000005F, + 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(IP_PROTOCOL_UUID, 0x00000009, 0x00000000, 0x00001000, + 0x00000080, 0x00000000, 0x00000000, 0x00000080, 0x0000005F, + 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(FTP_PROTOCOL_UUID, 0x0000000A, 0x00000000, 0x00001000, + 0x00000080, 0x00000000, 0x00000000, 0x00000080, 0x0000005F, + 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(HTTP_PROTOCOL_UUID, 0x0000000C, 0x00000000, 0x00001000, + 0x00000080, 0x00000000, 0x00000000, 0x00000080, 0x0000005F, + 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(WSP_PROTOCOL_UUID, 0x0000000E, 0x00000000, 0x00001000, + 0x00000080, 0x00000000, 0x00000000, 0x00000080, 0x0000005F, + 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(BNEP_PROTOCOL_UUID, 0x0000000F, 0x00000000, 0x00001000, + 0x00000080, 0x00000000, 0x00000000, 0x00000080, 0x0000005F, + 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(UPNP_PROTOCOL_UUID, 0x00000010, 0x00000000, 0x00001000, + 0x00000080, 0x00000000, 0x00000000, 0x00000080, 0x0000005F, + 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(HID_PROTOCOL_UUID, 0x00000011, 0x00000000, 0x00001000, + 0x00000080, 0x00000000, 0x00000000, 0x00000080, 0x0000005F, + 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(HCCC_PROTOCOL_UUID, 0x00000012, 0x00000000, 0x00001000, + 0x00000080, 0x00000000, 0x00000000, 0x00000080, 0x0000005F, + 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(HCDC_PROTOCOL_UUID, 0x00000014, 0x00000000, 0x00001000, + 0x00000080, 0x00000000, 0x00000000, 0x00000080, 0x0000005F, + 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(HN_PROTOCOL_UUID, 0x00000016, 0x00000000, 0x00001000, + 0x00000080, 0x00000000, 0x00000000, 0x00000080, 0x0000005F, + 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(AVCTP_PROTOCOL_UUID, 0x00000017, 0x00000000, 0x00001000, + 0x00000080, 0x00000000, 0x00000000, 0x00000080, 0x0000005F, + 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(AVDTP_PROTOCOL_UUID, 0x00000019, 0x00000000, 0x00001000, + 0x00000080, 0x00000000, 0x00000000, 0x00000080, 0x0000005F, + 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(CMPT_PROTOCOL_UUID, 0x0000001B, 0x00000000, 0x00001000, + 0x00000080, 0x00000000, 0x00000000, 0x00000080, 0x0000005F, + 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(UDI_C_PLANE_PROTOCOL_UUID, 0x0000001D, 0x00000000, 0x00001000, + 0x00000080, 0x00000000, 0x00000000, 0x00000080, 0x0000005F, + 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(L2CAP_PROTOCOL_UUID, 0x00000100, 0x00000000, 0x00001000, + 0x00000080, 0x00000000, 0x00000000, 0x00000080, 0x0000005F, + 0x0000009B, 0x00000034, 0x000000FB) +const + SDP_PROTOCOL_UUID16* = (0x00000001) + UDP_PROTOCOL_UUID16* = (0x00000002) + RFCOMM_PROTOCOL_UUID16* = (0x00000003) + TCP_PROTOCOL_UUID16* = (0x00000004) + TCSBIN_PROTOCOL_UUID16* = (0x00000005) + TCSAT_PROTOCOL_UUID16* = (0x00000006) + OBEX_PROTOCOL_UUID16* = (0x00000008) + IP_PROTOCOL_UUID16* = (0x00000009) + FTP_PROTOCOL_UUID16* = (0x0000000A) + HTTP_PROTOCOL_UUID16* = (0x0000000C) + WSP_PROTOCOL_UUID16* = (0x0000000E) + BNEP_PROTOCOL_UUID16* = (0x0000000F) + UPNP_PROTOCOL_UUID16* = (0x00000010) + HID_PROTOCOL_UUID16* = (0x00000011) + HCCC_PROTOCOL_UUID16* = (0x00000012) + HCDC_PROTOCOL_UUID16* = (0x00000014) + HCN_PROTOCOL_UUID16* = (0x00000016) + AVCTP_PROTOCOL_UUID16* = (0x00000017) + AVDTP_PROTOCOL_UUID16* = (0x00000019) + CMPT_PROTOCOL_UUID16* = (0x0000001B) + UDI_C_PLANE_PROTOCOL_UUID16* = (0x0000001D) + L2CAP_PROTOCOL_UUID16* = (0x00000100) +DEFINE_GUID(ServiceDiscoveryServerServiceClassID_UUID, 0x00001000, + 0x00000000, 0x00001000, 0x00000080, 0x00000000, 0x00000000, + 0x00000080, 0x0000005F, 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(BrowseGroupDescriptorServiceClassID_UUID, 0x00001001, + 0x00000000, 0x00001000, 0x00000080, 0x00000000, 0x00000000, + 0x00000080, 0x0000005F, 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(PublicBrowseGroupServiceClass_UUID, 0x00001002, 0x00000000, + 0x00001000, 0x00000080, 0x00000000, 0x00000000, 0x00000080, + 0x0000005F, 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(SerialPortServiceClass_UUID, 0x00001101, 0x00000000, + 0x00001000, 0x00000080, 0x00000000, 0x00000000, 0x00000080, + 0x0000005F, 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(LANAccessUsingPPPServiceClass_UUID, 0x00001102, 0x00000000, + 0x00001000, 0x00000080, 0x00000000, 0x00000000, 0x00000080, + 0x0000005F, 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(DialupNetworkingServiceClass_UUID, 0x00001103, 0x00000000, + 0x00001000, 0x00000080, 0x00000000, 0x00000000, 0x00000080, + 0x0000005F, 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(IrMCSyncServiceClass_UUID, 0x00001104, 0x00000000, 0x00001000, + 0x00000080, 0x00000000, 0x00000000, 0x00000080, 0x0000005F, + 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(OBEXObjectPushServiceClass_UUID, 0x00001105, 0x00000000, + 0x00001000, 0x00000080, 0x00000000, 0x00000000, 0x00000080, + 0x0000005F, 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(OBEXFileTransferServiceClass_UUID, 0x00001106, 0x00000000, + 0x00001000, 0x00000080, 0x00000000, 0x00000000, 0x00000080, + 0x0000005F, 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(IrMCSyncCommandServiceClass_UUID, 0x00001107, 0x00000000, + 0x00001000, 0x00000080, 0x00000000, 0x00000000, 0x00000080, + 0x0000005F, 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(HeadsetServiceClass_UUID, 0x00001108, 0x00000000, 0x00001000, + 0x00000080, 0x00000000, 0x00000000, 0x00000080, 0x0000005F, + 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(CordlessTelephonyServiceClass_UUID, 0x00001109, 0x00000000, + 0x00001000, 0x00000080, 0x00000000, 0x00000000, 0x00000080, + 0x0000005F, 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(AudioSourceServiceClass_UUID, 0x0000110A, 0x00000000, + 0x00001000, 0x00000080, 0x00000000, 0x00000000, 0x00000080, + 0x0000005F, 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(AudioSinkServiceClass_UUID, 0x0000110B, 0x00000000, + 0x00001000, 0x00000080, 0x00000000, 0x00000000, 0x00000080, + 0x0000005F, 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(AVRemoteControlTargetServiceClass_UUID, 0x0000110C, + 0x00000000, 0x00001000, 0x00000080, 0x00000000, 0x00000000, + 0x00000080, 0x0000005F, 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(AdvancedAudioDistributionServiceClass_UUID, 0x0000110D, + 0x00000000, 0x00001000, 0x00000080, 0x00000000, 0x00000000, + 0x00000080, 0x0000005F, 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(AVRemoteControlServiceClass_UUID, 0x0000110E, 0x00000000, + 0x00001000, 0x00000080, 0x00000000, 0x00000000, 0x00000080, + 0x0000005F, 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(AVRemoteControlControllerServiceClass_UUID, 0x0000110F, + 0x00000000, 0x00001000, 0x00000080, 0x00000000, 0x00000000, + 0x00000080, 0x0000005F, 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(IntercomServiceClass_UUID, 0x00001110, 0x00000000, 0x00001000, + 0x00000080, 0x00000000, 0x00000000, 0x00000080, 0x0000005F, + 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(FaxServiceClass_UUID, 0x00001111, 0x00000000, 0x00001000, + 0x00000080, 0x00000000, 0x00000000, 0x00000080, 0x0000005F, + 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(HeadsetAudioGatewayServiceClass_UUID, 0x00001112, 0x00000000, + 0x00001000, 0x00000080, 0x00000000, 0x00000000, 0x00000080, + 0x0000005F, 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(WAPServiceClass_UUID, 0x00001113, 0x00000000, 0x00001000, + 0x00000080, 0x00000000, 0x00000000, 0x00000080, 0x0000005F, + 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(WAPClientServiceClass_UUID, 0x00001114, 0x00000000, + 0x00001000, 0x00000080, 0x00000000, 0x00000000, 0x00000080, + 0x0000005F, 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(PANUServiceClass_UUID, 0x00001115, 0x00000000, 0x00001000, + 0x00000080, 0x00000000, 0x00000000, 0x00000080, 0x0000005F, + 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(NAPServiceClass_UUID, 0x00001116, 0x00000000, 0x00001000, + 0x00000080, 0x00000000, 0x00000000, 0x00000080, 0x0000005F, + 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(GNServiceClass_UUID, 0x00001117, 0x00000000, 0x00001000, + 0x00000080, 0x00000000, 0x00000000, 0x00000080, 0x0000005F, + 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(DirectPrintingServiceClass_UUID, 0x00001118, 0x00000000, + 0x00001000, 0x00000080, 0x00000000, 0x00000000, 0x00000080, + 0x0000005F, 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(ReferencePrintingServiceClass_UUID, 0x00001119, 0x00000000, + 0x00001000, 0x00000080, 0x00000000, 0x00000000, 0x00000080, + 0x0000005F, 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(ImagingServiceClass_UUID, 0x0000111A, 0x00000000, 0x00001000, + 0x00000080, 0x00000000, 0x00000000, 0x00000080, 0x0000005F, + 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(ImagingResponderServiceClass_UUID, 0x0000111B, 0x00000000, + 0x00001000, 0x00000080, 0x00000000, 0x00000000, 0x00000080, + 0x0000005F, 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(ImagingAutomaticArchiveServiceClass_UUID, 0x0000111C, + 0x00000000, 0x00001000, 0x00000080, 0x00000000, 0x00000000, + 0x00000080, 0x0000005F, 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(ImagingReferenceObjectsServiceClass_UUID, 0x0000111D, + 0x00000000, 0x00001000, 0x00000080, 0x00000000, 0x00000000, + 0x00000080, 0x0000005F, 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(HandsfreeServiceClass_UUID, 0x0000111E, 0x00000000, + 0x00001000, 0x00000080, 0x00000000, 0x00000000, 0x00000080, + 0x0000005F, 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(HandsfreeAudioGatewayServiceClass_UUID, 0x0000111F, + 0x00000000, 0x00001000, 0x00000080, 0x00000000, 0x00000000, + 0x00000080, 0x0000005F, 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(DirectPrintingReferenceObjectsServiceClass_UUID, 0x00001120, + 0x00000000, 0x00001000, 0x00000080, 0x00000000, 0x00000000, + 0x00000080, 0x0000005F, 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(ReflectedUIServiceClass_UUID, 0x00001121, 0x00000000, + 0x00001000, 0x00000080, 0x00000000, 0x00000000, 0x00000080, + 0x0000005F, 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(BasicPringingServiceClass_UUID, 0x00001122, 0x00000000, + 0x00001000, 0x00000080, 0x00000000, 0x00000000, 0x00000080, + 0x0000005F, 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(PrintingStatusServiceClass_UUID, 0x00001123, 0x00000000, + 0x00001000, 0x00000080, 0x00000000, 0x00000000, 0x00000080, + 0x0000005F, 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(HumanInterfaceDeviceServiceClass_UUID, 0x00001124, 0x00000000, + 0x00001000, 0x00000080, 0x00000000, 0x00000000, 0x00000080, + 0x0000005F, 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(HardcopyCableReplacementServiceClass_UUID, 0x00001125, + 0x00000000, 0x00001000, 0x00000080, 0x00000000, 0x00000000, + 0x00000080, 0x0000005F, 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(HCRPrintServiceClass_UUID, 0x00001126, 0x00000000, 0x00001000, + 0x00000080, 0x00000000, 0x00000000, 0x00000080, 0x0000005F, + 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(HCRScanServiceClass_UUID, 0x00001127, 0x00000000, 0x00001000, + 0x00000080, 0x00000000, 0x00000000, 0x00000080, 0x0000005F, + 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(CommonISDNAccessServiceClass_UUID, 0x00001128, 0x00000000, + 0x00001000, 0x00000080, 0x00000000, 0x00000000, 0x00000080, + 0x0000005F, 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(VideoConferencingGWServiceClass_UUID, 0x00001129, 0x00000000, + 0x00001000, 0x00000080, 0x00000000, 0x00000000, 0x00000080, + 0x0000005F, 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(UDIMTServiceClass_UUID, 0x0000112A, 0x00000000, 0x00001000, + 0x00000080, 0x00000000, 0x00000000, 0x00000080, 0x0000005F, + 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(UDITAServiceClass_UUID, 0x0000112B, 0x00000000, 0x00001000, + 0x00000080, 0x00000000, 0x00000000, 0x00000080, 0x0000005F, + 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(AudioVideoServiceClass_UUID, 0x0000112C, 0x00000000, + 0x00001000, 0x00000080, 0x00000000, 0x00000000, 0x00000080, + 0x0000005F, 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(SimAccessServiceClass_UUID, 0x0000112D, 0x00000000, + 0x00001000, 0x00000080, 0x00000000, 0x00000000, 0x00000080, + 0x0000005F, 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(PhonebookAccessPceServiceClass_UUID, 0x0000112E, 0x00000000, + 0x00001000, 0x00000080, 0x00000000, 0x00000000, 0x00000080, + 0x0000005F, 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(PhonebookAccessPseServiceClass_UUID, 0x0000112F, 0x00000000, + 0x00001000, 0x00000080, 0x00000000, 0x00000000, 0x00000080, + 0x0000005F, 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(PnPInformationServiceClass_UUID, 0x00001200, 0x00000000, + 0x00001000, 0x00000080, 0x00000000, 0x00000000, 0x00000080, + 0x0000005F, 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(GenericNetworkingServiceClass_UUID, 0x00001201, 0x00000000, + 0x00001000, 0x00000080, 0x00000000, 0x00000000, 0x00000080, + 0x0000005F, 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(GenericFileTransferServiceClass_UUID, 0x00001202, 0x00000000, + 0x00001000, 0x00000080, 0x00000000, 0x00000000, 0x00000080, + 0x0000005F, 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(GenericAudioServiceClass_UUID, 0x00001203, 0x00000000, + 0x00001000, 0x00000080, 0x00000000, 0x00000000, 0x00000080, + 0x0000005F, 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(GenericTelephonyServiceClass_UUID, 0x00001204, 0x00000000, + 0x00001000, 0x00000080, 0x00000000, 0x00000000, 0x00000080, + 0x0000005F, 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(UPnpServiceClass_UUID, 0x00001205, 0x00000000, 0x00001000, + 0x00000080, 0x00000000, 0x00000000, 0x00000080, 0x0000005F, + 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(UPnpIpServiceClass_UUID, 0x00001206, 0x00000000, 0x00001000, + 0x00000080, 0x00000000, 0x00000000, 0x00000080, 0x0000005F, + 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(ESdpUpnpIpPanServiceClass_UUID, 0x00001300, 0x00000000, + 0x00001000, 0x00000080, 0x00000000, 0x00000000, 0x00000080, + 0x0000005F, 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(ESdpUpnpIpLapServiceClass_UUID, 0x00001301, 0x00000000, + 0x00001000, 0x00000080, 0x00000000, 0x00000000, 0x00000080, + 0x0000005F, 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(ESdpUpnpL2capServiceClass_UUID, 0x00001302, 0x00000000, + 0x00001000, 0x00000080, 0x00000000, 0x00000000, 0x00000080, + 0x0000005F, 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(VideoSourceServiceClass_UUID, 0x00001303, 0x00000000, + 0x00001000, 0x00000080, 0x00000000, 0x00000000, 0x00000080, + 0x0000005F, 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(VideoSinkServiceClass_UUID, 0x00001304, 0x00000000, + 0x00001000, 0x00000080, 0x00000000, 0x00000000, 0x00000080, + 0x0000005F, 0x0000009B, 0x00000034, 0x000000FB) +DEFINE_GUID(VideoDistributionServiceClass_UUID, 0x00001305, 0x00000000, + 0x00001000, 0x00000080, 0x00000000, 0x00000000, 0x00000080, + 0x0000005F, 0x0000009B, 0x00000034, 0x000000FB) +# +# Fixing typos introduced in previous releases +# +const + BasicPrintingServiceClass_UUID* = BasicPringingServiceClass_UUID + ServiceDiscoveryServerServiceClassID_UUID16* = (0x00001000) + BrowseGroupDescriptorServiceClassID_UUID16* = (0x00001001) + PublicBrowseGroupServiceClassID_UUID16* = (0x00001002) + SerialPortServiceClassID_UUID16* = (0x00001101) + LANAccessUsingPPPServiceClassID_UUID16* = (0x00001102) + DialupNetworkingServiceClassID_UUID16* = (0x00001103) + IrMCSyncServiceClassID_UUID16* = (0x00001104) + OBEXObjectPushServiceClassID_UUID16* = (0x00001105) + OBEXFileTransferServiceClassID_UUID16* = (0x00001106) + IrMcSyncCommandServiceClassID_UUID16* = (0x00001107) + HeadsetServiceClassID_UUID16* = (0x00001108) + CordlessServiceClassID_UUID16* = (0x00001109) + AudioSourceServiceClassID_UUID16* = (0x0000110A) + AudioSinkSourceServiceClassID_UUID16* = (0x0000110B) + AVRemoteControlTargetServiceClassID_UUID16* = (0x0000110C) + AdvancedAudioDistributionServiceClassID_UUID16* = (0x0000110D) + AVRemoteControlServiceClassID_UUID16* = (0x0000110E) + AVRemoteControlControllerServiceClass_UUID16* = (0x0000110F) + IntercomServiceClassID_UUID16* = (0x00001110) + FaxServiceClassID_UUID16* = (0x00001111) + HeadsetAudioGatewayServiceClassID_UUID16* = (0x00001112) + WAPServiceClassID_UUID16* = (0x00001113) + WAPClientServiceClassID_UUID16* = (0x00001114) + PANUServiceClassID_UUID16* = (0x00001115) + NAPServiceClassID_UUID16* = (0x00001116) + GNServiceClassID_UUID16* = (0x00001117) + DirectPrintingServiceClassID_UUID16* = (0x00001118) + ReferencePrintingServiceClassID_UUID16* = (0x00001119) + ImagingServiceClassID_UUID16* = (0x0000111A) + ImagingResponderServiceClassID_UUID16* = (0x0000111B) + ImagingAutomaticArchiveServiceClassID_UUID16* = (0x0000111C) + ImagingReferenceObjectsServiceClassID_UUID16* = (0x0000111D) + HandsfreeServiceClassID_UUID16* = (0x0000111E) + HandsfreeAudioGatewayServiceClassID_UUID16* = (0x0000111F) + DirectPrintingReferenceObjectsServiceClassID_UUID16* = (0x00001120) + ReflectsUIServiceClassID_UUID16* = (0x00001121) + BasicPrintingServiceClassID_UUID16* = (0x00001122) + PrintingStatusServiceClassID_UUID16* = (0x00001123) + HumanInterfaceDeviceServiceClassID_UUID16* = (0x00001124) + HardcopyCableReplacementServiceClassID_UUID16* = (0x00001125) + HCRPrintServiceClassID_UUID16* = (0x00001126) + HCRScanServiceClassID_UUID16* = (0x00001127) + CommonISDNAccessServiceClass_UUID16* = (0x00001128) + VideoConferencingGWServiceClass_UUID16* = (0x00001129) + UDIMTServiceClass_UUID16* = (0x0000112A) + UDITAServiceClass_UUID16* = (0x0000112B) + AudioVideoServiceClass_UUID16* = (0x0000112C) + PnPInformationServiceClassID_UUID16* = (0x00001200) + GenericNetworkingServiceClassID_UUID16* = (0x00001201) + GenericFileTransferServiceClassID_UUID16* = (0x00001202) + GenericAudioServiceClassID_UUID16* = (0x00001203) + GenericTelephonyServiceClassID_UUID16* = (0x00001204) +# +# The SIG renamed the uuid for VideoConferencingServiceClass +# +const + VideoConferencingServiceClass_UUID* = AVRemoteControlControllerServiceClass_UUID + VideoConferencingServiceClassID_UUID16* = AVRemoteControlControllerServiceClass_UUID16 + +# +# max length of device friendly name. +# +const + BTH_MAX_NAME_SIZE* = (248) + BTH_MAX_PIN_SIZE* = (16) + BTH_LINK_KEY_LENGTH* = (16) + BTH_MFG_ERICSSON* = (0) + BTH_MFG_NOKIA* = (1) + BTH_MFG_INTEL* = (2) + BTH_MFG_IBM* = (3) + BTH_MFG_TOSHIBA* = (4) + BTH_MFG_3COM* = (5) + BTH_MFG_MICROSOFT* = (6) + BTH_MFG_LUCENT* = (7) + BTH_MFG_MOTOROLA* = (8) + BTH_MFG_INFINEON* = (9) + BTH_MFG_CSR* = (10) + BTH_MFG_SILICONWAVE* = (11) + BTH_MFG_DIGIANSWER* = (12) + BTH_MFG_TI* = (13) + BTH_MFG_PARTHUS* = (14) + BTH_MFG_BROADCOM* = (15) + BTH_MFG_MITEL* = (16) + BTH_MFG_WIDCOMM* = (17) + BTH_MFG_ZEEVO* = (18) + BTH_MFG_ATMEL* = (19) + BTH_MFG_MITSIBUSHI* = (20) + BTH_MFG_RTX_TELECOM* = (21) + BTH_MFG_KC_TECHNOLOGY* = (22) + BTH_MFG_NEWLOGIC* = (23) + BTH_MFG_TRANSILICA* = (24) + BTH_MFG_ROHDE_SCHWARZ* = (25) + BTH_MFG_TTPCOM* = (26) + BTH_MFG_SIGNIA* = (27) + BTH_MFG_CONEXANT* = (28) + BTH_MFG_QUALCOMM* = (29) + BTH_MFG_INVENTEL* = (30) + BTH_MFG_AVM_BERLIN* = (31) + BTH_MFG_BANDSPEED* = (32) + BTH_MFG_MANSELLA* = (33) + BTH_MFG_NEC* = (34) + BTH_MFG_WAVEPLUS_TECHNOLOGY_CO* = (35) + BTH_MFG_ALCATEL* = (36) + BTH_MFG_PHILIPS_SEMICONDUCTOR* = (37) + BTH_MFG_C_TECHNOLOGIES* = (38) + BTH_MFG_OPEN_INTERFACE* = (39) + BTH_MFG_RF_MICRO_DEVICES* = (40) + BTH_MFG_HITACHI* = (41) + BTH_MFG_SYMBOL_TECHNOLOGIES* = (42) + BTH_MFG_TENOVIS* = (43) + BTH_MFG_MACRONIX_INTERNATIONAL* = (44) + BTH_MFG_NORDIC_SEMICONDUCTORS_ASA* = (89) + BTH_MFG_INTERNAL_USE* = (65535) +type + BTH_ADDR* = ULONGLONG + PBTH_ADDR* = ptr ULONGLONG + BTH_COD* = ULONG + PBTH_COD* = ptr ULONG + BTH_LAP* = ULONG + PBTH_LAP* = ptr ULONG +const + NAP_BIT_OFFSET* = (8 * 4) + SAP_BIT_OFFSET* = (0) +template GET_NAP*(bth_addr: expr): expr = + ((USHORT)(((bth_addr) and NAP_MASK) shr NAP_BIT_OFFSET)) + +template GET_SAP*(bth_addr: expr): expr = + ((ULONG)(((bth_addr) and SAP_MASK) shr SAP_BIT_OFFSET)) + +template SET_NAP*(nap: expr): expr = + (((ULONGLONG)((USHORT)(nap))) shl NAP_BIT_OFFSET) + +template SET_SAP*(sap: expr): expr = + (((ULONGLONG)((ULONG)(sap))) shl SAP_BIT_OFFSET) + +template SET_NAP_SAP*(nap, sap: expr): expr = + (SET_NAP(nap) or SET_SAP(sap)) + +const + COD_FORMAT_BIT_OFFSET* = (0) + COD_MINOR_BIT_OFFSET* = (2) + COD_MAJOR_BIT_OFFSET* = (8 * 1) + COD_SERVICE_BIT_OFFSET* = (8 * 1 + 5) + COD_FORMAT_MASK* = (0x00000003) + COD_MINOR_MASK* = (0x000000FC) + COD_MAJOR_MASK* = (0x00001F00) + COD_SERVICE_MASK* = (0x00FFE000) +template GET_COD_FORMAT*(cod: expr): expr = + ((cod) and COD_FORMAT_MASK shr COD_FORMAT_BIT_OFFSET) + +template GET_COD_MINOR*(cod: expr): expr = + (((cod) and COD_MINOR_MASK) shr COD_MINOR_BIT_OFFSET) + +template GET_COD_MAJOR*(cod: expr): expr = + (((cod) and COD_MAJOR_MASK) shr COD_MAJOR_BIT_OFFSET) + +template GET_COD_SERVICE*(cod: expr): expr = + (((cod) and COD_SERVICE_MASK) shr COD_SERVICE_BIT_OFFSET) + +template SET_COD_MINOR*(cod, minor: expr): expr = + (cod) = ((cod) and not COD_MINOR_MASK) or + ((minor) shl COD_MINOR_BIT_OFFSET) + +template SET_COD_MAJOR*(cod, major: expr): expr = + (cod) = ((cod) and not COD_MAJOR_MASK) or + ((major) shl COD_MAJOR_BIT_OFFSET) + +template SET_COD_SERVICE*(cod, service: expr): expr = + (cod) = ((cod) and not COD_SERVICE_MASK) or + ((service) shl COD_SERVICE_BIT_OFFSET) + +const + COD_VERSION* = (0x00000000) + COD_SERVICE_LIMITED* = (0x00000001) + COD_SERVICE_POSITIONING* = (0x00000008) + COD_SERVICE_NETWORKING* = (0x00000010) + COD_SERVICE_RENDERING* = (0x00000020) + COD_SERVICE_CAPTURING* = (0x00000040) + COD_SERVICE_OBJECT_XFER* = (0x00000080) + COD_SERVICE_AUDIO* = (0x00000100) + COD_SERVICE_TELEPHONY* = (0x00000200) + COD_SERVICE_INFORMATION* = (0x00000400) + COD_SERVICE_VALID_MASK* = (COD_SERVICE_LIMITED or + COD_SERVICE_POSITIONING or COD_SERVICE_NETWORKING or + COD_SERVICE_RENDERING or COD_SERVICE_CAPTURING or + COD_SERVICE_OBJECT_XFER or COD_SERVICE_AUDIO or + COD_SERVICE_TELEPHONY or COD_SERVICE_INFORMATION) + COD_SERVICE_MAX_COUNT* = (9) +# +# Major class codes +# +const + COD_MAJOR_MISCELLANEOUS* = (0x00000000) + COD_MAJOR_COMPUTER* = (0x00000001) + COD_MAJOR_PHONE* = (0x00000002) + COD_MAJOR_LAN_ACCESS* = (0x00000003) + COD_MAJOR_AUDIO* = (0x00000004) + COD_MAJOR_PERIPHERAL* = (0x00000005) + COD_MAJOR_IMAGING* = (0x00000006) + COD_MAJOR_WEARABLE* = (0x00000007) + COD_MAJOR_TOY* = (0x00000008) + COD_MAJOR_HEALTH* = (0x00000009) + COD_MAJOR_UNCLASSIFIED* = (0x0000001F) +# +# Minor class codes specific to each major class +# +const + COD_COMPUTER_MINOR_UNCLASSIFIED* = (0x00000000) + COD_COMPUTER_MINOR_DESKTOP* = (0x00000001) + COD_COMPUTER_MINOR_SERVER* = (0x00000002) + COD_COMPUTER_MINOR_LAPTOP* = (0x00000003) + COD_COMPUTER_MINOR_HANDHELD* = (0x00000004) + COD_COMPUTER_MINOR_PALM* = (0x00000005) + COD_COMPUTER_MINOR_WEARABLE* = (0x00000006) + COD_PHONE_MINOR_UNCLASSIFIED* = (0x00000000) + COD_PHONE_MINOR_CELLULAR* = (0x00000001) + COD_PHONE_MINOR_CORDLESS* = (0x00000002) + COD_PHONE_MINOR_SMART* = (0x00000003) + COD_PHONE_MINOR_WIRED_MODEM* = (0x00000004) + COD_AUDIO_MINOR_UNCLASSIFIED* = (0x00000000) + COD_AUDIO_MINOR_HEADSET* = (0x00000001) + COD_AUDIO_MINOR_HANDS_FREE* = (0x00000002) + COD_AUDIO_MINOR_HEADSET_HANDS_FREE* = (0x00000003) + COD_AUDIO_MINOR_MICROPHONE* = (0x00000004) + COD_AUDIO_MINOR_LOUDSPEAKER* = (0x00000005) + COD_AUDIO_MINOR_HEADPHONES* = (0x00000006) + COD_AUDIO_MINOR_PORTABLE_AUDIO* = (0x00000007) + COD_AUDIO_MINOR_CAR_AUDIO* = (0x00000008) + COD_AUDIO_MINOR_SET_TOP_BOX* = (0x00000009) + COD_AUDIO_MINOR_HIFI_AUDIO* = (0x0000000A) + COD_AUDIO_MINOR_VCR* = (0x0000000B) + COD_AUDIO_MINOR_VIDEO_CAMERA* = (0x0000000C) + COD_AUDIO_MINOR_CAMCORDER* = (0x0000000D) + COD_AUDIO_MINOR_VIDEO_MONITOR* = (0x0000000E) + COD_AUDIO_MINOR_VIDEO_DISPLAY_LOUDSPEAKER* = (0x0000000F) + COD_AUDIO_MINOR_VIDEO_DISPLAY_CONFERENCING* = (0x00000010) +# #define COD_AUDIO_MINOR_RESERVED (0x11) +const + COD_AUDIO_MINOR_GAMING_TOY* = (0x00000012) + COD_PERIPHERAL_MINOR_KEYBOARD_MASK* = (0x00000010) + COD_PERIPHERAL_MINOR_POINTER_MASK* = (0x00000020) + COD_PERIPHERAL_MINOR_NO_CATEGORY* = (0x00000000) + COD_PERIPHERAL_MINOR_JOYSTICK* = (0x00000001) + COD_PERIPHERAL_MINOR_GAMEPAD* = (0x00000002) + COD_PERIPHERAL_MINOR_REMOTE_CONTROL* = (0x00000003) + COD_PERIPHERAL_MINOR_SENSING* = (0x00000004) + COD_IMAGING_MINOR_DISPLAY_MASK* = (0x00000004) + COD_IMAGING_MINOR_CAMERA_MASK* = (0x00000008) + COD_IMAGING_MINOR_SCANNER_MASK* = (0x00000010) + COD_IMAGING_MINOR_PRINTER_MASK* = (0x00000020) + COD_WEARABLE_MINOR_WRIST_WATCH* = (0x00000001) + COD_WEARABLE_MINOR_PAGER* = (0x00000002) + COD_WEARABLE_MINOR_JACKET* = (0x00000003) + COD_WEARABLE_MINOR_HELMET* = (0x00000004) + COD_WEARABLE_MINOR_GLASSES* = (0x00000005) + COD_TOY_MINOR_ROBOT* = (0x00000001) + COD_TOY_MINOR_VEHICLE* = (0x00000002) + COD_TOY_MINOR_DOLL_ACTION_FIGURE* = (0x00000003) + COD_TOY_MINOR_CONTROLLER* = (0x00000004) + COD_TOY_MINOR_GAME* = (0x00000005) + COD_HEALTH_MINOR_BLOOD_PRESSURE_MONITOR* = (0x00000001) + COD_HEALTH_MINOR_THERMOMETER* = (0x00000002) + COD_HEALTH_MINOR_WEIGHING_SCALE* = (0x00000003) + COD_HEALTH_MINOR_GLUCOSE_METER* = (0x00000004) + COD_HEALTH_MINOR_PULSE_OXIMETER* = (0x00000005) + COD_HEALTH_MINOR_HEART_PULSE_MONITOR* = (0x00000006) + COD_HEALTH_MINOR_HEALTH_DATA_DISPLAY* = (0x00000007) + COD_HEALTH_MINOR_STEP_COUNTER* = (0x00000008) +# +# Cannot use GET_COD_MINOR for this b/c it is embedded in a different manner +# than the rest of the major classes +# +const + COD_LAN_ACCESS_BIT_OFFSET* = (5) + COD_LAN_MINOR_MASK* = (0x0000001C) + COD_LAN_ACCESS_MASK* = (0x000000E0) +template GET_COD_LAN_MINOR*(cod: expr): expr = + (((cod) and COD_LAN_MINOR_MASK) shr COD_MINOR_BIT_OFFSET) + +template GET_COD_LAN_ACCESS*(cod: expr): expr = + (((cod) and COD_LAN_ACCESS_MASK) shr COD_LAN_ACCESS_BIT_OFFSET) + +# +# LAN access percent usage subcodes +# +const + COD_LAN_MINOR_UNCLASSIFIED* = (0x00000000) + COD_LAN_ACCESS_0_USED* = (0x00000000) + COD_LAN_ACCESS_17_USED* = (0x00000001) + COD_LAN_ACCESS_33_USED* = (0x00000002) + COD_LAN_ACCESS_50_USED* = (0x00000003) + COD_LAN_ACCESS_67_USED* = (0x00000004) + COD_LAN_ACCESS_83_USED* = (0x00000005) + COD_LAN_ACCESS_99_USED* = (0x00000006) + COD_LAN_ACCESS_FULL* = (0x00000007) +# +# Extended Inquiry Response (EIR) defines. +# +const + BTH_EIR_FLAGS_ID* = (0x00000001) + BTH_EIR_16_UUIDS_PARTIAL_ID* = (0x00000002) + BTH_EIR_16_UUIDS_COMPLETE_ID* = (0x00000003) + BTH_EIR_32_UUIDS_PARTIAL_ID* = (0x00000004) + BTH_EIR_32_UUIDS_COMPLETE_ID* = (0x00000005) + BTH_EIR_128_UUIDS_PARTIAL_ID* = (0x00000006) + BTH_EIR_128_UUIDS_COMPLETE_ID* = (0x00000007) + BTH_EIR_LOCAL_NAME_PARTIAL_ID* = (0x00000008) + BTH_EIR_LOCAL_NAME_COMPLETE_ID* = (0x00000009) + BTH_EIR_TX_POWER_LEVEL_ID* = (0x0000000A) + BTH_EIR_OOB_OPT_DATA_LEN_ID* = (0x0000000B) # OOB only. + BTH_EIR_OOB_BD_ADDR_ID* = (0x0000000C) # OOB only. + BTH_EIR_OOB_COD_ID* = (0x0000000D) # OOB only. + BTH_EIR_OOB_SP_HASH_ID* = (0x0000000E) # OOB only. + BTH_EIR_OOB_SP_RANDOMIZER_ID* = (0x0000000F) # OOB only. + BTH_EIR_MANUFACTURER_ID* = (0x000000FF) +# +# Extended Inquiry Response (EIR) size. +# +const + BTH_EIR_SIZE* = (240) +# +# General Inquiry Access Code. +# +const + LAP_GIAC_VALUE* = (0x009E8B33) +# +# Limited Inquiry Access Code. +# +const + LAP_LIAC_VALUE* = (0x009E8B00) + BTH_ADDR_IAC_FIRST* = (0x009E8B00) + BTH_ADDR_IAC_LAST* = (0x009E8B3F) + BTH_ADDR_LIAC* = (0x009E8B00) + BTH_ADDR_GIAC* = (0x009E8B33) +template BTH_ERROR*(btStatus: expr): expr = + ((btStatus) != BTH_ERROR_SUCCESS) + +template BTH_SUCCESS*(btStatus: expr): expr = + ((btStatus) == BTH_ERROR_SUCCESS) + +const + BTH_ERROR_SUCCESS* = (0x00000000) + BTH_ERROR_UNKNOWN_HCI_COMMAND* = (0x00000001) + BTH_ERROR_NO_CONNECTION* = (0x00000002) + BTH_ERROR_HARDWARE_FAILURE* = (0x00000003) + BTH_ERROR_PAGE_TIMEOUT* = (0x00000004) + BTH_ERROR_AUTHENTICATION_FAILURE* = (0x00000005) + BTH_ERROR_KEY_MISSING* = (0x00000006) + BTH_ERROR_MEMORY_FULL* = (0x00000007) + BTH_ERROR_CONNECTION_TIMEOUT* = (0x00000008) + BTH_ERROR_MAX_NUMBER_OF_CONNECTIONS* = (0x00000009) + BTH_ERROR_MAX_NUMBER_OF_SCO_CONNECTIONS* = (0x0000000A) + BTH_ERROR_ACL_CONNECTION_ALREADY_EXISTS* = (0x0000000B) + BTH_ERROR_COMMAND_DISALLOWED* = (0x0000000C) + BTH_ERROR_HOST_REJECTED_LIMITED_RESOURCES* = (0x0000000D) + BTH_ERROR_HOST_REJECTED_SECURITY_REASONS* = (0x0000000E) + BTH_ERROR_HOST_REJECTED_PERSONAL_DEVICE* = (0x0000000F) + BTH_ERROR_HOST_TIMEOUT* = (0x00000010) + BTH_ERROR_UNSUPPORTED_FEATURE_OR_PARAMETER* = (0x00000011) + BTH_ERROR_INVALID_HCI_PARAMETER* = (0x00000012) + BTH_ERROR_REMOTE_USER_ENDED_CONNECTION* = (0x00000013) + BTH_ERROR_REMOTE_LOW_RESOURCES* = (0x00000014) + BTH_ERROR_REMOTE_POWERING_OFF* = (0x00000015) + BTH_ERROR_LOCAL_HOST_TERMINATED_CONNECTION* = (0x00000016) + BTH_ERROR_REPEATED_ATTEMPTS* = (0x00000017) + BTH_ERROR_PAIRING_NOT_ALLOWED* = (0x00000018) + BTH_ERROR_UKNOWN_LMP_PDU* = (0x00000019) + BTH_ERROR_UNSUPPORTED_REMOTE_FEATURE* = (0x0000001A) + BTH_ERROR_SCO_OFFSET_REJECTED* = (0x0000001B) + BTH_ERROR_SCO_INTERVAL_REJECTED* = (0x0000001C) + BTH_ERROR_SCO_AIRMODE_REJECTED* = (0x0000001D) + BTH_ERROR_INVALID_LMP_PARAMETERS* = (0x0000001E) + BTH_ERROR_UNSPECIFIED_ERROR* = (0x0000001F) + BTH_ERROR_UNSUPPORTED_LMP_PARM_VALUE* = (0x00000020) + BTH_ERROR_ROLE_CHANGE_NOT_ALLOWED* = (0x00000021) + BTH_ERROR_LMP_RESPONSE_TIMEOUT* = (0x00000022) + BTH_ERROR_LMP_TRANSACTION_COLLISION* = (0x00000023) + BTH_ERROR_LMP_PDU_NOT_ALLOWED* = (0x00000024) + BTH_ERROR_ENCRYPTION_MODE_NOT_ACCEPTABLE* = (0x00000025) + BTH_ERROR_UNIT_KEY_NOT_USED* = (0x00000026) + BTH_ERROR_QOS_IS_NOT_SUPPORTED* = (0x00000027) + BTH_ERROR_INSTANT_PASSED* = (0x00000028) + BTH_ERROR_PAIRING_WITH_UNIT_KEY_NOT_SUPPORTED* = (0x00000029) + BTH_ERROR_DIFFERENT_TRANSACTION_COLLISION* = (0x0000002A) + BTH_ERROR_QOS_UNACCEPTABLE_PARAMETER* = (0x0000002C) + BTH_ERROR_QOS_REJECTED* = (0x0000002D) + BTH_ERROR_CHANNEL_CLASSIFICATION_NOT_SUPPORTED* = (0x0000002E) + BTH_ERROR_INSUFFICIENT_SECURITY* = (0x0000002F) + BTH_ERROR_PARAMETER_OUT_OF_MANDATORY_RANGE* = (0x00000030) + BTH_ERROR_ROLE_SWITCH_PENDING* = (0x00000032) + BTH_ERROR_RESERVED_SLOT_VIOLATION* = (0x00000034) + BTH_ERROR_ROLE_SWITCH_FAILED* = (0x00000035) + BTH_ERROR_EXTENDED_INQUIRY_RESPONSE_TOO_LARGE* = (0x00000036) + BTH_ERROR_SECURE_SIMPLE_PAIRING_NOT_SUPPORTED_BY_HOST* = (0x00000037) + BTH_ERROR_HOST_BUSY_PAIRING* = (0x00000038) + BTH_ERROR_CONNECTION_REJECTED_DUE_TO_NO_SUITABLE_CHANNEL_FOUND* = ( + 0x00000039) + BTH_ERROR_CONTROLLER_BUSY* = (0x0000003A) + BTH_ERROR_UNACCEPTABLE_CONNECTION_INTERVAL* = (0x0000003B) + BTH_ERROR_DIRECTED_ADVERTISING_TIMEOUT* = (0x0000003C) + BTH_ERROR_CONNECTION_TERMINATED_DUE_TO_MIC_FAILURE* = (0x0000003D) + BTH_ERROR_CONNECTION_FAILED_TO_BE_ESTABLISHED* = (0x0000003E) + BTH_ERROR_MAC_CONNECTION_FAILED* = (0x0000003F) + BTH_ERROR_UNSPECIFIED* = (0x000000FF) +# +# Min, max, and default L2cap MTU. +# +const + L2CAP_MIN_MTU* = (48) + L2CAP_MAX_MTU* = (0x0000FFFF) + L2CAP_DEFAULT_MTU* = (672) +# +# Max l2cap signal size (48) - size of signal header (4) +# +const + MAX_L2CAP_PING_DATA_LENGTH* = (44) + MAX_L2CAP_INFO_DATA_LENGTH* = (44) +# +# the following structures provide information about +# disocvered remote radios. +# +const + BDIF_ADDRESS* = (0x00000001) + BDIF_COD* = (0x00000002) + BDIF_NAME* = (0x00000004) + BDIF_PAIRED* = (0x00000008) + BDIF_PERSONAL* = (0x00000010) + BDIF_CONNECTED* = (0x00000020) +# +# Support added in KB942567 +# +const + BDIF_SHORT_NAME* = (0x00000040) + BDIF_VISIBLE* = (0x00000080) + BDIF_SSP_SUPPORTED* = (0x00000100) + BDIF_SSP_PAIRED* = (0x00000200) + BDIF_SSP_MITM_PROTECTED* = (0x00000400) + BDIF_RSSI* = (0x00001000) + BDIF_EIR* = (0x00002000) + +const + BDIF_BR* = (0x00004000) + BDIF_LE* = (0x00008000) + BDIF_LE_PAIRED* = (0x00010000) + BDIF_LE_PERSONAL* = (0x00020000) + BDIF_LE_MITM_PROTECTED* = (0x00040000) + BDIF_LE_PRIVACY_ENABLED* = (0x00080000) + BDIF_LE_RANDOM_ADDRESS_TYPE* = (0x00100000) + BDIF_VALID_FLAGS* = (BDIF_ADDRESS or BDIF_COD or BDIF_NAME or + BDIF_PAIRED or BDIF_PERSONAL or BDIF_CONNECTED or + BDIF_SHORT_NAME or BDIF_VISIBLE or BDIF_RSSI or BDIF_EIR or + BDIF_SSP_PAIRED or BDIF_SSP_MITM_PROTECTED or BDIF_BR or + BDIF_LE or BDIF_LE_PAIRED or BDIF_LE_PERSONAL or + BDIF_LE_MITM_PROTECTED or BDIF_LE_PRIVACY_ENABLED or + BDIF_LE_RANDOM_ADDRESS_TYPE) + +type + BTH_DEVICE_INFO* = object + flags*: ULONG # + # Combination BDIF_Xxx flags + # + # + # Address of remote device. + # + address*: BTH_ADDR # + # Class Of Device. + # + classOfDevice*: BTH_COD # + # name of the device + # + name*: array[BTH_MAX_NAME_SIZE, CHAR] + + PBTH_DEVICE_INFO* = ptr BTH_DEVICE_INFO +# +# Buffer associated with GUID_BLUETOOTH_RADIO_IN_RANGE +# +type + BTH_RADIO_IN_RANGE* = object + deviceInfo*: BTH_DEVICE_INFO # + # Information about the remote radio + # + # + # The previous flags value for the BTH_DEVICE_INFO. The receiver of this + # notification can compare the deviceInfo.flags and previousDeviceFlags + # to determine what has changed about this remote radio. + # + # For instance, if BDIF_NAME is set in deviceInfo.flags and not in + # previousDeviceFlags, the remote radio's has just been retrieved. + # + previousDeviceFlags*: ULONG + + PBTH_RADIO_IN_RANGE* = ptr BTH_RADIO_IN_RANGE +# +# Buffer associated with GUID_BLUETOOTH_L2CAP_EVENT +# +type + BTH_L2CAP_EVENT_INFO* = object + bthAddress*: BTH_ADDR # + # Remote radio address which the L2CAP event is associated with + # + # + # The PSM that is either being connected to or disconnected from + # + psm*: USHORT # + # If != 0, then the channel has just been established. If == 0, then the + # channel has been destroyed. Notifications for a destroyed channel will + # only be sent for channels successfully established. + # + connected*: UCHAR # + # If != 0, then the local host iniated the l2cap connection. If == 0, then + # the remote host initated the connection. This field is only valid if + # connect is != 0. + # + initiated*: UCHAR + + PBTH_L2CAP_EVENT_INFO* = ptr BTH_L2CAP_EVENT_INFO +const + HCI_CONNECTION_TYPE_ACL* = (1) + HCI_CONNECTION_TYPE_SCO* = (2) + HCI_CONNECTION_TYPE_LE* = (3) +# +# Fix typos +# +const + HCI_CONNNECTION_TYPE_ACL* = HCI_CONNECTION_TYPE_ACL + HCI_CONNNECTION_TYPE_SCO* = HCI_CONNECTION_TYPE_SCO +# +# Buffer associated with GUID_BLUETOOTH_HCI_EVENT +# +type + BTH_HCI_EVENT_INFO* = object + bthAddress*: BTH_ADDR # + # Remote radio address which the HCI event is associated with + # + # + # HCI_CONNNECTION_TYPE_XXX value + # + connectionType*: UCHAR # + # If != 0, then the underlying connection to the remote radio has just + # been estrablished. If == 0, then the underlying conneciton has just been + # destroyed. + # + connected*: UCHAR + + PBTH_HCI_EVENT_INFO* = ptr BTH_HCI_EVENT_INFO +# +# Support added in KB942567 +# +type + IO_CAPABILITY* {.size: sizeof(cint).} = enum + IoCaps_DisplayOnly = 0x00000000, IoCaps_DisplayYesNo = 0x00000001, + IoCaps_KeyboardOnly = 0x00000002, + IoCaps_NoInputNoOutput = 0x00000003, IoCaps_Undefined = 0x000000FF + AUTHENTICATION_REQUIREMENTS* {.size: sizeof(cint).} = enum + MITMProtectionNotRequired = 0x00000000, + MITMProtectionRequired = 0x00000001, + MITMProtectionNotRequiredBonding = 0x00000002, + MITMProtectionRequiredBonding = 0x00000003, + MITMProtectionNotRequiredGeneralBonding = 0x00000004, + MITMProtectionRequiredGeneralBonding = 0x00000005, + MITMProtectionNotDefined = 0x000000FF +template IsMITMProtectionRequired*(requirements: expr): expr = + ((MITMProtectionRequired == requirements) or + (MITMProtectionRequiredBonding == requirements) or + (MITMProtectionRequiredGeneralBonding == requirements)) + +# +# Max length we allow for ServiceName in the remote SDP records +# +const + BTH_MAX_SERVICE_NAME_SIZE* = (256) + MAX_UUIDS_IN_QUERY* = (12) + BTH_VID_DEFAULT_VALUE* = (0x0000FFFF) + SDP_ERROR_INVALID_SDP_VERSION* = (0x00000001) + SDP_ERROR_INVALID_RECORD_HANDLE* = (0x00000002) + SDP_ERROR_INVALID_REQUEST_SYNTAX* = (0x00000003) + SDP_ERROR_INVALID_PDU_SIZE* = (0x00000004) + SDP_ERROR_INVALID_CONTINUATION_STATE* = (0x00000005) + SDP_ERROR_INSUFFICIENT_RESOURCES* = (0x00000006) +# +# Defined by windows to handle server errors that are not described by the +# above errors. Start at 0x0100 so we don't go anywhere near the spec +# defined values. +# +# +# Success, nothing went wrong +# +const + SDP_ERROR_SUCCESS* = SDP_ERROR(0x00000000) +# +# The SDP PDU or parameters other than the SDP stream response was not correct +# +const + SDP_ERROR_SERVER_INVALID_RESPONSE* = SDP_ERROR(0x00000100) +# +# The SDP response stream did not parse correctly. +# +const + SDP_ERROR_SERVER_RESPONSE_DID_NOT_PARSE* = SDP_ERROR(0x00000200) +# +# The SDP response stream was successfully parsed, but did not match the +# required format for the query. +# +const + SDP_ERROR_SERVER_BAD_FORMAT* = SDP_ERROR(0x00000300) +# +# SDP was unable to send a continued query back to the server +# +const + SDP_ERROR_COULD_NOT_SEND_CONTINUE* = SDP_ERROR(0x00000400) +# +# Server sent a response that was too large to fit in the caller's buffer. +# +const + SDP_ERROR_RESPONSE_TOO_LARGE* = SDP_ERROR(0x00000500) + SDP_ATTRIB_RECORD_HANDLE* = (0x00000000) + SDP_ATTRIB_CLASS_ID_LIST* = (0x00000001) + SDP_ATTRIB_RECORD_STATE* = (0x00000002) + SDP_ATTRIB_SERVICE_ID* = (0x00000003) + SDP_ATTRIB_PROTOCOL_DESCRIPTOR_LIST* = (0x00000004) + SDP_ATTRIB_BROWSE_GROUP_LIST* = (0x00000005) + SDP_ATTRIB_LANG_BASE_ATTRIB_ID_LIST* = (0x00000006) + SDP_ATTRIB_INFO_TIME_TO_LIVE* = (0x00000007) + SDP_ATTRIB_AVAILABILITY* = (0x00000008) + SDP_ATTRIB_PROFILE_DESCRIPTOR_LIST* = (0x00000009) + SDP_ATTRIB_DOCUMENTATION_URL* = (0x0000000A) + SDP_ATTRIB_CLIENT_EXECUTABLE_URL* = (0x0000000B) + SDP_ATTRIB_ICON_URL* = (0x0000000C) + SDP_ATTRIB_ADDITIONAL_PROTOCOL_DESCRIPTOR_LIST* = (0x0000000D) +# +# Attribute IDs in the range of 0x000D - 0x01FF are reserved for future use +# +const + SDP_ATTRIB_PROFILE_SPECIFIC* = (0x00000200) + LANG_BASE_LANGUAGE_INDEX* = (0x00000000) + LANG_BASE_ENCODING_INDEX* = (0x00000001) + LANG_BASE_OFFSET_INDEX* = (0x00000002) + LANG_DEFAULT_ID* = (0x00000100) + LANGUAGE_EN_US* = (0x0000656E) + ENCODING_UTF_8* = (0x0000006A) + STRING_NAME_OFFSET* = (0x00000000) + STRING_DESCRIPTION_OFFSET* = (0x00000001) + STRING_PROVIDER_NAME_OFFSET* = (0x00000002) + SDP_ATTRIB_SDP_VERSION_NUMBER_LIST* = (0x00000200) + SDP_ATTRIB_SDP_DATABASE_STATE* = (0x00000201) + SDP_ATTRIB_BROWSE_GROUP_ID* = (0x00000200) + SDP_ATTRIB_CORDLESS_EXTERNAL_NETWORK* = (0x00000301) + SDP_ATTRIB_FAX_CLASS_1_SUPPORT* = (0x00000302) + SDP_ATTRIB_FAX_CLASS_2_0_SUPPORT* = (0x00000303) + SDP_ATTRIB_FAX_CLASS_2_SUPPORT* = (0x00000304) + SDP_ATTRIB_FAX_AUDIO_FEEDBACK_SUPPORT* = (0x00000305) + SDP_ATTRIB_HEADSET_REMOTE_AUDIO_VOLUME_CONTROL* = (0x00000302) + SDP_ATTRIB_LAN_LPSUBNET* = (0x00000200) + SDP_ATTRIB_OBJECT_PUSH_SUPPORTED_FORMATS_LIST* = (0x00000303) + SDP_ATTRIB_SYNCH_SUPPORTED_DATA_STORES_LIST* = (0x00000301) +# this is in the assigned numbers doc, but it does not show up in any profile +const + SDP_ATTRIB_SERVICE_VERSION* = (0x00000300) + SDP_ATTRIB_PAN_NETWORK_ADDRESS* = (0x00000306) + SDP_ATTRIB_PAN_WAP_GATEWAY* = (0x00000307) + SDP_ATTRIB_PAN_HOME_PAGE_URL* = (0x00000308) + SDP_ATTRIB_PAN_WAP_STACK_TYPE* = (0x00000309) + SDP_ATTRIB_PAN_SECURITY_DESCRIPTION* = (0x0000030A) + SDP_ATTRIB_PAN_NET_ACCESS_TYPE* = (0x0000030B) + SDP_ATTRIB_PAN_MAX_NET_ACCESS_RATE* = (0x0000030C) + SDP_ATTRIB_IMAGING_SUPPORTED_CAPABILITIES* = (0x00000310) + SDP_ATTRIB_IMAGING_SUPPORTED_FEATURES* = (0x00000311) + SDP_ATTRIB_IMAGING_SUPPORTED_FUNCTIONS* = (0x00000312) + SDP_ATTRIB_IMAGING_TOTAL_DATA_CAPACITY* = (0x00000313) + SDP_ATTRIB_DI_SPECIFICATION_ID* = (0x00000200) + SDP_ATTRIB_DI_VENDOR_ID* = (0x00000201) + SDP_ATTRIB_DI_PRODUCT_ID* = (0x00000202) + SDP_ATTRIB_DI_VERSION* = (0x00000203) + SDP_ATTRIB_DI_PRIMARY_RECORD* = (0x00000204) + SDP_ATTRIB_DI_VENDOR_ID_SOURCE* = (0x00000205) + SDP_ATTRIB_HID_DEVICE_RELEASE_NUMBER* = (0x00000200) + SDP_ATTRIB_HID_PARSER_VERSION* = (0x00000201) + SDP_ATTRIB_HID_DEVICE_SUBCLASS* = (0x00000202) + SDP_ATTRIB_HID_COUNTRY_CODE* = (0x00000203) + SDP_ATTRIB_HID_VIRTUAL_CABLE* = (0x00000204) + SDP_ATTRIB_HID_RECONNECT_INITIATE* = (0x00000205) + SDP_ATTRIB_HID_DESCRIPTOR_LIST* = (0x00000206) + SDP_ATTRIB_HID_LANG_ID_BASE_LIST* = (0x00000207) + SDP_ATTRIB_HID_SDP_DISABLE* = (0x00000208) + SDP_ATTRIB_HID_BATTERY_POWER* = (0x00000209) + SDP_ATTRIB_HID_REMOTE_WAKE* = (0x0000020A) + SDP_ATTRIB_HID_PROFILE_VERSION* = (0x0000020B) + SDP_ATTRIB_HID_SUPERVISION_TIMEOUT* = (0x0000020C) + SDP_ATTRIB_HID_NORMALLY_CONNECTABLE* = (0x0000020D) + SDP_ATTRIB_HID_BOOT_DEVICE* = (0x0000020E) + SDP_ATTRIB_HID_SSR_HOST_MAX_LATENCY* = (0x0000020F) + SDP_ATTRIB_HID_SSR_HOST_MIN_TIMEOUT* = (0x00000210) +# +# Profile specific values +# +const + CORDLESS_EXTERNAL_NETWORK_PSTN* = (0x00000001) + CORDLESS_EXTERNAL_NETWORK_ISDN* = (0x00000002) + CORDLESS_EXTERNAL_NETWORK_GSM* = (0x00000003) + CORDLESS_EXTERNAL_NETWORK_CDMA* = (0x00000004) + CORDLESS_EXTERNAL_NETWORK_ANALOG_CELLULAR* = (0x00000005) + CORDLESS_EXTERNAL_NETWORK_PACKET_SWITCHED* = (0x00000006) + CORDLESS_EXTERNAL_NETWORK_OTHER* = (0x00000007) + OBJECT_PUSH_FORMAT_VCARD_2_1* = (0x00000001) + OBJECT_PUSH_FORMAT_VCARD_3_0* = (0x00000002) + OBJECT_PUSH_FORMAT_VCAL_1_0* = (0x00000003) + OBJECT_PUSH_FORMAT_ICAL_2_0* = (0x00000004) + OBJECT_PUSH_FORMAT_VNOTE* = (0x00000005) + OBJECT_PUSH_FORMAT_VMESSAGE* = (0x00000006) + OBJECT_PUSH_FORMAT_ANY* = (0x000000FF) + SYNCH_DATA_STORE_PHONEBOOK* = (0x00000001) + SYNCH_DATA_STORE_CALENDAR* = (0x00000003) + SYNCH_DATA_STORE_NOTES* = (0x00000005) + SYNCH_DATA_STORE_MESSAGES* = (0x00000006) + DI_VENDOR_ID_SOURCE_BLUETOOTH_SIG* = (0x00000001) + DI_VENDOR_ID_SOURCE_USB_IF* = (0x00000002) + PSM_SDP* = (0x00000001) + PSM_RFCOMM* = (0x00000003) + PSM_TCS_BIN* = (0x00000005) + PSM_TCS_BIN_CORDLESS* = (0x00000007) + PSM_BNEP* = (0x0000000F) + PSM_HID_CONTROL* = (0x00000011) + PSM_HID_INTERRUPT* = (0x00000013) + PSM_AVCTP* = (0x00000017) + PSM_AVDTP* = (0x00000019) + PSM_UDI_C_PLANE* = (0x0000001D) +# +# Strings +# +const + STR_ADDR_FMTA* = "(%02x:%02x:%02x:%02x:%02x:%02x)" +const + STR_ADDR_SHORT_FMTA* = "%04x%08x" +const + STR_USBHCI_CLASS_HARDWAREIDA* = "USB\x08Class_E0&SubClass_01&Prot_01" +when defined(UNICODE) or defined(BTH_KERN): + const + STR_ADDR_FMT* = STR_ADDR_FMTW + STR_ADDR_SHORT_FMT* = STR_ADDR_SHORT_FMTW + STR_USBHCI_CLASS_HARDWAREID* = STR_USBHCI_CLASS_HARDWAREIDW +else: + const + STR_ADDR_FMT* = STR_ADDR_FMTA + STR_ADDR_SHORT_FMT* = STR_ADDR_SHORT_FMTA + STR_USBHCI_CLASS_HARDWAREID* = STR_USBHCI_CLASS_HARDWAREIDA + +template GET_BITS*(field, offset, mask: expr): expr = + (((field) shr (offset)) and (mask)) + +template GET_BIT*(field, offset: expr): expr = + (GET_BITS(field, offset, 0x00000001)) + +template LMP_3_SLOT_PACKETS*(x: expr): expr = + (GET_BIT(x, 0)) + +template LMP_5_SLOT_PACKETS*(x: expr): expr = + (GET_BIT(x, 1)) + +template LMP_ENCRYPTION*(x: expr): expr = + (GET_BIT(x, 2)) + +template LMP_SLOT_OFFSET*(x: expr): expr = + (GET_BIT(x, 3)) + +template LMP_TIMING_ACCURACY*(x: expr): expr = + (GET_BIT(x, 4)) + +template LMP_SWITCH*(x: expr): expr = + (GET_BIT(x, 5)) + +template LMP_HOLD_MODE*(x: expr): expr = + (GET_BIT(x, 6)) + +template LMP_SNIFF_MODE*(x: expr): expr = + (GET_BIT(x, 7)) + +template LMP_PARK_MODE*(x: expr): expr = + (GET_BIT(x, 8)) + +template LMP_RSSI*(x: expr): expr = + (GET_BIT(x, 9)) + +template LMP_CHANNEL_QUALITY_DRIVEN_MODE*(x: expr): expr = + (GET_BIT(x, 10)) + +template LMP_SCO_LINK*(x: expr): expr = + (GET_BIT(x, 11)) + +template LMP_HV2_PACKETS*(x: expr): expr = + (GET_BIT(x, 12)) + +template LMP_HV3_PACKETS*(x: expr): expr = + (GET_BIT(x, 13)) + +template LMP_MU_LAW_LOG*(x: expr): expr = + (GET_BIT(x, 14)) + +template LMP_A_LAW_LOG*(x: expr): expr = + (GET_BIT(x, 15)) + +template LMP_CVSD*(x: expr): expr = + (GET_BIT(x, 16)) + +template LMP_PAGING_SCHEME*(x: expr): expr = + (GET_BIT(x, 17)) + +template LMP_POWER_CONTROL*(x: expr): expr = + (GET_BIT(x, 18)) + +template LMP_TRANSPARENT_SCO_DATA*(x: expr): expr = + (GET_BIT(x, 19)) + +template LMP_FLOW_CONTROL_LAG*(x: expr): expr = + (GET_BITS(x, 20, 0x00000003)) + +template LMP_BROADCAST_ENCRYPTION*(x: expr): expr = + (GET_BIT(x, 23)) + +template LMP_ENHANCED_DATA_RATE_ACL_2MBPS_MODE*(x: expr): expr = + (GET_BIT(x, 25)) + +template LMP_ENHANCED_DATA_RATE_ACL_3MBPS_MODE*(x: expr): expr = + (GET_BIT(x, 26)) + +template LMP_ENHANCED_INQUIRY_SCAN*(x: expr): expr = + (GET_BIT(x, 27)) + +template LMP_INTERLACED_INQUIRY_SCAN*(x: expr): expr = + (GET_BIT(x, 28)) + +template LMP_INTERLACED_PAGE_SCAN*(x: expr): expr = + (GET_BIT(x, 29)) + +template LMP_RSSI_WITH_INQUIRY_RESULTS*(x: expr): expr = + (GET_BIT(x, 30)) + +template LMP_ESCO_LINK*(x: expr): expr = + (GET_BIT(x, 31)) + +template LMP_EV4_PACKETS*(x: expr): expr = + (GET_BIT(x, 32)) + +template LMP_EV5_PACKETS*(x: expr): expr = + (GET_BIT(x, 33)) + +template LMP_AFH_CAPABLE_SLAVE*(x: expr): expr = + (GET_BIT(x, 35)) + +template LMP_AFH_CLASSIFICATION_SLAVE*(x: expr): expr = + (GET_BIT(x, 36)) + +template LMP_BR_EDR_NOT_SUPPORTED*(x: expr): expr = + (GET_BIT(x, 37)) + +template LMP_LE_SUPPORTED*(x: expr): expr = + (GET_BIT(x, 38)) + +template LMP_3SLOT_EDR_ACL_PACKETS*(x: expr): expr = + (GET_BIT(x, 39)) + +template LMP_5SLOT_EDR_ACL_PACKETS*(x: expr): expr = + (GET_BIT(x, 40)) + +template LMP_SNIFF_SUBRATING*(x: expr): expr = + (GET_BIT(x, 41)) + +template LMP_PAUSE_ENCRYPTION*(x: expr): expr = + (GET_BIT(x, 42)) + +template LMP_AFH_CAPABLE_MASTER*(x: expr): expr = + (GET_BIT(x, 43)) + +template LMP_AFH_CLASSIFICATION_MASTER*(x: expr): expr = + (GET_BIT(x, 44)) + +template LMP_EDR_ESCO_2MBPS_MODE*(x: expr): expr = + (GET_BIT(x, 45)) + +template LMP_EDR_ESCO_3MBPS_MODE*(x: expr): expr = + (GET_BIT(x, 46)) + +template LMP_3SLOT_EDR_ESCO_PACKETS*(x: expr): expr = + (GET_BIT(x, 47)) + +template LMP_EXTENDED_INQUIRY_RESPONSE*(x: expr): expr = + (GET_BIT(x, 48)) + +template LMP_SIMULT_LE_BR_TO_SAME_DEV*(x: expr): expr = + (GET_BIT(x, 49)) + +template LMP_SECURE_SIMPLE_PAIRING*(x: expr): expr = + (GET_BIT(x, 51)) + +template LMP_ENCAPSULATED_PDU*(x: expr): expr = + (GET_BIT(x, 52)) + +template LMP_ERRONEOUS_DATA_REPORTING*(x: expr): expr = + (GET_BIT(x, 53)) + +template LMP_NON_FLUSHABLE_PACKET_BOUNDARY_FLAG*(x: expr): expr = + (GET_BIT(x, 54)) + +template LMP_LINK_SUPERVISION_TIMEOUT_CHANGED_EVENT*(x: expr): expr = + (GET_BIT(x, 56)) + +template LMP_INQUIRY_RESPONSE_TX_POWER_LEVEL*(x: expr): expr = + (GET_BIT(x, 57)) + +template LMP_EXTENDED_FEATURES*(x: expr): expr = + (GET_BIT(x, 63)) diff --git a/nimbluez/msbt/ms_bthsdpdef.nim b/nimbluez/msbt/ms_bthsdpdef.nim new file mode 100644 index 0000000..051fc44 --- /dev/null +++ b/nimbluez/msbt/ms_bthsdpdef.nim @@ -0,0 +1,98 @@ +# +# Copyright (C) Microsoft. All rights reserved. +# + +import winlean + +type + WCHAR* = uint16 + LPWSTR* = ptr WCHAR + LPCWSTR* = ptr WCHAR + PWSTR* = LPWSTR +# GUID* {.final, pure.} = object +# D1*: int32 +# D2*: int16 +# D3*: int16 +# D4*: array [0..7, int8] + BOOL* = int32 + CHAR* = char + UCHAR* = uint8 + BYTE* = byte +# ULONG* = int32 +# DWORD* = int32 + LPSTR* = cstring + LPDWORD* = ptr DWORD + ULONGLONG* = uint64 + LONGLONG* = int64 + USHORT* = uint16 + SHORT* = int16 +# HANDLE* = int32 + SYSTEMTIME* {.final, pure.} = object + wYear*: int16 + wMonth*: int16 + wDayOfWeek*: int16 + wDay*: int16 + wHour*: int16 + wMinute*: int16 + wSecond*: int16 + wMilliseconds*: int16 + LPVOID* = pointer + PVOID* = pointer + HWND* = HANDLE + LPBYTE* = ptr int8 + + +type + SDP_LARGE_INTEGER_16* = object + LowPart*: ULONGLONG + HighPart*: LONGLONG + + SDP_ULARGE_INTEGER_16* = object + LowPart*: ULONGLONG + HighPart*: ULONGLONG + + PSDP_ULARGE_INTEGER_16* = ptr SDP_ULARGE_INTEGER_16 + LPSDP_ULARGE_INTEGER_16* = ptr SDP_ULARGE_INTEGER_16 + PSDP_LARGE_INTEGER_16* = ptr SDP_LARGE_INTEGER_16 + LPSDP_LARGE_INTEGER_16* = ptr SDP_LARGE_INTEGER_16 + + NodeContainerType* = enum + NodeContainerTypeSequence, NodeContainerTypeAlternative + + SDP_ERROR* = USHORT + PSDP_ERROR* = ptr USHORT + + SDP_TYPE* = enum + SDP_TYPE_NIL = 0x00000000, SDP_TYPE_UINT = 0x00000001, + SDP_TYPE_INT = 0x00000002, SDP_TYPE_UUID = 0x00000003, + SDP_TYPE_STRING = 0x00000004, SDP_TYPE_BOOLEAN = 0x00000005, + SDP_TYPE_SEQUENCE = 0x00000006, SDP_TYPE_ALTERNATIVE = 0x00000007, + SDP_TYPE_URL = 0x00000008, SDP_TYPE_CONTAINER = 0x00000020 +# 9 - 31 are reserved +# allow for a little easier type checking / sizing for integers and UUIDs +# ((SDP_ST_XXX & 0xF0) >> 4) == SDP_TYPE_XXX +# size of the data (in bytes) is encoded as ((SDP_ST_XXX & 0xF0) >> 8) + + SDP_SPECIFICTYPE* = enum + SDP_ST_NONE = 0x00000000, SDP_ST_UINT8 = 0x00000010, + SDP_ST_INT8 = 0x00000020, SDP_ST_UINT16 = 0x00000110, + SDP_ST_INT16 = 0x00000120, SDP_ST_UUID16 = 0x00000130, + SDP_ST_UINT32 = 0x00000210, SDP_ST_INT32 = 0x00000220, + SDP_ST_UINT64 = 0x00000310, SDP_ST_INT64 = 0x00000320, + SDP_ST_UINT128 = 0x00000410, SDP_ST_INT128 = 0x00000420, + SDP_ST_UUID128 = 0x00000430 +const + SDP_ST_UUID32* = SDP_ST_INT32 +type + SdpAttributeRange* = object + minAttribute*: USHORT + maxAttribute*: USHORT + + SdpQueryUuidUnion* = object {.union.} + uuid128*: GUID + uuid32*: ULONG + uuid16*: USHORT + + SdpQueryUuid* = object + u*: SdpQueryUuidUnion + uuidType*: USHORT diff --git a/nimbluez/msbt/ms_ws2bth.nim b/nimbluez/msbt/ms_ws2bth.nim new file mode 100644 index 0000000..4afb08d --- /dev/null +++ b/nimbluez/msbt/ms_ws2bth.nim @@ -0,0 +1,372 @@ +#++ +# +#Copyright (c) 2000 Microsoft Corporation +# +#Module Name: +# +# ws2bth.h +# +#Abstract: +# +# Winsock 2 Bluetooth Annex definitions. +# +#Notes: +# +# Change BT_* to BTH_* +# +#-- +{.passC: "-mno-ms-bitfields".} + +import winlean +import ms_bthdef, ms_bthsdpdef, ms_bluetoothapis + +const + AF_BTH* = 32 + PF_BTH* = AF_BTH + + IOC_UNIX* = 0x00000000 + IOC_WS2* = 0x08000000 + IOC_PROTOCOL* = 0x10000000 + IOC_VENDOR* = 0x18000000 + + IOCPARM_MASK* = 0x0000007F + IOC_VOID* = 0x20000000 + IOC_OUT* = 0x40000000 + IOC_IN* = 0x80000000 + IOC_INOUT* = (IOC_IN or IOC_OUT) + +template WSAIO*(x, y: expr): expr = + (IOC_VOID or (x) or (y)) + +template WSAIOR*(x, y: expr): expr = + (IOC_OUT or (x) or (y)) + +template WSAIOW*(x, y: expr): expr = + (IOC_IN or (x) or (y)) + +template WSAIORW*(x, y: expr): expr = + (IOC_INOUT or (x) or (y)) + +const + BT_PORT_ANY* = ULONG(-1) + BT_PORT_MIN* = 0x00000001 + BT_PORT_MAX* = 0x0000FFFF + BT_PORT_DYN_FIRST* = 0x00001001 +# +# These three definitions are duplicated in winsock2.h to reserve ordinals +# +type + SOCKADDR_BTH* {.packed.} = object + addressFamily*: USHORT # Always AF_BTH + btAddr*: BTH_ADDR # Bluetooth device address + serviceClassId*: GUID # [OPTIONAL] system will query SDP for port + port*: ULONG # RFCOMM channel or L2CAP PSM + + PSOCKADDR_BTH* = ptr SOCKADDR_BTH + +DEFINE_GUID(SVCID_BTH_PROVIDER, 0x06AA63E0, 0x00007D60, 0x000041FF, + 0x000000AF, 0x000000B2, 0x0000003E, 0x000000E6, 0x000000D2, + 0x000000D9, 0x00000039, 0x0000002D) +const + BTH_ADDR_STRING_SIZE* = 12 +# +# Bluetooth protocol #s are assigned according to the Bluetooth +# Assigned Numbers portion of the Bluetooth Specification +# +const + BTHPROTO_RFCOMM* = 0x00000003 + BTHPROTO_L2CAP* = 0x00000100 + + SOL_RFCOMM* = BTHPROTO_RFCOMM + SOL_L2CAP* = BTHPROTO_L2CAP + SOL_SDP* = 0x00000101 +# +# SOCKET OPTIONS +# +const + SO_BTH_AUTHENTICATE* = 0x80000001 + SO_BTH_ENCRYPT* = 0x00000002 + SO_BTH_MTU* = 0x80000007 + SO_BTH_MTU_MAX* = 0x80000008 + SO_BTH_MTU_MIN* = 0x8000000A +# +# Socket option parameters +# +# 3-DH5 => payload of 1021 => L2cap payload of 1017 => RFComm payload of 1011 +const + RFCOMM_MAX_MTU* = 0x000003F3 + RFCOMM_MIN_MTU* = 0x00000017 +# +# NAME SERVICE PROVIDER DEFINITIONS +# For calling WSASetService +# and WSALookupServiceBegin, WSALookupServiceNext, WSALookupServiceEnd +# with Bluetooth-specific extensions +# +const + BTH_SDP_VERSION* = 1 +# +# [OPTIONAL] passed in BLOB member of WSAQUERYSET +# QUERYSET and its lpBlob member are copied & converted +# to unicode in the system for non-unicode applications. +# However, nothing is copied back upon return. In +# order for the system to return data such as pRecordHandle, +# it much have an extra level of indirection from lpBlob +# +type + BTH_SET_SERVICE* = object + pSdpVersion*: PULONG # + # This version number will change when/if the binary format of + # SDP records change, affecting the format of pRecord. + # Set to BTH_SDP_VERSION by client, and returned by system + # + # + # Handle to SDP record. When BTH_SET_SERVICE structure is later + # passed to WSASetService RNRSERVICE_DELETE, this handle identifies the + # record to delete. + # + pRecordHandle*: ptr HANDLE # + # COD_SERVICE_* bit(s) associated with this SDP record, which will be + # advertised when the local radio is found during device inquiry. + # When the last SDP record associated with a bit is deleted, that + # service bit is no longer reported in repsonse to inquiries + # + fCodService*: ULONG # COD_SERVICE_* bits + Reserved*: array[5, ULONG] # Reserved by system. Must be zero. + ulRecordLength*: ULONG # length of pRecord which follows + pRecord*: array[1, UCHAR] # SDP record as defined by bluetooth spec + + PBTH_SET_SERVICE* = ptr BTH_SET_SERVICE +# +# Default device inquiry duration in seconds +# +# The application thread will be blocked in WSALookupServiceBegin +# for the duration of the device inquiry, so this value needs to +# be balanced against the chance that a device that is actually +# present might not being found by Bluetooth in this time +# +# Paging improvements post-1.1 will cause devices to be +# found generally uniformly in the 0-6 sec timeperiod +# +const + SDP_DEFAULT_INQUIRY_SECONDS* = 6 + SDP_MAX_INQUIRY_SECONDS* = 60 +# +# Default maximum number of devices to search for +# +const + SDP_DEFAULT_INQUIRY_MAX_RESPONSES* = 255 + SDP_SERVICE_SEARCH_REQUEST* = 1 + SDP_SERVICE_ATTRIBUTE_REQUEST* = 2 + SDP_SERVICE_SEARCH_ATTRIBUTE_REQUEST* = 3 +# +# [OPTIONAL] input restrictions on device inquiry +# Passed in BLOB of LUP_CONTAINERS (device) search +# +type + BTH_QUERY_DEVICE* = object + LAP*: ULONG # reserved: must be 0 (GIAC inquiry only) + length*: UCHAR # requested length of inquiry (seconds) + + PBTH_QUERY_DEVICE* = ptr BTH_QUERY_DEVICE +# +# [OPTIONAL] Restrictions on searching for a particular service +# Passed in BLOB of !LUP_CONTAINERS (service) search +# +type + BTH_QUERY_SERVICE* = object + `type`*: ULONG # one of SDP_SERVICE_* + serviceHandle*: ULONG + uuids*: array[MAX_UUIDS_IN_QUERY, SdpQueryUuid] + numRange*: ULONG + pRange*: array[1, SdpAttributeRange] + + PBTH_QUERY_SERVICE* = ptr BTH_QUERY_SERVICE +# +# BTHNS_RESULT_* +# +# Bluetooth specific flags returned from WSALookupServiceNext +# in WSAQUERYSET.dwOutputFlags in response to device inquiry +# +# +# Local device is paired with remote device +# +const + BTHNS_RESULT_DEVICE_CONNECTED* = 0x00010000 + BTHNS_RESULT_DEVICE_REMEMBERED* = 0x00020000 + BTHNS_RESULT_DEVICE_AUTHENTICATED* = 0x00040000 +# +# SOCKET IOCTLs +# +const + SIO_RFCOMM_SEND_COMMAND* = WSAIORW(IOC_VENDOR, 101) + SIO_RFCOMM_WAIT_COMMAND* = WSAIORW(IOC_VENDOR, 102) +# +# These IOCTLs are for test/validation/conformance and may only be +# present in debug/checked builds of the system +# +const + SIO_BTH_PING* = WSAIORW(IOC_VENDOR, 8) + SIO_BTH_INFO* = WSAIORW(IOC_VENDOR, 9) + SIO_RFCOMM_SESSION_FLOW_OFF* = WSAIORW(IOC_VENDOR, 103) + SIO_RFCOMM_TEST* = WSAIORW(IOC_VENDOR, 104) + SIO_RFCOMM_USECFC* = WSAIORW(IOC_VENDOR, 105) +# RESERVED _WSAIORW (IOC_VENDOR, 106) +# +# SOCKET IOCTL DEFINITIONS +# +when not defined(BIT): + template BIT*(b: expr): expr = + (1 shl (b)) + +# +# Structure definition from Bluetooth RFCOMM spec, TS 07.10 5.4.6.3.7 +# +# Signals field values +const +# MSC_EA_BIT* = EA_BIT + MSC_FC_BIT* = BIT(1) # Flow control, clear if we can receive + MSC_RTC_BIT* = BIT(2) # Ready to communicate, set when ready + MSC_RTR_BIT* = BIT(3) # Ready to receive, set when ready + MSC_RESERVED* = (BIT(4) or BIT(5)) # Reserved by spec, must be 0 + MSC_IC_BIT* = BIT(6) # Incoming call + MSC_DV_BIT* = BIT(7) # Data valid + # Break field values + MSC_BREAK_BIT* = BIT(1) # Set if sending break +template MSC_SET_BREAK_LENGTH*(b, l: expr): expr = + ((b) = ((b) and 0x00000003) or (((l) and 0x0000000F) shl 4)) + +type + RFCOMM_MSC_DATA* = object + Signals*: UCHAR + Break*: UCHAR + + PRFCOMM_MSC_DATA* = ptr RFCOMM_MSC_DATA +# +# Structure definition from Bluetooth RFCOMM spec, TS 07.10 5.4.6.3.10 +# +const + RLS_ERROR* = 0x00000001 + RLS_OVERRUN* = 0x00000002 + RLS_PARITY* = 0x00000004 + RLS_FRAMING* = 0x00000008 +type + RFCOMM_RLS_DATA* = object + LineStatus*: UCHAR + + PRFCOMM_RLS_DATA* = ptr RFCOMM_RLS_DATA +# +# Structure definition from Bluetooth RFCOMM spec, TS 07.10 5.4.6.3.9 +# +const + RPN_BAUD_2400* = 0 + RPN_BAUD_4800* = 1 + RPN_BAUD_7200* = 2 + RPN_BAUD_9600* = 3 + RPN_BAUD_19200* = 4 + RPN_BAUD_38400* = 5 + RPN_BAUD_57600* = 6 + RPN_BAUD_115200* = 7 + RPN_BAUD_230400* = 8 + RPN_DATA_5* = 0x00000000 + RPN_DATA_6* = 0x00000001 + RPN_DATA_7* = 0x00000002 + RPN_DATA_8* = 0x00000003 + RPN_STOP_1* = 0x00000000 + RPN_STOP_1_5* = 0x00000004 + RPN_PARITY_NONE* = 0x00000000 + RPN_PARITY_ODD* = 0x00000008 + RPN_PARITY_EVEN* = 0x00000018 + RPN_PARITY_MARK* = 0x00000028 + RPN_PARITY_SPACE* = 0x00000038 + RPN_FLOW_X_IN* = 0x00000001 + RPN_FLOW_X_OUT* = 0x00000002 + RPN_FLOW_RTR_IN* = 0x00000004 + RPN_FLOW_RTR_OUT* = 0x00000008 + RPN_FLOW_RTC_IN* = 0x00000010 + RPN_FLOW_RTC_OUT* = 0x00000020 + RPN_PARAM_BAUD* = 0x00000001 + RPN_PARAM_DATA* = 0x00000002 + RPN_PARAM_STOP* = 0x00000004 + RPN_PARAM_PARITY* = 0x00000008 + RPN_PARAM_P_TYPE* = 0x00000010 + RPN_PARAM_XON* = 0x00000020 + RPN_PARAM_XOFF* = 0x00000040 + RPN_PARAM_X_IN* = 0x00000001 + RPN_PARAM_X_OUT* = 0x00000002 + RPN_PARAM_RTR_IN* = 0x00000004 + RPN_PARAM_RTR_OUT* = 0x00000008 + RPN_PARAM_RTC_IN* = 0x00000010 + RPN_PARAM_RTC_OUT* = 0x00000020 +type + RFCOMM_RPN_DATA* = object + Baud*: UCHAR + Data*: UCHAR + FlowControl*: UCHAR + XonChar*: UCHAR + XoffChar*: UCHAR + ParameterMask1*: UCHAR + ParameterMask2*: UCHAR + + PRFCOMM_RPN_DATA* = ptr RFCOMM_RPN_DATA +const + RFCOMM_CMD_NONE* = 0 + RFCOMM_CMD_MSC* = 1 + RFCOMM_CMD_RLS* = 2 + RFCOMM_CMD_RPN* = 3 + RFCOMM_CMD_RPN_REQUEST* = 4 + RFCOMM_CMD_RPN_RESPONSE* = 5 +# RESERVED_CMD 6 +type + INNER_C_UNION_112492126* = object {.union.} + MSC*: RFCOMM_MSC_DATA + RLS*: RFCOMM_RLS_DATA + RPN*: RFCOMM_RPN_DATA + +type + RFCOMM_COMMAND* = object + CmdType*: ULONG # one of RFCOMM_CMD_* + Data*: INNER_C_UNION_112492126 + + PRFCOMM_COMMAND* = ptr RFCOMM_COMMAND +# +# These structures are for test/validation/conformance and may only be +# present in debug/checked builds of the system +# +type + INNER_C_UNION_301228124* = object {.union.} + connectionlessMTU*: USHORT + data*: array[MAX_L2CAP_INFO_DATA_LENGTH, UCHAR] + +type + BTH_PING_REQ* = object + btAddr*: BTH_ADDR + dataLen*: UCHAR + data*: array[MAX_L2CAP_PING_DATA_LENGTH, UCHAR] + + PBTH_PING_REQ* = ptr BTH_PING_REQ + BTH_PING_RSP* = object + dataLen*: UCHAR + data*: array[MAX_L2CAP_PING_DATA_LENGTH, UCHAR] + + PBTH_PING_RSP* = ptr BTH_PING_RSP + BTH_INFO_REQ* = object + btAddr*: BTH_ADDR + infoType*: USHORT + + PBTH_INFO_REQ* = ptr BTH_INFO_REQ + BTH_INFO_RSP* = object + result*: USHORT + dataLen*: UCHAR + ano_2541354110*: INNER_C_UNION_301228124 + + PBTH_INFO_RSP* = ptr BTH_INFO_RSP +# +# WinCE compatible struct names +# +type + BTHNS_SETBLOB* = BTH_SET_SERVICE + PBTHNS_SETBLOB* = ptr BTH_SET_SERVICE + BTHNS_INQUIRYBLOB* = BTH_QUERY_DEVICE + PBTHNS_INQUIRYBLOB* = ptr BTH_QUERY_DEVICE + BTHNS_RESTRICTIONBLOB* = BTH_QUERY_SERVICE + PBTHNS_RESTRICTIONBLOB* = ptr BTH_QUERY_SERVICE |
