static void reset_complete(const void *data, uint8_t size, void *user_data) { uint8_t status = *((uint8_t *) data); if (status) { fprintf(stderr, "Failed to reset (0x%02x)\n", status); mainloop_quit(); return; } mainloop_quit(); }
static void signal_callback(int signum, void *user_data) { switch (signum) { case SIGINT: case SIGTERM: mainloop_quit(); break; case SIGCHLD: while (1) { pid_t pid; int status; pid = waitpid(WAIT_ANY, &status, WNOHANG); if (pid < 0 || pid == 0) break; printf("Process %d terminated with status=%d\n", pid, status); if (pid == daemon_pid) daemon_pid = -1; else if (pid == snoop_pid) snoop_pid = -1; } break; } }
static void signal_callback(int signum, void *user_data) { switch (signum) { case SIGINT: case SIGTERM: mainloop_quit(); break; case SIGCHLD: while (1) { pid_t pid; int status; pid = waitpid(WAIT_ANY, &status, WNOHANG); if (pid < 0 || pid == 0) break; if (WIFEXITED(status)) { printf("PID %d exited (status=%d)\n", pid, WEXITSTATUS(status)); if (pid == shell_pid) exit_shell(); } else if (WIFSIGNALED(status)) { printf("PID %d terminated (signal=%d)\n", pid, WTERMSIG(status)); if (pid == shell_pid) exit_shell(); } } break; } }
static void shutdown_device(void) { bt_hci_flush(hci_dev); free(firmware_data); if (use_manufacturer_mode) { struct cmd_manufacturer_mode cmd; cmd.mode_switch = 0x00; cmd.reset = manufacturer_mode_reset; bt_hci_send(hci_dev, CMD_MANUFACTURER_MODE, &cmd, sizeof(cmd), leave_manufacturer_mode_complete, NULL, NULL); return; } if (reset_on_exit) { bt_hci_send(hci_dev, BT_HCI_CMD_RESET, NULL, 0, reset_complete, NULL, NULL); return; } mainloop_quit(); }
static void shutdown_complete(const void *data, uint8_t size, void *user_data) { unsigned int id = PTR_TO_UINT(user_data); timeout_remove(id); mainloop_quit(); }
static void enter_manufacturer_mode_complete(const void *data, uint8_t size, void *user_data) { uint8_t status = *((uint8_t *) data); if (status) { fprintf(stderr, "Failed to enter manufacturer mode (0x%02x)\n", status); mainloop_quit(); return; } if (load_firmware) { uint8_t status = BT_HCI_ERR_SUCCESS; firmware_command_complete(&status, sizeof(status), NULL); return; } if (get_bddata || set_bdaddr) { bt_hci_send(hci_dev, CMD_READ_BD_DATA, NULL, 0, read_bd_data_complete, NULL, NULL); return; } if (set_traces) { act_deact_traces(); return; } shutdown_device(); }
static void scan_le_adv_report(const void *data, uint8_t size, void *user_data) { const struct bt_hci_evt_le_adv_report *evt = data; if (evt->addr_type == 0x01 && (evt->addr[5] & 0xc0) == 0x40) { uint8_t hash[3], irk[16]; memcpy(irk, ADV_IRK, 16); bt_crypto_ah(crypto, irk, evt->addr + 3, hash); if (!memcmp(evt->addr, hash, 3)) { printf("Received advertising report\n"); print_rpa(evt->addr); memcpy(irk, ADV_IRK, 16); bt_crypto_ah(crypto, irk, evt->addr + 3, hash); printf(" -> Computed hash: %02x%02x%02x\n", hash[0], hash[1], hash[2]); mainloop_quit(); } } }
static void signal_callback(int signum, void *user_data) { switch (signum) { case SIGINT: case SIGTERM: mainloop_quit(); break; } }
static void check_quit(mrp_timer_t *timer, void *user_data) { MRP_UNUSED(user_data); if (cfg.nrunning <= 0) { mrp_del_timer(timer); mainloop_quit(&cfg); } }
static void on_name_lost (GDBusConnection *connection, const char *name, gpointer user_data) { g_debug ("Dbus - Lost or failed to acquire name %s\n", name); mainloop_quit (); }
static void leave_manufacturer_mode_complete(const void *data, uint8_t size, void *user_data) { uint8_t status = *((uint8_t *) data); if (status) { fprintf(stderr, "Failed to leave manufacturer mode (0x%02x)\n", status); mainloop_quit(); return; } if (reset_on_exit) { bt_hci_send(hci_dev, BT_HCI_CMD_RESET, NULL, 0, reset_complete, NULL, NULL); return; } mainloop_quit(); }
static void exit_shell(void) { shell_pid = -1; if (!is_init) { mainloop_quit(); return; } run_shell(); }
static void write_bd_address_complete(const void *data, uint8_t size, void *user_data) { uint8_t status = *((uint8_t *) data); if (status) { fprintf(stderr, "Failed to write address (0x%02x)\n", status); mainloop_quit(); return; } shutdown_device(); }
static void server_callback(int fd, uint32_t events, void *user_data) { union { struct sockaddr common; struct sockaddr_un sun; struct sockaddr_in sin; } addr; socklen_t len; int host_fd, dev_fd; if (events & (EPOLLERR | EPOLLHUP)) { mainloop_quit(); return; } memset(&addr, 0, sizeof(addr)); len = sizeof(addr); if (getsockname(fd, &addr.common, &len) < 0) { perror("Failed to get socket name"); return; } host_fd = accept(fd, &addr.common, &len); if (host_fd < 0) { perror("Failed to accept client socket"); return; } if (client_active) { fprintf(stderr, "Active client already present\n"); close(host_fd); return; } dev_fd = open_channel(hci_index); if (dev_fd < 0) { close(host_fd); return; } printf("New client connected\n"); if (!setup_proxy(host_fd, true, dev_fd, false)) { close(dev_fd); close(host_fd); return; } client_active = true; }
static void shutdown_device(void) { unsigned int id; bt_hci_flush(hci_dev); if (reset_on_shutdown) { id = timeout_add(5000, shutdown_timeout, NULL, NULL); bt_hci_send(hci_dev, BT_HCI_CMD_RESET, NULL, 0, shutdown_complete, UINT_TO_PTR(id), NULL); } else mainloop_quit(); }
static void signal_callback(int signum, void *user_data) { static bool terminated = false; switch (signum) { case SIGINT: case SIGTERM: if (!terminated) { mainloop_quit(); terminated = true; } break; } }
static void read_bd_addr_complete(const void *data, uint8_t size, void *user_data) { const struct bt_hci_rsp_read_bd_addr *rsp = data; struct cmd_write_bd_address cmd; if (rsp->status) { fprintf(stderr, "Failed to read address (0x%02x)\n", rsp->status); mainloop_quit(); shutdown_device(); return; } if (set_bdaddr_value) { fprintf(stderr, "Setting address is not supported\n"); mainloop_quit(); return; } printf("Controller Address\n"); printf("\tOld BD_ADDR: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n", rsp->bdaddr[5], rsp->bdaddr[4], rsp->bdaddr[3], rsp->bdaddr[2], rsp->bdaddr[1], rsp->bdaddr[0]); memcpy(cmd.bdaddr, rsp->bdaddr, 6); cmd.bdaddr[0] = (hci_index & 0xff); printf("\tNew BD_ADDR: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n", cmd.bdaddr[5], cmd.bdaddr[4], cmd.bdaddr[3], cmd.bdaddr[2], cmd.bdaddr[1], cmd.bdaddr[0]); bt_hci_send(hci_dev, CMD_WRITE_BD_ADDRESS, &cmd, sizeof(cmd), write_bd_address_complete, NULL, NULL); }
static void prompt_read_cb(int fd, uint32_t events, void *user_data) { ssize_t read; size_t len = 0; char *line = NULL; char *cmd = NULL, *args; struct server *server = user_data; int i; if (events & (EPOLLRDHUP | EPOLLHUP | EPOLLERR)) { mainloop_quit(); return; } read = getline(&line, &len, stdin); if (read < 0) return; if (read <= 1) { cmd_help(server, NULL); print_prompt(); return; } line[read-1] = '\0'; args = line; while ((cmd = strsep(&args, " \t"))) if (*cmd != '\0') break; if (!cmd) goto failed; for (i = 0; command[i].cmd; i++) { if (strcmp(command[i].cmd, cmd) == 0) break; } if (command[i].cmd) command[i].func(server, args); else fprintf(stderr, "Unknown command: %s\n", line); failed: print_prompt(); free(line); }
static void signal_callback(int fd, uint32_t events, void *user_data) { struct signal_data *data = user_data; struct signalfd_siginfo si; ssize_t result; if (events & (EPOLLERR | EPOLLHUP)) { mainloop_quit(); return; } result = read(fd, &si, sizeof(si)); if (result != sizeof(si)) return; if (data->callback) data->callback(si.ssi_signo, data->user_data); }
static void att_disconnect_cb(int err, void *user_data) { printf("Device disconnected: %s\n", strerror(err)); mainloop_quit(); }
static bool shutdown_timeout(void *user_data) { mainloop_quit(); return false; }
void mainloop_exit_success(void) { exit_status = EXIT_SUCCESS; mainloop_quit(); }
static void att_disconnect_cb(void *user_data) { printf("Device disconnected\n"); mainloop_quit(); }
void mainloop_exit_failure(void) { exit_status = EXIT_FAILURE; mainloop_quit(); }
static void read_version_complete(const void *data, uint8_t size, void *user_data) { const struct rsp_read_version *rsp = data; const char *str; int i; if (rsp->status) { fprintf(stderr, "Failed to read version (0x%02x)\n", rsp->status); mainloop_quit(); return; } if (load_firmware) { if (load_firmware_value) { printf("Firmware: %s\n", load_firmware_value); request_firmware(load_firmware_value); } else { char fw_name[PATH_MAX]; snprintf(fw_name, sizeof(fw_name), "%s/%s/ibt-hw-%x.%x.%x-fw-%x.%x.%x.%x.%x.bseq", FIRMWARE_BASE_PATH, "intel", rsp->hw_platform, rsp->hw_variant, rsp->hw_revision, rsp->fw_variant, rsp->fw_revision, rsp->fw_build_nn, rsp->fw_build_cw, rsp->fw_build_yy); printf("Firmware: %s\n", fw_name); printf("Patch level: %d\n", rsp->fw_patch); request_firmware(fw_name); } } if (use_manufacturer_mode) { struct cmd_manufacturer_mode cmd; cmd.mode_switch = 0x01; cmd.reset = 0x00; bt_hci_send(hci_dev, CMD_MANUFACTURER_MODE, &cmd, sizeof(cmd), enter_manufacturer_mode_complete, NULL, NULL); return; } if (set_bdaddr) { bt_hci_send(hci_dev, BT_HCI_CMD_READ_BD_ADDR, NULL, 0, read_bd_addr_complete, NULL, NULL); return; } printf("Controller Version Information\n"); printf("\tHardware Platform:\t%u\n", rsp->hw_platform); str = "Reserved"; for (i = 0; hw_variant_table[i].str; i++) { if (hw_variant_table[i].val == rsp->hw_variant) { str = hw_variant_table[i].str; break; } } printf("\tHardware Variant:\t%s (0x%02x)\n", str, rsp->hw_variant); printf("\tHardware Revision:\t%u.%u\n", rsp->hw_revision >> 4, rsp->hw_revision & 0x0f); str = "Reserved"; for (i = 0; fw_variant_table[i].str; i++) { if (fw_variant_table[i].val == rsp->fw_variant) { str = fw_variant_table[i].str; break; } } printf("\tFirmware Variant:\t%s (0x%02x)\n", str, rsp->fw_variant); printf("\tFirmware Revision:\t%u.%u\n", rsp->fw_revision >> 4, rsp->fw_revision & 0x0f); printf("\tFirmware Build Number:\t%u-%u.%u\n", rsp->fw_build_nn, rsp->fw_build_cw, 2000 + rsp->fw_build_yy); printf("\tFirmware Patch Number:\t%u\n", rsp->fw_patch); mainloop_quit(); }