1
0
mirror of https://github.com/kellyjonbrazil/jc.git synced 2025-07-07 00:57:22 +02:00

initial working hciconfig parser

This commit is contained in:
Kelly Brazil
2021-02-09 16:03:00 -08:00
parent 229e953a38
commit c672d1c174
7 changed files with 902 additions and 21 deletions

View File

@ -1,5 +1,8 @@
jc changelog
20210209 v1.14.3
- Add hciconfig parser tested on linux
20210205 v1.14.2
- Update dig parser to fix cases where there are spaces in the answer data (e.g. TXT records)

View File

@ -915,6 +915,132 @@ md5sum * | jc --hashsum -p # or: jc -p md5sum *
}
]
```
### hciconfig
```bash
hciconfig -a | jc --hciconfig -p # or: jc -p hciconfig -a
```
```json
[
{
"device": "hci0",
"type": "Primary",
"bus": "USB",
"bd_address": "00:1A:7D:DA:71:13",
"acl_mtu": 310,
"acl_mtu_packets": 10,
"sco_mtu": 64,
"sco_mtu_packets": 8,
"state": [
"UP",
"RUNNING"
],
"rx_bytes": 13905869,
"rx_acl": 0,
"rx_sco": 0,
"rx_events": 393300,
"rx_errors": 0,
"tx_bytes": 62629,
"tx_acl": 0,
"tx_sco": 0,
"tx_commands": 3893,
"tx_errors": 0,
"features": [
"0xff",
"0xff",
"0x8f",
"0xfe",
"0xdb",
"0xff",
"0x5b",
"0x87"
],
"packet_type": [
"DM1",
"DM3",
"DM5",
"DH1",
"DH3",
"DH5",
"HV1",
"HV2",
"HV3"
],
"link_policy": [
"RSWITCH",
"HOLD",
"SNIFF",
"PARK"
],
"link_mode": [
"SLAVE",
"ACCEPT"
],
"name": "CSR8510 A10",
"class": "0x000000",
"service_classes": null,
"device_class": "Miscellaneous",
"hci_version": "4.0 (0x6)",
"hci_revision": "0x22bb",
"lmp_version": "4.0 (0x6)",
"lmp_subversion": "0x22bb",
"manufacturer": "Cambridge Silicon Radio (10)"
},
{
"device": "hci1",
"type": "Primary",
"bus": "USB",
"bd_address": "00:1A:7D:DA:71:13",
"acl_mtu": 310,
"acl_mtu_packets": 10,
"sco_mtu": 64,
"sco_mtu_packets": 8,
"state": [
"DOWN"
],
"rx_bytes": 4388363,
"rx_acl": 0,
"rx_sco": 0,
"rx_events": 122021,
"rx_errors": 0,
"tx_bytes": 52350,
"tx_acl": 0,
"tx_sco": 0,
"tx_commands": 3480,
"tx_errors": 2,
"features": [
"0xff",
"0xff",
"0x8f",
"0xfe",
"0xdb",
"0xff",
"0x5b",
"0x87"
],
"packet_type": [
"DM1",
"DM3",
"DM5",
"DH1",
"DH3",
"DH5",
"HV1",
"HV2",
"HV3"
],
"link_policy": [
"RSWITCH",
"HOLD",
"SNIFF",
"PARK"
],
"link_mode": [
"SLAVE",
"ACCEPT"
]
}
]
```
### history
```bash
history | jc --history -p

View File

@ -139,6 +139,7 @@ The JSON output can be compact (default) or pretty formatted with the `-p` optio
- `--gshadow` enables the `/etc/gshadow` file parser
- `--hash` enables the `hash` command parser
- `--hashsum` enables the `hashsum` command parser (`md5`, `md5sum`, `shasum`, `sha1sum`, `sha224sum`, `sha256sum`, `sha384sum`, `sha512sum`)
- `--hciconfig` enables the `hciconfig` command parser
- `--history` enables the `history` command parser
- `--hosts` enables the `/etc/hosts` file parser
- `--id` enables the `id` command parser

View File

