1# -*- coding: utf-8 -*- 2# Copyright 2019 Oticon A/S 3# SPDX-License-Identifier: Apache-2.0 4 5opCodes = { 0x0401: 'Inquire', 6 0x0406: 'Disconnect', 7 0x041D: 'Read Remote Version Information', 8 0x0C01: 'Set Event Mask', 9 0x0C03: 'Reset', 10 0x0C2D: 'Read Transmit Power Level', 11 0x0C31: 'Set Controller To Host Flow Control', 12 0x0C33: 'Host Buffer Size', 13 0x0C35: 'Host Number Of Completed Packets', 14 0x0C63: 'Set Event Mask Page 2', 15 0x0C6C: 'Read LE Host Support', 16 0x0C6D: 'Write LE Host Support', 17 0x0C7B: 'Read Authenticated Payload Timeout', 18 0x0C7C: 'Write Authenticated Payload Timeout', 19 0x1001: 'Read Local Version Information', 20 0x1002: 'Read Local Supported Commands', 21 0x1003: 'Read Local Supported Features', 22 0x1005: 'Read Buffer Size', 23 0x1009: 'Read BD_ADDR', 24 0x1405: 'Read RSSI', 25 0x2001: 'LE Set Event Mask', 26 0x2002: 'LE Read Buffer Size', 27 0x2003: 'LE Read Local Supported Features', 28 0x2005: 'LE Set Random Address', 29 0x2006: 'LE Set Advertising Parameters', 30 0x2007: 'LE Read Advertising Channel TX Power', 31 0x2008: 'LE Set Advertising Data', 32 0x2009: 'LE Set Scan Response Data', 33 0x200A: 'LE Set Advertising Enable', 34 0x200B: 'LE Set Scan Parameters', 35 0x200C: 'LE Set Scan Enable', 36 0x200D: 'LE Create Connection', 37 0x200E: 'LE Create Connection Cancel', 38 0x200F: 'LE Read Filter Accept List Size', 39 0x2010: 'LE Clear Filter Accept List', 40 0x2011: 'LE Add Device To Filter Accept List', 41 0x2012: 'LE Remove Device From Filter Accept List', 42 0x2013: 'LE Connection Update', 43 0x2014: 'LE Set Host Channel Classification', 44 0x2015: 'LE Read Channel Map', 45 0x2016: 'LE Read Remote Features', 46 0x2017: 'LE Encrypt', 47 0x2018: 'LE Rand', 48 0x2019: 'LE Start Encryption', 49 0x201A: 'LE Long Term Key Request Reply', 50 0x201B: 'LE Long Term Key Request Negative Reply', 51 0x201C: 'LE Read Supported States', 52 0x201D: 'LE Receiver Test', 53 0x201E: 'LE Transmitter Test', 54 0x201F: 'LE Test End', 55 0x2020: 'LE Remote Connection Parameter Request Reply', 56 0x2021: 'LE Remote Connection Parameter Request Negative Reply', 57 0x2022: 'LE Set Data Length', 58 0x2023: 'LE Read Suggested Default Data Length', 59 0x2024: 'LE Write Suggested Default Data Length', 60 0x2027: 'LE Add Device to Resolving List', 61 0x2028: 'LE Remove Device From Resolving List', 62 0x2029: 'LE Clear Resolving List', 63 0x202A: 'LE Read Resolving List Size', 64 0x202B: 'LE Read Peer Resolvable Address', 65 0x202C: 'LE Read Local Resolvable Address', 66 0x202D: 'LE Set Address Resolution Enable', 67 0x202E: 'LE Set Resolvable Private Address Timeout', 68 0x202F: 'LE Read Maximum Data Length', 69 0x2030: 'LE Read PHY', 70 0x2031: 'LE Set Default PHY', 71 0x2032: 'LE Set PHY', 72 0x2033: 'LE Enhanced Receiver Test', 73 0x2034: 'LE Enhanced Transmitter Test', 74 0x2036: 'LE Set Extended Advertising Parameters', 75 0x2037: 'LE Set Extended Advertising Data', 76 0x2038: 'LE Set Extended Scan Response Data', 77 0x2039: 'LE Set Extended Advertising Enable', 78 0x203A: 'LE Read Maximum Advertising Data Length', 79 0x203B: 'LE Read Number of Supported Advertising Sets', 80 0x203C: 'LE Remove Advertising Set', 81 0x203D: 'LE Clear Advertising Sets', 82 0x203E: 'LE Set Periodic Advertising Parameters', 83 0x203F: 'LE Set Periodic Advertising Data', 84 0x2040: 'LE Set Periodic Advertising Enable', 85 0x2041: 'LE Set Extended Scan Parameters', 86 0x2042: 'LE Set Extended Scan Enable', 87 0x2043: 'LE Extended Create Connection', 88 0x2044: 'LE Periodic Advertising Create Sync', 89 0x2045: 'LE Periodic Advertising Create Sync Cancel', 90 0x2046: 'LE Periodic Advertising Terminate Sync', 91 0x2047: 'LE Add Device To Periodic Advertiser List', 92 0x2048: 'LE Remove Device From Periodic Advertiser List', 93 0x2049: 'LE Clear Periodic Advertiser List', 94 0x204A: 'LE Read Periodic Advertiser List Size', 95 0x204B: 'LE Read Transmit Power', 96 0x204C: 'LE Read RF Path Compensation', 97 0x204D: 'LE Write RF Path Compensation', 98 0x204E: 'LE Set Privacy Mode', 99 0xFC06: 'Write BD_ADDR' }; 100 101crc_table_24_ble = [ 102 0x000000, 0x01b4c0, 0x036980, 0x02dd40, 0x06d300, 0x0767c0, 0x05ba80, 0x040e40, 103 0x0da600, 0x0c12c0, 0x0ecf80, 0x0f7b40, 0x0b7500, 0x0ac1c0, 0x081c80, 0x09a840, 104 0x1b4c00, 0x1af8c0, 0x182580, 0x199140, 0x1d9f00, 0x1c2bc0, 0x1ef680, 0x1f4240, 105 0x16ea00, 0x175ec0, 0x158380, 0x143740, 0x103900, 0x118dc0, 0x135080, 0x12e440, 106 0x369800, 0x372cc0, 0x35f180, 0x344540, 0x304b00, 0x31ffc0, 0x332280, 0x329640, 107 0x3b3e00, 0x3a8ac0, 0x385780, 0x39e340, 0x3ded00, 0x3c59c0, 0x3e8480, 0x3f3040, 108 0x2dd400, 0x2c60c0, 0x2ebd80, 0x2f0940, 0x2b0700, 0x2ab3c0, 0x286e80, 0x29da40, 109 0x207200, 0x21c6c0, 0x231b80, 0x22af40, 0x26a100, 0x2715c0, 0x25c880, 0x247c40, 110 0x6d3000, 0x6c84c0, 0x6e5980, 0x6fed40, 0x6be300, 0x6a57c0, 0x688a80, 0x693e40, 111 0x609600, 0x6122c0, 0x63ff80, 0x624b40, 0x664500, 0x67f1c0, 0x652c80, 0x649840, 112 0x767c00, 0x77c8c0, 0x751580, 0x74a140, 0x70af00, 0x711bc0, 0x73c680, 0x727240, 113 0x7bda00, 0x7a6ec0, 0x78b380, 0x790740, 0x7d0900, 0x7cbdc0, 0x7e6080, 0x7fd440, 114 0x5ba800, 0x5a1cc0, 0x58c180, 0x597540, 0x5d7b00, 0x5ccfc0, 0x5e1280, 0x5fa640, 115 0x560e00, 0x57bac0, 0x556780, 0x54d340, 0x50dd00, 0x5169c0, 0x53b480, 0x520040, 116 0x40e400, 0x4150c0, 0x438d80, 0x423940, 0x463700, 0x4783c0, 0x455e80, 0x44ea40, 117 0x4d4200, 0x4cf6c0, 0x4e2b80, 0x4f9f40, 0x4b9100, 0x4a25c0, 0x48f880, 0x494c40, 118 0xda6000, 0xdbd4c0, 0xd90980, 0xd8bd40, 0xdcb300, 0xdd07c0, 0xdfda80, 0xde6e40, 119 0xd7c600, 0xd672c0, 0xd4af80, 0xd51b40, 0xd11500, 0xd0a1c0, 0xd27c80, 0xd3c840, 120 0xc12c00, 0xc098c0, 0xc24580, 0xc3f140, 0xc7ff00, 0xc64bc0, 0xc49680, 0xc52240, 121 0xcc8a00, 0xcd3ec0, 0xcfe380, 0xce5740, 0xca5900, 0xcbedc0, 0xc93080, 0xc88440, 122 0xecf800, 0xed4cc0, 0xef9180, 0xee2540, 0xea2b00, 0xeb9fc0, 0xe94280, 0xe8f640, 123 0xe15e00, 0xe0eac0, 0xe23780, 0xe38340, 0xe78d00, 0xe639c0, 0xe4e480, 0xe55040, 124 0xf7b400, 0xf600c0, 0xf4dd80, 0xf56940, 0xf16700, 0xf0d3c0, 0xf20e80, 0xf3ba40, 125 0xfa1200, 0xfba6c0, 0xf97b80, 0xf8cf40, 0xfcc100, 0xfd75c0, 0xffa880, 0xfe1c40, 126 0xb75000, 0xb6e4c0, 0xb43980, 0xb58d40, 0xb18300, 0xb037c0, 0xb2ea80, 0xb35e40, 127 0xbaf600, 0xbb42c0, 0xb99f80, 0xb82b40, 0xbc2500, 0xbd91c0, 0xbf4c80, 0xbef840, 128 0xac1c00, 0xada8c0, 0xaf7580, 0xaec140, 0xaacf00, 0xab7bc0, 0xa9a680, 0xa81240, 129 0xa1ba00, 0xa00ec0, 0xa2d380, 0xa36740, 0xa76900, 0xa6ddc0, 0xa40080, 0xa5b440, 130 0x81c800, 0x807cc0, 0x82a180, 0x831540, 0x871b00, 0x86afc0, 0x847280, 0x85c640, 131 0x8c6e00, 0x8ddac0, 0x8f0780, 0x8eb340, 0x8abd00, 0x8b09c0, 0x89d480, 0x886040, 132 0x9a8400, 0x9b30c0, 0x99ed80, 0x985940, 0x9c5700, 0x9de3c0, 0x9f3e80, 0x9e8a40, 133 0x972200, 0x9696c0, 0x944b80, 0x95ff40, 0x91f100, 0x9045c0, 0x929880, 0x932c40 134] 135 136 137# Bitwise reverse 1 byte 138def rev_byte(input): 139 result = 0 140 for bit in range(8): 141 if input & (1 << bit): 142 result = result | (1 << (7-bit)) 143 return result 144 145# Reverse the bits order in a 24 bit word 146def rev_24(input): 147 return rev_byte((input >> 0) & 0xff) << 16 | rev_byte((input >> 8) & 0xff) << 8 | rev_byte((input >> 16) & 0xff) 148 149def BLECRCUpdate(crc, data): 150 for i in range(len(data)): 151 tbl_idx = (crc ^ data[i]) & 0xff 152 crc = (crc_table_24_ble[tbl_idx] ^ (crc >> 8)) & 0xffffff 153 return crc & 0xffffff 154 155def calcBLECRC(crc_init, packet): 156 return BLECRCUpdate(rev_24(crc_init), packet) 157 158def formatAddress(address, addressType=None): 159 result = ''; 160 for part in reversed(address): 161 if ( len(result) ): 162 result += ':'; 163 result += '%02X' % part; 164 if ( not addressType is None ): 165 result += '(R)' if ( (addressType & 1) == 1 ) else '(P)'; 166 return result; 167 168def formatChannelMap(channelMap): 169 value = 0; 170 for part in reversed(channelMap): 171 value <<= 8; 172 value += part; 173 return '%010X' % value; 174 175def formatArray(intArray): 176 result = ''; 177 for part in intArray: 178 if ( len(result) ): 179 result += ' '; 180 result += '%02X' % part; 181 return result; 182 183def formatPattern(pattern): 184 PatternTexts = [ 'Pseudo-Random bit sequence 9', 'Pattern of alternating bits ‘11110000’', 'Pattern of alternating bits ‘10101010’', 'Pseudo-Random bit sequence 15', 185 'Pattern of All ‘1’ bits', 'Pattern of All ‘0’ bits', 'Pattern of alternating bits ‘00001111’', 'Pattern of alternating bits ‘0101’' ]; 186 return PatternTexts[pattern] if ( pattern in range(len(PatternTexts)) ) else 'Unknown pattern!'; 187 188def showCommands(commands, trace): 189 CommandTexts = [ 190 [ 'Inquiry', 'Inquiry Cancel', 'Periodic Inquiry Mode', 'Exit Periodic Inquiry Mode', 'Create Connection', 'Disconnect', 'Add SCO Connection (deprecated)', 'Create Connection Cancel' ], 191 [ 'Accept Connection Request', 'Reject Connection Request', 'Link Key Request Reply', 'Link Key Request Negative Reply', 'PIN Code Request Reply', 'PIN Code Request Negative Reply', 'Change Connection Packet Type', 'Authentication Requested' ], 192 [ 'Set Connection Encryption', 'Change Connection Link Key', 'Central Link Key', 'Remote Name Request', 'Remote Name Request Cancel', 'Read Remote Supported Features', 'Read Remote Extended Features', 'Read Remote Version Information' ], 193 [ 'Read Clock Offset', 'Read LMP Handle', 'Reserved for Future Use', 'Reserved for Future Use', 'Reserved for Future Use', 'Reserved for Future Use', 'Reserved for Future Use', 'Reserved for Future Use' ], 194 [ 'Reserved for Future Use', 'Hold Mode', 'Sniff Mode', 'Exit Sniff Mode', 'Reserved for Future Use', 'Reserved for Future Use', 'QoS Setup', 'Role Discovery' ], 195 [ 'Switch Role', 'Read Link Policy Settings', 'Write Link Policy Settings', 'Read Default Link Policy Settings', 'Write Default Link Policy Settings', 'Flow Specification', 'Set Event Mask', 'Reset' ], 196 [ 'Set Event Filter', 'Flush', 'Read PIN Type', 'Write PIN Type', 'Create New Unit Key', 'Read Stored Link Key', 'Write Stored Link Key', 'Delete Stored Link Key' ], 197 [ 'Write Local Name', 'Read Local Name', 'Read Connection Accept Timeout', 'Write Connection Accept Timeout', 'Read Page Timeout', 'Write Page Timeout', 'Read Scan Enable', 'Write Scan Enable' ], 198 [ 'Read Page Scan Activity', 'Write Page Scan Activity', 'Read Inquiry Scan Activity', 'Write Inquiry Scan Activity', 'Read Authentication Enable', 'Write Authentication Enable', 'Read Encryption Mode (deprecated)', 'Write Encryption Mode (deprecated)' ], 199 [ 'Read Class Of Device', 'Write Class Of Device', 'Read Voice Setting', 'Write Voice Setting', 'Read Automatic Flush Timeout', 'Write Automatic Flush Timeout', 'Read Num Broadcast Retransmissions', 'Write Num Broadcast Retransmissions' ], 200 [ 'Read Hold Mode Activity', 'Write Hold Mode Activity', 'Read Transmit Power Level', 'Read Synchronous Flow Control Enable', 'Write Synchronous Flow Control Enable', 'Set Controller To Host Flow Control', 'Host Buffer Size', 'Host Number Of Completed Packets' ], 201 [ 'Read Link Supervision Timeout', 'Write Link Supervision Timeout', 'Read Number of Supported IAC', 'Read Current IAC LAP', 'Write Current IAC LAP', 'Read Page Scan Mode Period (deprecated)', 'Write Page Scan Mode Period (deprecated)', 'Read Page Scan Mode (deprecated)' ], 202 [ 'Write Page Scan Mode (deprecated)', 'Set AFH Host Channel Classification', 'Reserved for Future Use', 'Reserved for Future Use', 'Read Inquiry Scan Type', 'Write Inquiry Scan Type', 'Read Inquiry Mode', 'Write Inquiry Mode' ], 203 [ 'Read Page Scan Type', 'Write Page Scan Type', 'Read AFH Channel Assessment Mode', 'Write AFH Channel Assessment Mode', 'Reserved for Future Use', 'Reserved for Future Use', 'Reserved for Future Use', 'Reserved for Future Use' ], 204 [ 'Reserved for Future Use', 'Reserved for Future Use', 'Reserved for Future Use', 'Read Local Version Information', 'Reserved for Future Use', 'Read Local Supported Features', 'Read Local Extended Features', 'Read Buffer Size' ], 205 [ 'Read Country Code [Deprecated]', 'Read BD ADDR', 'Read Failed Contact Counter', 'Reset Failed Contact Counter', 'Read Link Quality', 'Read RSSI', 'Read AFH Channel Map', 'Read Clock' ], 206 [ 'Read Loopback Mode', 'Write Loopback Mode', 'Enable Device Under Test Mode', 'Setup Synchronous Connection Request', 'Accept Synchronous Connection Request', 'Reject Synchronous Connection Request', 'Reserved for Future Use', 'Reserved for Future Use' ], 207 [ 'Read Extended Inquiry Response', 'Write Extended Inquiry Response', 'Refresh Encryption Key', 'Reserved for Future Use', 'Sniff Subrating', 'Read Simple Pairing Mode', 'Write Simple Pairing Mode', 'Read Local OOB Data' ], 208 [ 'Read Inquiry Response Transmit Power Level', 'Write Inquiry Transmit Power Level', 'Read Default Erroneous Data Reporting', 'Write Default Erroneous Data Reporting', 'Reserved for Future Use', 'Reserved for Future Use', 'Reserved for Future Use', 'IO Capability Request Reply' ], 209 [ 'User Confirmation Request Reply', 'User Confirmation Request Negative Reply', 'User Passkey Request Reply', 'User Passkey Request Negative Reply', 'Remote OOB Data Request Reply', 'Write Simple Pairing Debug Mode', 'Enhanced Flush', 'Remote OOB Data Request Negative Reply' ], 210 [ 'Reserved for Future Use', 'Reserved for Future Use', 'Send Keypress Notification', 'IO Capability Request Negative Reply', 'Read Encryption Key Size', 'Reserved for Future Use', 'Reserved for Future Use', 'Reserved for Future Use' ], 211 [ 'Create Physical Link', 'Accept Physical Link', 'Disconnect Physical Link', 'Create Logical Link', 'Accept Logical Link', 'Disconnect Logical Link', 'Logical Link Cancel', 'Flow Spec Modify' ], 212 [ 'Read Logical Link Accept Timeout', 'Write Logical Link Accept Timeout', 'Set Event Mask Page 2', 'Read Location Data', 'Write Location Data', 'Read Local AMP Info', 'Read Local AMP_ASSOC', 'Write Remote AMP_ASSOC' ], 213 [ 'Read Flow Control Mode', 'Write Flow Control Mode', 'Read Data Block Size', 'Reserved for Future Use', 'Reserved for Future Use', 'Enable AMP Receiver Reports', 'AMP Test End', 'AMP Test' ], 214 [ 'Read Enhanced Transmit Power Level', 'Reserved for Future Use', 'Read Best Effort Flush Timeout', 'Write Best Effort Flush Timeout', 'Short Range Mode', 'Read LE Host Support', 'Write LE Host Support', 'Reserved for Future Use' ], 215 [ 'LE Set Event Mask', 'LE Read Buffer Size', 'LE Read Local Supported Features', 'Reserved for Future Use', 'LE Set Random Address', 'LE Set Advertising Parameters', 'LE Read Advertising Channel TX Power', 'LE Set Advertising Data' ], 216 [ 'LE Set Scan Response Data', 'LE Set Advertising Enable', 'LE Set Scan Parameters', 'LE Set Scan Enable', 'LE Create Connection', 'LE Create Connection Cancel', 'LE Read Filter Accept List Size', 'LE Clear Filter Accept List' ], 217 [ 'LE Add Device To Filter Accept List', 'LE Remove Device From Filter Accept List', 'LE Connection Update', 'LE Set Host Channel Classification', 'LE Read Channel Map', 'LE Read Remote Features', 'LE Encrypt', 'LE Rand' ], 218 [ 'LE Start Encryption', 'LE Long Term Key Request Reply', 'LE Long Term Key Request Negative Reply', 'LE Read Supported States', 'LE Receiver Test', 'LE Transmitter Test', 'LE Test End', 'Reserved for Future Use' ], 219 [ 'Reserved for Future Use', 'Reserved for Future Use', 'Reserved for Future Use', 'Enhanced Setup Synchronous Connection', 'Enhanced Accept Synchronous Connection', 'Read Local Supported Codecs', 'Set MWS Channel Parameters', 'Set External Frame Configuration' ], 220 [ 'Set MWS Signaling', 'Set MWS Transport Layer', 'Set MWS Scan Frequency Table', 'Get MWS Transport Layer Configuration', 'Set MWS PATTERN Configuration', 'Set Triggered Clock Capture', 'Truncated Page', 'Truncated Page Cancel' ], 221 [ 'Set Connectionless Peripheral Broadcast', 'Set Connectionless Peripheral Broadcast Receive', 'Start Synchronization Train', 'Receive Synchronization Train', 'Set Reserved LT_ADDR', 'Delete Reserved LT_ADDR', 'Set Connectionless Peripheral Broadcast Data', 'Read Synchronization Train Parameters' ], 222 [ 'Write Synchronization Train Parameters', 'Remote OOB Extended Data Request Reply', 'Read Secure Connections Host Support', 'Write Secure Connections Host Support', 'Read Authenticated Payload Timeout', 'Write Authenticated Payload Timeout', 'Read Local OOB Extended Data', 'Write Secure Connections Test Mode' ], 223 [ 'Read Extended Page Timeout', 'Write Extended Page Timeout', 'Read Extended Inquiry Length', 'Write Extended Inquiry Length', 'LE Remote Connection Parameter Request Reply', 'LE Remote Connection Parameter Request Negative Reply', 'LE Set Data Length', 'LE Read Suggested Default Data Length' ], 224 [ 'LE Write Suggested Default Data Length', 'LE Read Local P-256 Public Key', 'LE Generate DH Key', 'LE Add Device To Resolving List', 'LE Remove Device From Resolving List', 'LE Clear Resolving List', 'LE Read Resolving List Size', 'LE Read Peer Resolvable Address' ], 225 [ 'LE Read Local Resolvable Address', 'LE Set Address Resolution Enable', 'LE Set Resolvable Private Address Timeout', 'LE Read Maximum Data Length', 'LE Read PHY Command', 'LE Set Default PHY Command', 'LE Set PHY Command', 'LE Enhanced Receiver Test Command' ], 226 [ 'LE Enhanced Transmitter Test Command', 'LE Set Advertising Set Random Address Command', 'LE Set Extended Advertising Parameters Command', 'LE Set Extended Advertising Data Command', 'LE Set Extended Scan Response Data Command', 'LE Set Extended Advertising Enable Command', 'LE Read Maximum Advertising Data Length Command', 'LE Read Number of Supported Advertising Sets Command' ], 227 [ 'LE Remove Advertising Set Command', 'LE Clear Advertising Sets Command', 'LE Set Periodic Advertising Parameters Command', 'LE Set Periodic Advertising Data Command', 'LE Set Periodic Advertising Enable Command', 'LE Set Extended Scan Parameters Command', 'LE Set Extended Scan Enable Command', 'LE Extended Create Connection Command' ], 228 [ 'LE Periodic Advertising Create Sync Command', 'LE Periodic Advertising Create Sync Cancel Command', 'LE Periodic Advertising Terminate Sync Command', 'LE Add Device To Periodic Advertiser List Command', 'LE Remove Device From Periodic Advertiser List Command', 'LE Clear Periodic Advertiser List Command', 'LE Read Periodic Advertiser List Size Command', 'LE Read Transmit Power Command' ], 229 [ 'LE Read RF Path Compensation Command', 'LE Write RF Path Compensation Command', 'LE Set Privacy Mode', 'Reserved for Future Use', 'Reserved for Future Use', 'Reserved for Future Use', 'Reserved for Future Use', 'Reserved for Future Use' ] 230 ]; 231 232 for n in range(len(CommandTexts)): 233 fmt = '%2i %s'; 234 for i in range(8): 235 txt = 'SUPPORTED' if ( commands[n] & (1<<i) ) else 'NOT SUPPORTED'; 236 if ( i ): 237 trace.trace(8, fmt % CommandTexts[n][i] + ' ' + txt); 238 else: 239 trace.trace(8, fmt % (n, CommandTexts[n][i] + ' ' + txt)); 240 fmt = ' %s'; 241 242def showFeatures(features, trace): 243 FeatureTexts = [ 244 [ '3 slot packets', '5 slot packets', 'Encryption', 'Slot offset', 'Timing accuracy', 'Role switch', 'Hold mode', 'Sniff mode' ], 245 [ 'Reserved for Future Use', 'Power control requests', 'Channel quality driven data rate (CQDDR)', 'SCO link', 'HV2 packets', 'HV3 packets', 'µ-law log synchronous data', 'A-law log synchronous data' ], 246 [ 'CVSD synchronous data', 'Paging parameter negotiation', 'Power control', 'Transparent synchronous data', 'Flow control lag (least significant bit)', 'Flow control lag (middle bit)', 'Flow control lag (most significant bit)', 'Broadcast Encryption' ], 247 [ 'Reserved for Future Use', 'Enhanced Data Rate ACL 2 Mb/s mode', 'Enhanced Data Rate ACL 3 Mb/s mode', 'Enhanced inquiry scan', 'Interlaced inquiry scan', 'Interlaced page scan', 'RSSI with inquiry results', 'Extended SCO link (EV3 packets)' ], 248 [ 'EV4 packets', 'EV5 packets', 'Reserved for Future Use', 'AFH capable peripheral', 'AFH classification peripheral', 'BR/EDR Not Supported', 'LE Supported (Controller)', '3-slot Enhanced Data Rate ACL packets' ], 249 [ '5-slot Enhanced Data Rate ACL packets', 'Sniff subrating', 'Pause encryption', 'AFH capable central', 'AFH classification central', 'Enhanced Data Rate eSCO 2 Mb/s mode', 'Enhanced Data Rate eSCO 3 Mb/s mode', '3-slot Enhanced Data Rate eSCO packets' ], 250 [ 'Extended Inquiry Response', 'Simultaneous LE and BR/EDR to Same Device Capable (Controller)', 'Reserved for Future Use', 'Secure Simple Pairing', 'Encapsulated PDU', 'Erroneous Data Reporting', 'Non-flushable Packet Boundary Flag', 'Reserved for Future Use' ], 251 [ 'Link Supervision Timeout Changed Event', 'Inquiry TX Power Level', 'Enhanced Power Control', 'Reserved for Future Use', 'Reserved for Future Use', 'Reserved for Future Use', 'Reserved for Future Use', 'Reserved for Future Use' ] 252 ]; 253 254 for n in range(len(FeatureTexts)): 255 fmt = '%2i %s'; 256 for i in range(8): 257 txt = 'SUPPORTED' if ( features[n] & (1<<i) ) else 'NOT SUPPORTED'; 258 if ( i ): 259 trace.trace(8, fmt % FeatureTexts[n][i] + ' ' + txt); 260 else: 261 trace.trace(8, fmt % (n, FeatureTexts[n][i] + ' ' + txt)); 262 fmt = ' %s'; 263 264def showLEFeatures(features, trace): 265 LEFeatureTexts = [ 266 [ 'LE Encryption', 'Connection Parameters Request Procedure', 'Extended Reject Indication', 'Peripheral-initiated Features Exchange', 'LE Ping', 'LE Data Packet Length Extension', 'LL Privacy', 'Extended Scanner Filter Policies' ], 267 [ 'LE 2M PHY', 'Stable Modulation Index - Transmitter', 'Stable Modulation Index - Receiver', 'LE Coded PHY', 'LE Extended Advertising', 'LE Periodic Advertising', 'Channel Selection Algorithm #2', 'LE Power Class 1' ], 268 [ 'Minimum Number of Used Channels Procedure', 'Reserved for Future Use', 'Reserved for Future Use', 'Reserved for Future Use', 'Reserved for Future Use', 'Reserved for Future Use', 'Reserved for Future Use', 'Reserved for Future Use' ], 269 ]; 270 271 for n in range(len(LEFeatureTexts)): 272 fmt = '%2i %s'; 273 for i in range(8): 274 txt = 'SUPPORTED' if ( features[n] & (1<<i) ) else 'NOT SUPPORTED'; 275 if ( i ): 276 trace.trace(8, fmt % LEFeatureTexts[n][i] + ' ' + txt); 277 else: 278 trace.trace(8, fmt % (n, LEFeatureTexts[n][i] + ' ' + txt)); 279 fmt = ' %s'; 280 281def showLEStates(states, trace): 282 LEStateTexts = [ 'Scannable Advertising State', 'Connectable Advertising State', 'Non-connectable Advertising State', 'High Duty Cycle Directed Advertising State', 'Low Duty Cycle Directed Advertising State', 283 'Active Scanning State', 'Passive Scanning State', 'Initiating State', 'Connection State (Central Role)', 'Connection State (Peripheral Role)' ]; 284 LEStateMap = [ [ 4, 1, 2, 8, 64, 32, 128, 512 ], 285 [ 68, 65, 66, 72, 36, 33, 34, 40 ], 286 [ 132, 129, 260, 257, 516, 513, 192, 160 ], 287 [ 320, 288, 576, 544, 384, 16, 80, 48 ], 288 [ 130, 136, 144, 258, 264, 272, 514, 520 ], 289 [ 528, 640, 0, 0, 0, 0, 0, 0 ] ]; 290 291 for n in range(len(LEStateMap)): 292 fmt = '%2i %s'; 293 for i in range(8): 294 if ( LEStateMap[n][i] ): 295 txt = ''; 296 for j in range(len(LEStateTexts)): 297 if ( LEStateMap[n][i] & (1<<j) ): 298 if ( len(txt) ): 299 txt += ' | ' 300 txt += LEStateTexts[j]; 301 txt += ' SUPPORTED' if ( states[n] & (1<<i) ) else ' NOT SUPPORTED'; 302 if ( i ): 303 trace.trace(8, fmt % txt); 304 else: 305 trace.trace(8, fmt % (n, txt)); 306 fmt = ' %s'; 307 308def showEventMask(eventMask, trace): 309 """ 310 0x0000000000000000 ~ No events specified. 311 """ 312 EventTexts = [ 'Inquiry Complete Event', 'Inquiry Result Event', 'Connection Complete Event', 'Connection Request Event', 313 'Disconnection Complete Event', 'Authentication Complete Event', 'Remote Name Request Complete Event', 'Encryption Change Event', 314 'Change Connection Link Key Complete Event', 'Central Link Key Complete Event', 'Read Remote Supported Features Complete Event', 'Read Remote Version Information Complete Event', 315 'QoS Setup Complete Event', 'Reserved', 'Reserved', 'Hardware Error Event', 316 'Flush Occurred Event', 'Role Change Event', 'Reserved', 'Mode Change Event', 317 'Return Link Keys Event', 'PIN Code Request Event', 'Link Key Request Event', 'Link Key Notification Event', 318 'Loopback Command Event', 'Data Buffer Overflow Event', 'Max Slots Change Event', 'Read Clock Offset Complete Event', 319 'Connection Packet Type Changed Event', 'QoS Violation Event', 'Page Scan Mode Change Event [deprecated]', 'Page Scan Repetition Mode Change Event', 320 'Flow Specification Complete Event', 'Inquiry Result with RSSI Event', 'Read Remote Extended Features Complete Event', 'Reserved', 321 'Reserved', 'Reserved', 'Reserved', 'Reserved', 322 'Reserved', 'Reserved', 'Reserved', 'Synchronous Connection Complete Event', 323 'Synchronous Connection Changed Event', 'Sniff Subrating Event', 'Extended Inquiry Result Event', 'Encryption Key Refresh Complete Event', 324 'IO Capability Request Event', 'IO Capability Request Reply Event', 'User Confirmation Request Event', 'User Passkey Request Event', 325 'Remote OOB Data Request Event','Simple Pairing Complete Event', 'Reserved', 'Link Supervision Timeout Changed Event', 326 'Enhanced Flush Complete Event', 'Reserved', 'User Passkey Notification Event', 'Keypress Notification Event', 327 'Remote Host Supported Features Notification Event', 'LE Meta-Event' ]; 328 """ 329 0x00001FFFFFFFFFFF ~ Default. 330 0xC000000000000000 ~ Reserved for future use." 331 """ 332 value = 0; 333 for part in reversed(eventMask): 334 value <<= 8; 335 value += part; 336 if ( value & 0x3FFFFFFFFFFFFFFF ): 337 if ( value == 0x1FFFFFFFFFFF ): 338 txt = 'Default'; 339 else: 340 txt = ''; 341 for n in range(len(EventTexts)): 342 if ( len(txt) ): 343 txt += ' | '; 344 if ( value & (1<<n) ): 345 txt += EventTexts[n]; 346 else: 347 txt = 'No events specified'; 348 trace.trace(8, txt); 349 350def showLEEventMask(eventMask, trace): 351 """ 352 0x0000000000000000 ~ No LE events specified. 353 """ 354 LEEventTexts = [ 'LE Connection Complete Event', 'LE Advertising Report Event', 'LE Connection Update Complete Event', 'LE Read Remote Used Features Complete Event', 355 'LE Long Term Key Request Event', 'LE Remote Connection Parameter Request Event' ]; 356 """ 357 0x000000000000001F ~ Default. 358 0xFFFFFFFFFFFFFFC0 ~ Reserved for future use. 359 """ 360 value = 0; 361 for part in reversed(eventMask): 362 value <<= 8; 363 value += part; 364 if ( value & 0x1f ): 365 if ( value == 0x1f ): 366 txt = 'Default'; 367 else: 368 txt = ''; 369 for n in range(len(LEEventTexts)): 370 if ( len(txt) ): 371 txt += ' | '; 372 if ( value & (1<<n) ): 373 txt += LEEventTexts[n]; 374 else: 375 txt = 'No LE events specified'; 376 trace.trace(8, txt); 377 378def toNumber(intArray): 379 value = 0; 380 for part in reversed(intArray): 381 value <<= 8; 382 value += part; 383 return value; 384 385def toArray(number, size): 386 array = [0 for _ in range(size)]; 387 388 for i in range(size): 389 array[i] = number & 0xFF; 390 number >>= 8; 391 return array; 392