diff options
Diffstat (limited to 'tools/csr.c')
-rw-r--r-- | tools/csr.c | 59 |
1 files changed, 57 insertions, 2 deletions
diff --git a/tools/csr.c b/tools/csr.c index c646ebde..a155efcb 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -374,6 +374,18 @@ char *csr_chipvertostr(uint16_t ver, uint16_t rev) } } +char *csr_pskeytostr(uint16_t pskey) +{ + switch (pskey) { + case CSR_PSKEY_HOSTIO_MAP_SCO_PCM: + return "Map SCO over PCM"; + case CSR_PSKEY_INITIAL_BOOTMODE: + return "Initial device bootmode"; + default: + return "Unknown"; + } +} + int csr_read_varid_uint16(int dd, uint16_t seqnum, uint16_t varid, uint16_t *value) { unsigned char cmd[] = { 0x00, 0x00, 0x09, 0x00, @@ -404,8 +416,10 @@ int csr_read_varid_uint16(int dd, uint16_t seqnum, uint16_t varid, uint16_t *val return -1; } - if ((rp[9] + (rp[10] << 8)) != 0) + if ((rp[9] + (rp[10] << 8)) != 0) { + errno = ENXIO; return -1; + } *value = rp[11] + (rp[12] << 8); @@ -442,10 +456,51 @@ int csr_read_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t *val return -1; } - if ((rp[9] + (rp[10] << 8)) != 0) + if ((rp[9] + (rp[10] << 8)) != 0) { + errno = ENXIO; return -1; + } *value = rp[17] + (rp[18] << 8); return 0; } + +int csr_write_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t value) +{ + unsigned char cmd[] = { 0x02, 0x00, 0x09, 0x00, + seqnum & 0xff, seqnum >> 8, 0x03, 0x70, 0x00, 0x00, + pskey & 0xff, pskey >> 8, 0x01, 0x00, 0x00, 0x00, + value & 0xff, value >> 8 }; + + unsigned char cp[254], rp[254]; + struct hci_request rq; + + memset(&cp, 0, sizeof(cp)); + cp[0] = 0xc2; + memcpy(cp + 1, cmd, sizeof(cmd)); + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = 0x00; + rq.event = EVT_VENDOR; + rq.cparam = cp; + rq.clen = sizeof(cmd) + 1; + rq.rparam = rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(dd, &rq, 2000) < 0) + return -1; + + if (rp[0] != 0xc2) { + errno = EIO; + return -1; + } + + if ((rp[9] + (rp[10] << 8)) != 0) { + errno = ENXIO; + return -1; + } + + return 0; +} |