static int brf_send_command_file(int fd, struct bts_action_send *send_action, long size) { unsigned char response[1024] = {0}; long ret = 0; /* send command */ if (size != write(fd, send_action, size)) { perror("Texas: Failed to write action command"); return -1; } /* read response */ ret = read_hci_event(fd, response, sizeof(response)); if (ret < 0) { perror("texas: failed to read command response"); return -1; } /* verify success */ if (ret < 7 || 0 != response[6]) { fprintf( stderr, "TI init command failed.\n" ); errno = EIO; return -1; } return 0; }
static int read_command_complete(int fd, unsigned short opcode) { struct cmd_complete resp; int err; DBG(""); err = read_hci_event(fd, (unsigned char *)&resp, sizeof(resp)); if (err < 0) return err; DBG("HCI event %d bytes", err); if (resp.uart_prefix != HCI_EVENT_PKT) { connman_error("Not an event packet"); return -EIO; } if (resp.evt != EVT_CMD_COMPLETE) { connman_error("Not a cmd complete event"); return -EIO; } if (resp.plen < 4) { connman_error("HCI header length %d", resp.plen); return -EIO; } if (resp.opcode != (unsigned short) opcode) { connman_error("opcode 0x%04x 0x%04x", resp.opcode, opcode); return -EIO; } return 0; }
static int texas(int fd, struct uart_t *u, struct termios *ti) { struct timespec tm = {0, 50000}; char cmd[10]; unsigned char resp[100]; /* Response */ int n; memset(resp,'\0', 100); /* Switch to default Texas baudrate*/ if (set_speed(fd, ti, 115200) < 0) { perror("Can't set default baud rate"); return -1; } /* It is possible to get software version with manufacturer specific HCI command HCI_VS_TI_Version_Number. But the only thing you get more is if this is point-to-point or point-to-multipoint module */ /* Get Manufacturer and LMP version */ cmd[0] = HCI_COMMAND_PKT; cmd[1] = 0x01; cmd[2] = 0x10; cmd[3] = 0x00; do { n = write(fd, cmd, 4); if (n < 0) { perror("Failed to write init command (READ_LOCAL_VERSION_INFORMATION)"); return -1; } if (n < 4) { fprintf(stderr, "Wanted to write 4 bytes, could only write %d. Stop\n", n); return -1; } /* Read reply. */ if (read_hci_event(fd, resp, 100) < 0) { perror("Failed to read init response (READ_LOCAL_VERSION_INFORMATION)"); return -1; } /* Wait for command complete event for our Opcode */ } while (resp[4] != cmd[1] && resp[5] != cmd[2]); /* Verify manufacturer */ if ((resp[11] & 0xFF) != 0x0d) fprintf(stderr,"WARNING : module's manufacturer is not Texas Instrument\n"); /* Print LMP version */ fprintf(stderr, "Texas module LMP version : 0x%02x\n", resp[10] & 0xFF); /* Print LMP subversion */ fprintf(stderr, "Texas module LMP sub-version : 0x%02x%02x\n", resp[14] & 0xFF, resp[13] & 0xFF); nanosleep(&tm, NULL); return 0; }
int texas_init(int fd, int *speed, struct termios *ti) { struct timespec tm = {0, 50000}; char cmd[4]; unsigned char resp[100]; /* Response */ const char *bts_file; int n; memset(resp,'\0', 100); /* It is possible to get software version with manufacturer specific HCI command HCI_VS_TI_Version_Number. But the only thing you get more is if this is point-to-point or point-to-multipoint module */ /* Get Manufacturer and LMP version */ cmd[0] = HCI_COMMAND_PKT; cmd[1] = 0x01; cmd[2] = 0x10; cmd[3] = 0x00; do { n = write(fd, cmd, 4); if (n < 0) { perror("Failed to write init command (READ_LOCAL_VERSION_INFORMATION)"); return -1; } if (n < 4) { fprintf(stderr, "Wanted to write 4 bytes, could only write %d. Stop\n", n); return -1; } /* Read reply. */ if (read_hci_event(fd, resp, 100) < 0) { perror("Failed to read init response (READ_LOCAL_VERSION_INFORMATION)"); return -1; } /* Wait for command complete event for our Opcode */ } while (resp[4] != cmd[1] && resp[5] != cmd[2]); /* Verify manufacturer */ if (! is_it_texas(resp)) { fprintf(stderr,"ERROR: module's manufacturer is not Texas Instruments\n"); return -1; } fprintf(stderr, "Found a Texas Instruments' chip!\n"); bts_file = get_firmware_name(resp); fprintf(stderr, "Firmware file : %s\n", bts_file); n = brf_do_script(fd, speed, ti, bts_file); nanosleep(&tm, NULL); return n; }
/* Function to read the Command complete event * * This will read the response for the change speed * command that was sent to configure the UART speed * with the custom baud rate */ static int read_command_complete(int fd, unsigned short opcode) { command_complete_t resp; UIM_START_FUNC(); UIM_VER(" Command complete started"); if (read_hci_event(fd, (unsigned char *)&resp, sizeof(resp)) < 0) { UIM_ERR("Invalid response"); return -1; } /* Response should be an event packet */ if (resp.uart_prefix != HCI_EVENT_PKT) { UIM_ERR ("Error in response: not an event packet, 0x%02x!", resp.uart_prefix); return -1; } /* Response should be a command complete event */ if (resp.hci_hdr.evt != EVT_CMD_COMPLETE) { /* event must be event-complete */ UIM_ERR("Error in response: not a cmd-complete event,0x%02x!", resp.hci_hdr.evt); return -1; } if (resp.hci_hdr.plen < 4) { /* plen >= 4 for EVT_CMD_COMPLETE */ UIM_ERR("Error in response: plen is not >= 4, but 0x%02x!", resp.hci_hdr.plen); return -1; } if (resp.cmd_complete.opcode != (unsigned short)opcode) { UIM_ERR("Error in response: opcode is 0x%04x, not 0x%04x!", resp.cmd_complete.opcode, opcode); return -1; } UIM_DBG("Command complete done"); return resp.status == 0 ? 0 : -1; }