diff options
-rw-r--r-- | include/hci.h | 3 | ||||
-rw-r--r-- | include/hci_lib.h | 2 | ||||
-rw-r--r-- | src/hci.c | 67 |
3 files changed, 70 insertions, 2 deletions
diff --git a/include/hci.h b/include/hci.h index 65eabc62..4610ac00 100644 --- a/include/hci.h +++ b/include/hci.h @@ -139,7 +139,7 @@ enum { #define LMP_TACCURACY 0x10 #define LMP_RSWITCH 0x20 #define LMP_HOLD 0x40 -#define LMP_SNIF 0x80 +#define LMP_SNIFF 0x80 #define LMP_PARK 0x01 #define LMP_RSSI 0x02 @@ -153,6 +153,7 @@ enum { #define LMP_CVSD 0x01 #define LMP_PSCHEME 0x02 #define LMP_PCONTROL 0x04 +#define LMP_TRSP_SCO 0x08 /* Link policies */ #define HCI_LP_RSWITCH 0x0001 diff --git a/include/hci_lib.h b/include/hci_lib.h index ed3306ab..10374a30 100644 --- a/include/hci_lib.h +++ b/include/hci_lib.h @@ -82,6 +82,8 @@ int hci_strtover(char *str, unsigned int *ver); char *lmp_vertostr(unsigned int ver); int lmp_strtover(char *str, unsigned int *ver); +char *lmp_featurestostr(uint8_t *features, char *pref, int width); + static inline void hci_set_bit(int nr, void *addr) { *((uint32_t *) addr + (nr >> 5)) |= (1 << (nr & 31)); @@ -53,7 +53,7 @@ typedef struct { static char *hci_bit2str(hci_map *m, unsigned int val) { - char *str = malloc(50); + char *str = malloc(120); char *ptr = str; if (!str) @@ -287,6 +287,71 @@ int lmp_strtover(char *str, unsigned int *ver) return hci_str2uint(ver_map, str, ver); } +/* LMP features mapping */ +hci_map lmp_features_map[][9] = { + { /* byte 0 */ + { "<3-slot packets>", LMP_3SLOT }, + { "<5-slot packets>", LMP_5SLOT }, + { "<encryption>", LMP_ENCRYPT }, + { "<slot offset>", LMP_SOFFSET }, + { "<timing accuracy>", LMP_TACCURACY}, + { "<role switch>", LMP_RSWITCH }, + { "<hold mode>", LMP_HOLD }, + { "<sniff mode>", LMP_SNIFF }, + { NULL } + }, + { /* byte 1 */ + { "<park mode>", LMP_PARK }, + { "<RSSI>", LMP_RSSI }, + { "<channel quality>", LMP_QUALITY }, + { "<SCO link>", LMP_SCO }, + { "<HV2 packets>", LMP_HV2 }, + { "<HV3 packets>", LMP_HV3 }, + { "<u-law log>", LMP_ULAW }, + { "<A-law log>", LMP_ALAW }, + { NULL } + }, + { /* byte 2 */ + { "<CVSD>", LMP_CVSD }, + { "<paging scheme>", LMP_PSCHEME }, + { "<power control>", LMP_PCONTROL }, + { "<transparent SCO>", LMP_TRSP_SCO }, + { NULL } + }, + {{ NULL }} +}; + +char *lmp_featurestostr(uint8_t *features, char *pref, int width) +{ + char *ptr, *str = malloc(400); + int i, w; + + if (!str) + return NULL; + + ptr = str; *ptr = 0; + + if (pref) + ptr += sprintf(ptr, "%s", pref); + + for(i=0, w=0; lmp_features_map[i][0].str; i++) { + hci_map *m; + + m = lmp_features_map[i]; + while (m->str) { + if ((unsigned int) m->val & (unsigned int) features[i]) + ptr += sprintf(ptr, "%s ", m->str); + m++; + + w = (w + 1) & width; + if (!w) + ptr += sprintf(ptr, "\n%s", pref); + } + } + + return str; +} + /* HCI functions that do not require open device */ int hci_devinfo(int dev_id, struct hci_dev_info *di) |