Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Path: blob/next/external/cache/sources/hcitools/hciattach_st.c
Views: 3959
/*1*2* BlueZ - Bluetooth protocol stack for Linux3*4* Copyright (C) 2005-2010 Marcel Holtmann <[email protected]>5*6*7* This program is free software; you can redistribute it and/or modify8* it under the terms of the GNU General Public License as published by9* the Free Software Foundation; either version 2 of the License, or10* (at your option) any later version.11*12* This program is distributed in the hope that it will be useful,13* but WITHOUT ANY WARRANTY; without even the implied warranty of14* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the15* GNU General Public License for more details.16*17* You should have received a copy of the GNU General Public License18* along with this program; if not, write to the Free Software19* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA20*21*/2223#ifdef HAVE_CONFIG_H24#include <config.h>25#endif2627#include <stdio.h>28#include <errno.h>29#include <fcntl.h>30#include <unistd.h>31#include <stdlib.h>32#include <stdint.h>33#include <string.h>34#include <dirent.h>35#include <sys/param.h>3637#include <bluetooth/bluetooth.h>3839#include "hciattach.h"4041static int debug = 0;4243static int do_command(int fd, uint8_t ogf, uint16_t ocf,44uint8_t *cparam, int clen, uint8_t *rparam, int rlen)45{46//uint16_t opcode = (uint16_t) ((ocf & 0x03ff) | (ogf << 10));47unsigned char cp[260], rp[260];48int len, size, offset = 3;4950cp[0] = 0x01;51cp[1] = ocf & 0xff;52cp[2] = ogf << 2 | ocf >> 8;53cp[3] = clen;5455if (clen > 0)56memcpy(cp + 4, cparam, clen);5758if (debug) {59int i;60printf("[<");61for (i = 0; i < clen + 4; i++)62printf(" %02x", cp[i]);63printf("]\n");64}6566if (write(fd, cp, clen + 4) < 0)67return -1;6869do {70if (read(fd, rp, 1) < 1)71return -1;72} while (rp[0] != 0x04);7374if (read(fd, rp + 1, 2) < 2)75return -1;7677do {78len = read(fd, rp + offset, sizeof(rp) - offset);79offset += len;80} while (offset < rp[2] + 3);8182if (debug) {83int i;84printf("[>");85for (i = 0; i < offset; i++)86printf(" %02x", rp[i]);87printf("]\n");88}8990if (rp[0] != 0x04) {91errno = EIO;92return -1;93}9495switch (rp[1]) {96case 0x0e: /* command complete */97if (rp[6] != 0x00)98return -ENXIO;99offset = 3 + 4;100size = rp[2] - 4;101break;102case 0x0f: /* command status */103/* fall through */104default:105offset = 3;106size = rp[2];107break;108}109110if (!rparam || rlen < size)111return -ENXIO;112113memcpy(rparam, rp + offset, size);114115return size;116}117118static int load_file(int dd, uint16_t version, const char *suffix)119{120DIR *dir;121struct dirent *d;122char pathname[PATH_MAX], filename[NAME_MAX], prefix[20];123unsigned char cmd[256];124unsigned char buf[256];125uint8_t seqnum = 0;126int fd, size, len, found_fw_file;127128memset(filename, 0, sizeof(filename));129130snprintf(prefix, sizeof(prefix), "STLC2500_R%d_%02d_",131version >> 8, version & 0xff);132133strcpy(pathname, "/lib/firmware");134dir = opendir(pathname);135if (!dir) {136strcpy(pathname, ".");137dir = opendir(pathname);138if (!dir)139return -errno;140}141142found_fw_file = 0;143while (1) {144d = readdir(dir);145if (!d)146break;147148if (strncmp(d->d_name + strlen(d->d_name) - strlen(suffix),149suffix, strlen(suffix)))150continue;151152if (strncmp(d->d_name, prefix, strlen(prefix)))153continue;154155snprintf(filename, sizeof(filename), "%s/%s",156pathname, d->d_name);157found_fw_file = 1;158}159160closedir(dir);161162if (!found_fw_file)163return -ENOENT;164165printf("Loading file %s\n", filename);166167fd = open(filename, O_RDONLY);168if (fd < 0) {169perror("Can't open firmware file");170return -errno;171}172173while (1) {174size = read(fd, cmd + 1, 254);175if (size <= 0)176break;177178cmd[0] = seqnum;179180len = do_command(dd, 0xff, 0x002e, cmd, size + 1, buf, sizeof(buf));181if (len < 1)182break;183184if (buf[0] != seqnum) {185fprintf(stderr, "Sequence number mismatch\n");186break;187}188189seqnum++;190}191192close(fd);193194return 0;195}196197int stlc2500_init(int dd, bdaddr_t *bdaddr)198{199unsigned char cmd[16];200unsigned char buf[254];201uint16_t version;202int len;203int err;204205/* Hci_Cmd_Ericsson_Read_Revision_Information */206len = do_command(dd, 0xff, 0x000f, NULL, 0, buf, sizeof(buf));207if (len < 0)208return -1;209210printf("%s\n", buf);211212/* HCI_Read_Local_Version_Information */213len = do_command(dd, 0x04, 0x0001, NULL, 0, buf, sizeof(buf));214if (len < 0)215return -1;216217version = buf[2] << 8 | buf[1];218219err = load_file(dd, version, ".ptc");220if (err < 0) {221if (err == -ENOENT)222fprintf(stderr, "No ROM patch file loaded.\n");223else224return -1;225}226227err = load_file(dd, buf[2] << 8 | buf[1], ".ssf");228if (err < 0) {229if (err == -ENOENT)230fprintf(stderr, "No static settings file loaded.\n");231else232return -1;233}234235cmd[0] = 0xfe;236cmd[1] = 0x06;237bacpy((bdaddr_t *) (cmd + 2), bdaddr);238239/* Hci_Cmd_ST_Store_In_NVDS */240len = do_command(dd, 0xff, 0x0022, cmd, 8, buf, sizeof(buf));241if (len < 0)242return -1;243244/* HCI_Reset : applies parameters*/245len = do_command(dd, 0x03, 0x0003, NULL, 0, buf, sizeof(buf));246if (len < 0)247return -1;248249return 0;250}251252int bgb2xx_init(int dd, bdaddr_t *bdaddr)253{254unsigned char cmd[16];255unsigned char buf[254];256int len;257258len = do_command(dd, 0xff, 0x000f, NULL, 0, buf, sizeof(buf));259if (len < 0)260return -1;261262printf("%s\n", buf);263264cmd[0] = 0xfe;265cmd[1] = 0x06;266bacpy((bdaddr_t *) (cmd + 2), bdaddr);267268len = do_command(dd, 0xff, 0x0022, cmd, 8, buf, sizeof(buf));269if (len < 0)270return -1;271272len = do_command(dd, 0x03, 0x0003, NULL, 0, buf, sizeof(buf));273if (len < 0)274return -1;275276return 0;277}278279280