@ -26,6 +26,7 @@ pydocmd simple jc.parsers.group+ > ../docs/parsers/group.md
pydocmd simple jc.parsers.gshadow+ > ../docs/parsers/gshadow.md
pydocmd simple jc.parsers.hash+ > ../docs/parsers/hash.md
pydocmd simple jc.parsers.hashsum+ > ../docs/parsers/hashsum.md
pydocmd simple jc.parsers.hciconfig+ > ../docs/parsers/hciconfig.md
pydocmd simple jc.parsers.history+ > ../docs/parsers/history.md
pydocmd simple jc.parsers.hosts+ > ../docs/parsers/hosts.md
pydocmd simple jc.parsers.id+ > ../docs/parsers/id.md

358
docs/parsers/hciconfig.md Normal file
View File

@ -0,0 +1,358 @@
# jc.parsers.hciconfig
jc - JSON CLI output utility `hciconfig` command output parser
Usage (cli):
$ hciconfig | jc --hciconfig
or
$ jc hciconfig
Usage (module):
import jc.parsers.hciconfig
result = jc.parsers.hciconfig.parse(hciconfig_command_output)
Compatibility:
'linux'
Examples:
$ hciconfig -a | jc --hciconfig -p
[
{
"device": "hci0",
"type": "Primary",
"bus": "USB",
"bd_address": "00:1A:7D:DA:71:13",
"acl_mtu": 310,
"acl_mtu_packets": 10,
"sco_mtu": 64,
"sco_mtu_packets": 8,
"state": [
"UP",
"RUNNING"
],
"rx_bytes": 13905869,
"rx_acl": 0,
"rx_sco": 0,
"rx_events": 393300,
"rx_errors": 0,
"tx_bytes": 62629,
"tx_acl": 0,
"tx_sco": 0,
"tx_commands": 3893,
"tx_errors": 0,
"features": [
"0xff",
"0xff",
"0x8f",
"0xfe",
"0xdb",
"0xff",
"0x5b",
"0x87"
],
"packet_type": [
"DM1",
"DM3",
"DM5",
"DH1",
"DH3",
"DH5",
"HV1",
"HV2",
"HV3"
],
"link_policy": [
"RSWITCH",
"HOLD",
"SNIFF",
"PARK"
],
"link_mode": [
"SLAVE",
"ACCEPT"
],
"name": "CSR8510 A10",
"class": "0x000000",
"service_classes": null,
"device_class": "Miscellaneous",
"hci_version": "4.0 (0x6)",
"hci_revision": "0x22bb",
"lmp_version": "4.0 (0x6)",
"lmp_subversion": "0x22bb",
"manufacturer": "Cambridge Silicon Radio (10)"
},
{
"device": "hci1",
"type": "Primary",
"bus": "USB",
"bd_address": "00:1A:7D:DA:71:13",
"acl_mtu": 310,
"acl_mtu_packets": 10,
"sco_mtu": 64,
"sco_mtu_packets": 8,
"state": [
"DOWN"
],
"rx_bytes": 4388363,
"rx_acl": 0,
"rx_sco": 0,
"rx_events": 122021,
"rx_errors": 0,
"tx_bytes": 52350,
"tx_acl": 0,
"tx_sco": 0,
"tx_commands": 3480,
"tx_errors": 2,
"features": [
"0xff",
"0xff",
"0x8f",
"0xfe",
"0xdb",
"0xff",
"0x5b",
"0x87"
],
"packet_type": [
"DM1",
"DM3",
"DM5",
"DH1",
"DH3",
"DH5",
"HV1",
"HV2",
"HV3"
],
"link_policy": [
"RSWITCH",
"HOLD",
"SNIFF",
"PARK"
],
"link_mode": [
"SLAVE",
"ACCEPT"
]
}
]
$ hciconfig -a | jc --hciconfig -p -r
[
{
"device": "hci0",
"type": "Primary",
"bus": "USB",
"bd_address": "00:1A:7D:DA:71:13",
"acl_mtu": "310",
"acl_mtu_packets": "10",
"sco_mtu": "64",
"sco_mtu_packets": "8",
"state": [
"UP",
"RUNNING"
],
"rx_bytes": "13905869",
"rx_acl": "0",
"rx_sco": "0",
"rx_events": "393300",
"rx_errors": "0",
"tx_bytes": "62629",
"tx_acl": "0",
"tx_sco": "0",
"tx_commands": "3893",
"tx_errors": "0",
"features": [
"0xff",
"0xff",
"0x8f",
"0xfe",
"0xdb",
"0xff",
"0x5b",
"0x87"
],
"packet_type": [
"DM1",
"DM3",
"DM5",
"DH1",
"DH3",
"DH5",
"HV1",
"HV2",
"HV3"
],
"link_policy": [
"RSWITCH",
"HOLD",
"SNIFF",
"PARK"
],
"link_mode": [
"SLAVE",
"ACCEPT"
],
"name": "CSR8510 A10",
"class": "0x000000",
"service_classes": [
"Unspecified"
],
"device_class": "Miscellaneous",
"hci_version": "4.0 (0x6)",
"hci_revision": "0x22bb",
"lmp_version": "4.0 (0x6)",
"lmp_subversion": "0x22bb",
"manufacturer": "Cambridge Silicon Radio (10)"
},
{
"device": "hci1",
"type": "Primary",
"bus": "USB",
"bd_address": "00:1A:7D:DA:71:13",
"acl_mtu": "310",
"acl_mtu_packets": "10",
"sco_mtu": "64",
"sco_mtu_packets": "8",
"state": [
"DOWN"
],
"rx_bytes": "4388363",
"rx_acl": "0",
"rx_sco": "0",
"rx_events": "122021",
"rx_errors": "0",
"tx_bytes": "52350",
"tx_acl": "0",
"tx_sco": "0",
"tx_commands": "3480",
"tx_errors": "2",
"features": [
"0xff",
"0xff",
"0x8f",
"0xfe",
"0xdb",
"0xff",
"0x5b",
"0x87"
],
"packet_type": [
"DM1",
"DM3",
"DM5",
"DH1",
"DH3",
"DH5",
"HV1",
"HV2",
"HV3"
],
"link_policy": [
"RSWITCH",
"HOLD",
"SNIFF",
"PARK"
],
"link_mode": [
"SLAVE",
"ACCEPT"
]
}
]
## info
```python
info()
```
## process
```python
process(proc_data)
```
Final processing to conform to the schema.
Parameters:
proc_data: (List of Dictionaries) raw structured data to process
Returns:
List of Dictionaries. Structured data with the following schema:
[
{
"device": string,
"type": string,
"bus": string,
"bd_address": string,
"acl_mtu": integer,
"acl_mtu_packets": integer,
"sco_mtu": integer,
"sco_mtu_packets": integer,
"state": [
string
],
"rx_bytes": integer,
"rx_acl": integer,
"rx_sco": integer,
"rx_events": integer,
"rx_errors": integer,
"tx_bytes": integer,
"tx_acl": integer,
"tx_sco": integer,
"tx_commands": integer,
"tx_errors": integer,
"features": [
string
],
"packet_type": [
string
],
"link_policy": [
string
],
"link_mode": [
string
],
"name": string,
"class": string,
"service_classes": [
string # 'Unspecified' is null
],
"device_class": string,
"hci_version": string,
"hci_revision": string,
"lmp_version": string,
"lmp_subversion": string,
"manufacturer": string
}
]
## parse
```python
parse(data, raw=False, quiet=False)
```
Main text parsing function
Parameters:
data: (string) text data to parse
raw: (boolean) output preprocessed JSON if True
quiet: (boolean) suppress warning messages if True
Returns:
List of Dictionaries. Raw or processed structured data.

View File

@ -1,7 +1,5 @@
"""jc - JSON CLI output utility `hciconfig` command output parser
<<Short hciconfig description and caveats>>
Usage (cli):
$ hciconfig | jc --hciconfig
@ -21,11 +19,251 @@ Compatibility:
Examples:
$ hciconfig | jc --hciconfig -p
[]
$ hciconfig -a | jc --hciconfig -p
[
{
"device": "hci0",
"type": "Primary",
"bus": "USB",
"bd_address": "00:1A:7D:DA:71:13",
"acl_mtu": 310,
"acl_mtu_packets": 10,
"sco_mtu": 64,
"sco_mtu_packets": 8,
"state": [
"UP",
"RUNNING"
],
"rx_bytes": 13905869,
"rx_acl": 0,
"rx_sco": 0,
"rx_events": 393300,
"rx_errors": 0,
"tx_bytes": 62629,
"tx_acl": 0,
"tx_sco": 0,
"tx_commands": 3893,
"tx_errors": 0,
"features": [
"0xff",
"0xff",
"0x8f",
"0xfe",
"0xdb",
"0xff",
"0x5b",
"0x87"
],
"packet_type": [
"DM1",
"DM3",
"DM5",
"DH1",
"DH3",
"DH5",
"HV1",
"HV2",
"HV3"
],
"link_policy": [
"RSWITCH",
"HOLD",
"SNIFF",
"PARK"
],
"link_mode": [
"SLAVE",
"ACCEPT"
],
"name": "CSR8510 A10",
"class": "0x000000",
"service_classes": null,
"device_class": "Miscellaneous",
"hci_version": "4.0 (0x6)",
"hci_revision": "0x22bb",
"lmp_version": "4.0 (0x6)",
"lmp_subversion": "0x22bb",
"manufacturer": "Cambridge Silicon Radio (10)"
},
{
"device": "hci1",
"type": "Primary",
"bus": "USB",
"bd_address": "00:1A:7D:DA:71:13",
"acl_mtu": 310,
"acl_mtu_packets": 10,
"sco_mtu": 64,
"sco_mtu_packets": 8,
"state": [
"DOWN"
],
"rx_bytes": 4388363,
"rx_acl": 0,
"rx_sco": 0,
"rx_events": 122021,
"rx_errors": 0,
"tx_bytes": 52350,
"tx_acl": 0,
"tx_sco": 0,
"tx_commands": 3480,
"tx_errors": 2,
"features": [
"0xff",
"0xff",
"0x8f",
"0xfe",
"0xdb",
"0xff",
"0x5b",
"0x87"
],
"packet_type": [
"DM1",
"DM3",
"DM5",
"DH1",
"DH3",
"DH5",
"HV1",
"HV2",
"HV3"
],
"link_policy": [
"RSWITCH",
"HOLD",
"SNIFF",
"PARK"
],
"link_mode": [
"SLAVE",
"ACCEPT"
]
}
]
$ hciconfig | jc --hciconfig -p -r
[]
$ hciconfig -a | jc --hciconfig -p -r
[
{
"device": "hci0",
"type": "Primary",
"bus": "USB",
"bd_address": "00:1A:7D:DA:71:13",
"acl_mtu": "310",
"acl_mtu_packets": "10",
"sco_mtu": "64",
"sco_mtu_packets": "8",
"state": [
"UP",
"RUNNING"
],
"rx_bytes": "13905869",
"rx_acl": "0",
"rx_sco": "0",
"rx_events": "393300",
"rx_errors": "0",
"tx_bytes": "62629",
"tx_acl": "0",
"tx_sco": "0",
"tx_commands": "3893",
"tx_errors": "0",
"features": [
"0xff",
"0xff",
"0x8f",
"0xfe",
"0xdb",
"0xff",
"0x5b",
"0x87"
],
"packet_type": [
"DM1",
"DM3",
"DM5",
"DH1",
"DH3",
"DH5",
"HV1",
"HV2",
"HV3"
],
"link_policy": [
"RSWITCH",
"HOLD",
"SNIFF",
"PARK"
],
"link_mode": [
"SLAVE",
"ACCEPT"
],
"name": "CSR8510 A10",
"class": "0x000000",
"service_classes": [
"Unspecified"
],
"device_class": "Miscellaneous",
"hci_version": "4.0 (0x6)",
"hci_revision": "0x22bb",
"lmp_version": "4.0 (0x6)",
"lmp_subversion": "0x22bb",
"manufacturer": "Cambridge Silicon Radio (10)"
},
{
"device": "hci1",
"type": "Primary",
"bus": "USB",
"bd_address": "00:1A:7D:DA:71:13",
"acl_mtu": "310",
"acl_mtu_packets": "10",
"sco_mtu": "64",
"sco_mtu_packets": "8",
"state": [
"DOWN"
],
"rx_bytes": "4388363",
"rx_acl": "0",
"rx_sco": "0",
"rx_events": "122021",
"rx_errors": "0",
"tx_bytes": "52350",
"tx_acl": "0",
"tx_sco": "0",
"tx_commands": "3480",
"tx_errors": "2",
"features": [
"0xff",
"0xff",
"0x8f",
"0xfe",
"0xdb",
"0xff",
"0x5b",
"0x87"
],
"packet_type": [
"DM1",
"DM3",
"DM5",
"DH1",
"DH3",
"DH5",
"HV1",
"HV2",
"HV3"
],
"link_policy": [
"RSWITCH",
"HOLD",
"SNIFF",
"PARK"
],
"link_mode": [
"SLAVE",
"ACCEPT"
]
}
]
"""
import jc.utils
@ -95,19 +333,33 @@ def process(proc_data):
"name": string,
"class": string,
"service_classes": [
string
string # 'Unspecified' is null
],
"device_class": string,
"hci_version": string,
"revision": string,
"hci_revision": string,
"lmp_version": string,
"subversion": string,
"lmp_subversion": string,
"manufacturer": string
}
]
"""
# rebuild output for added semantic information
for entry in proc_data:
# integers
int_list = ['acl_mtu', 'acl_mtu_packets', 'sco_mtu', 'sco_mtu_packets', 'rx_bytes', 'rx_acl', 'rx_sco',
'rx_events', 'rx_errors', 'tx_bytes', 'tx_acl', 'tx_sco', 'tx_commands', 'tx_errors']
for key in int_list:
if key in entry:
try:
entry[key] = int(entry[key])
except (ValueError):
entry[key] = None
if 'service_classes' in entry and len(entry['service_classes']) == 1 and 'Unspecified' in entry['service_classes']:
entry['service_classes'] = None
return proc_data
@ -129,12 +381,148 @@ def parse(data, raw=False, quiet=False):
jc.utils.compatibility(__name__, info.compatible)
raw_output = []
device_object = {}
line_count = 0
if jc.utils.has_data(data):
for line in filter(None, data.splitlines()):
# parse the content
pass
line_count += 1
# print(line)
# start of a new device object
# hci0: Type: Primary Bus: USB
if not line.startswith(' '):
if device_object:
raw_output.append(device_object)
device_object = {}
line_count = 1
line = line.replace(':', '')
line = line.split()
device_object['device'] = line[0]
device_object['type'] = line[2]
device_object['bus'] = line[4]
continue
# BD Address: 00:50:56:E7:46:1A ACL MTU: 8192:128 SCO MTU: 64:128
if line.startswith(' ') and ' BD Address:' in line:
line = line.split()
device_object['bd_address'] = line[2]
device_object['acl_mtu'] = line[5].split(':')[0]
device_object['acl_mtu_packets'] = line[5].split(':')[1]
device_object['sco_mtu'] = line[8].split(':')[0]
device_object['sco_mtu_packets'] = line[8].split(':')[1]
continue
# UP RUNNING (always line 3)
if line_count == 3:
device_object['state'] = line.split()
continue
# RX bytes:1307 acl:0 sco:0 events:51 errors:0
if line.startswith(' ') and ' RX bytes:' in line:
line = line.replace(':', ' ')
line = line.split()
device_object['rx_bytes'] = line[2]
device_object['rx_acl'] = line[4]
device_object['rx_sco'] = line[6]
device_object['rx_events'] = line[8]
device_object['rx_errors'] = line[10]
continue
# TX bytes:1200 acl:0 sco:0 commands:51 errors:0
if line.startswith(' ') and ' TX bytes:' in line:
line = line.replace(':', ' ')
line = line.split()
device_object['tx_bytes'] = line[2]
device_object['tx_acl'] = line[4]
device_object['tx_sco'] = line[6]
device_object['tx_commands'] = line[8]
device_object['tx_errors'] = line[10]
continue
# Features: 0xff 0xff 0x8f 0xfe 0x83 0xe1 0x08 0x80
if line.startswith(' ') and line.lstrip().startswith('Features:'):
device_object['features'] = line.split()[1:]
continue
# Packet type: DM1 DM3 DM5 DH1 DH3 DH5 HV1 HV2 HV3
if line.startswith(' ') and line.lstrip().startswith('Packet type:'):
device_object['packet_type'] = line.split()[2:]
continue
# Link policy: RSWITCH HOLD SNIFF PARK
if line.startswith(' ') and line.lstrip().startswith('Link policy:'):
device_object['link_policy'] = line.split()[2:]
continue
# Link mode: SLAVE ACCEPT
if line.startswith(' ') and line.lstrip().startswith('Link mode:'):
device_object['link_mode'] = line.split()[2:]
continue
# Name: 'kbrazil-ubuntu'
if line.startswith(' ') and line.lstrip().startswith('Name:'):
device_object['name'] = line.split(maxsplit=1)[1][1:-1]
continue
# Class: 0x000000
if line.startswith(' ') and line.lstrip().startswith('Class:'):
device_object['class'] = line.split(maxsplit=1)[1]
continue
# Service Classes: Unspecified
if line.startswith(' ') and line.lstrip().startswith('Service Classes:'):
device_object['service_classes'] = line.split()[2:]
continue
# Device Class: Miscellaneous,
if line.startswith(' ') and line.lstrip().startswith('Device Class:'):
dev_class = line.split()[2]
if dev_class.endswith(','):
dev_class = dev_class[0:-1]
device_object['device_class'] = dev_class
continue
# HCI Version: 4.0 (0x6) Revision: 0x22bb
if line.startswith(' ') and line.lstrip().startswith('HCI Version:'):
line = line.split()
device_object['hci_version'] = ' '.join(line[2:4])
device_object['hci_revision'] = line[5]
continue
# LMP Version: 4.0 (0x6) Subversion: 0x22bb
if line.startswith(' ') and line.lstrip().startswith('LMP Version:'):
line = line.split()
device_object['lmp_version'] = ' '.join(line[2:4])
device_object['lmp_subversion'] = line[5]
continue
# Manufacturer: Cambridge Silicon Radio (10)
if line.startswith(' ') and line.lstrip().startswith('Manufacturer:'):
device_object['manufacturer'] = line.split(maxsplit=1)[1]
continue
if device_object:
raw_output.append(device_object)
if raw:
return raw_output

View File

@ -1,4 +1,4 @@
.TH jc 1 2021-01-05 1.14.1 "JSON CLI output utility"
.TH jc 1 2021-01-05 1.14.3 "JSON CLI output utility"
.SH NAME
jc \- JSONifies the output of many CLI tools and file-types
.SH SYNOPSIS
@ -92,6 +92,18 @@ fstab file parser
/etc/gshadow file parser
.TP
.B
\fB--hash\fP
hash BASH builtin command parser
.TP
.B
\fB--hashsum\fP
md5, md5sum, shasum, sha1sum, sha224sum, sha256sum, sha384sum, and sha512sum command parser
.TP
.B
\fB--hciconfig\fP
hciconfig command parser
.TP
.B
\fB--history\fP
history command parser
.TP
@ -120,14 +132,6 @@ iptables command parser
iw dev <device> scan command parser
.TP
.B
\fB--hash\fP
hash BASH builtin command parser
.TP
.B
\fB--hashsum\fP
md5, md5sum, shasum, sha1sum, sha224sum, sha256sum, sha384sum, and sha512sum command parser
.TP
.B
\fB--jobs\fP
jobs command parser
.TP