static void act_deact_traces_complete(const void *data, uint8_t size, void *user_data) { uint8_t status = *((uint8_t *) data); if (status) { fprintf(stderr, "Failed to activate traces (0x%02x)\n", status); shutdown_device(); return; } shutdown_device(); }
static void read_clock(const void *data, uint8_t size, void *user_data) { const struct bt_hci_rsp_read_clock *rsp = data; struct broadcast_message msg; uint8_t bcastdata[sizeof(msg) + 3] = { LT_ADDR, 0x03, 0x11, }; if (rsp->status) { printf("Failed to read local clock information\n"); shutdown_device(); return; } msg.frame_sync_instant = rsp->clock; msg.bluetooth_clock_phase = rsp->accuracy; msg.left_open_offset = cpu_to_le16(50); msg.left_close_offset = cpu_to_le16(300); msg.right_open_offset = cpu_to_le16(350); msg.right_close_offset = cpu_to_le16(600); msg.frame_sync_period = cpu_to_le16(650); msg.frame_sync_period_fraction = 0; memcpy(bcastdata + 3, &msg, sizeof(msg)); bt_hci_send(hci_dev, BT_HCI_CMD_SET_SLAVE_BROADCAST_DATA, bcastdata, sizeof(bcastdata), NULL, NULL, NULL); }
static void setup_internal_mux(struct ofono_modem *modem) { struct ifx_data *data = ofono_modem_get_data(modem); int i; DBG(""); data->mux = g_at_mux_new_gsm0710_basic(data->device, data->frame_size); if (data->mux == NULL) goto error; if (getenv("OFONO_MUX_DEBUG")) g_at_mux_set_debug(data->mux, ifx_debug, "MUX: "); g_at_mux_start(data->mux); for (i = 0; i < NUM_DLC; i++) { GIOChannel *channel = g_at_mux_create_channel(data->mux); data->dlcs[i] = create_chat(channel, modem, dlc_prefixes[i]); if (data->dlcs[i] == NULL) { ofono_error("Failed to create channel"); goto error; } } /* wait for DLC creation to settle */ data->dlc_init_source = g_timeout_add(500, dlc_setup, modem); return; error: shutdown_device(data); ofono_modem_set_powered(modem, FALSE); }
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(); }
/* * Main timer handle: check every PWRKEY_DETECT_FREQUENCY to see * if power key is pressed. * Shutdown the device if power key is release before * (PWRKEY_LONG_PRESS_COUNT/MPM_SLEEP_TIMETICK_COUNT) seconds. */ static enum handler_return long_press_pwrkey_timer_func(struct timer *p_timer, void *arg) { uint32_t sclk_count = platform_get_sclk_count(); /* * The following condition is treated as the power key * is pressed long enough. * 1. if the power key is pressed last for PWRKEY_LONG_PRESS_COUNT. */ if (sclk_count > PWRKEY_LONG_PRESS_COUNT) { timer_cancel(p_timer); pon_timer_complete = 1; } else { if (pm8x41_get_pwrkey_is_pressed()) { /* * For normal man response is > 0.1 secs, so we use 0.05 secs default * for software to be safely detect if there is a key release action. */ timer_set_oneshot(p_timer, PWRKEY_DETECT_FREQUENCY, long_press_pwrkey_timer_func, NULL); } else { shutdown_device(); } } return INT_RESCHEDULE; }
static void target_shutdown_for_pwrkey(void) { if (pu_reason == PWR_ON_EVENT_KEYPAD && target_check_keyinfo() == 0) { dprintf(CRITICAL, "Key is not pressed long enough\n"); shutdown_device(); } }
static void read_bd_data_complete(const void *data, uint8_t size, void *user_data) { const struct rsp_read_bd_data *rsp = data; if (rsp->status) { fprintf(stderr, "Failed to read data (0x%02x)\n", rsp->status); shutdown_device(); return; } printf("Controller Data\n"); printf("\tBD_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]); printf("\tLMP Version: %u\n", rsp->lmp_version); printf("\tLMP Features: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x" " 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", rsp->features[0], rsp->features[1], rsp->features[2], rsp->features[3], rsp->features[4], rsp->features[5], rsp->features[6], rsp->features[7]); printf("\tLE Features: 0x%2.2x\n", rsp->le_features); if (set_bdaddr) { struct cmd_write_bd_data cmd; memcpy(cmd.bdaddr, rsp->bdaddr, 6); cmd.bdaddr[0] = (hci_index & 0xff); cmd.lmp_version = 0x07; memcpy(cmd.features, rsp->features, 8); cmd.le_features = rsp->le_features; cmd.le_features |= 0x1e; memcpy(cmd.reserved1, rsp->reserved1, sizeof(cmd.reserved1)); memcpy(cmd.reserved2, rsp->reserved2, sizeof(cmd.reserved2)); memcpy(cmd.reserved3, rsp->reserved3, sizeof(cmd.reserved3)); bt_hci_send(hci_dev, CMD_WRITE_BD_DATA, &cmd, sizeof(cmd), write_bd_data_complete, NULL, NULL); return; } shutdown_device(); }
static void target_shutdown_for_rtc_alarm(void) { if (target_check_power_on_reason() == PWR_ON_EVENT_RTC_ALARM) { dprintf(CRITICAL, "Power on due to RTC alarm. Going to shutdown!!\n"); pm8058_rtc0_alarm_irq_disable(); shutdown_device(); } }
static void write_bd_data_complete(const void *data, uint8_t size, void *user_data) { uint8_t status = *((uint8_t *) data); if (status) { fprintf(stderr, "Failed to write data (0x%02x)\n", status); shutdown_device(); return; } if (set_traces) { act_deact_traces(); return; } shutdown_device(); }
static void firmware_command_complete(const void *data, uint8_t size, void *user_data) { uint8_t status = *((uint8_t *) data); if (status) { fprintf(stderr, "Failed to load firmware (0x%02x)\n", status); manufacturer_mode_reset = 0x01; shutdown_device(); return; } if (firmware_offset >= firmware_size) { printf("Activating firmware\n"); manufacturer_mode_reset = 0x02; shutdown_device(); return; } if (firmware_data[firmware_offset] == 0x01) { uint16_t opcode; uint8_t dlen; opcode = firmware_data[firmware_offset + 2] << 8 | firmware_data[firmware_offset + 1]; dlen = firmware_data[firmware_offset + 3]; bt_hci_send(hci_dev, opcode, firmware_data + firmware_offset + 4, dlen, firmware_command_complete, NULL, NULL); firmware_offset += dlen + 4; if (firmware_data[firmware_offset] == 0x02) { dlen = firmware_data[firmware_offset + 2]; firmware_offset += dlen + 3; } } else { fprintf(stderr, "Invalid packet in firmware\n"); manufacturer_mode_reset = 0x01; shutdown_device(); } }
static void target_shutdown_for_battinfo(void) { unsigned battinfo = 0; battinfo = target_check_battinfo(); if (battinfo == 0x10) { dprintf(INFO, "Battery is weak and no charger\n"); shutdown_device(); } }
static void dlc_disconnect(gpointer user_data) { struct ofono_modem *modem = user_data; struct ifx_data *data = ofono_modem_get_data(modem); DBG(""); ofono_warn("Disconnect of modem channel"); shutdown_device(data); }
static void local_features_callback(const void *data, uint8_t size, void *user_data) { const struct bt_hci_rsp_read_local_features *rsp = data; if (rsp->status) { fprintf(stderr, "Failed to read local features\n"); shutdown_device(); return; } if (!(rsp->features[4] & 0x40)) { fprintf(stderr, "Controller without Low Energy support\n"); shutdown_device(); return; } bt_hci_send(hci_dev, BT_HCI_CMD_LE_READ_ADV_TX_POWER, NULL, 0, adv_tx_power_callback, NULL, NULL); }
static void inquiry_started(const void *data, uint8_t size, void *user_data) { uint8_t status = *((uint8_t *) data); if (status) { printf("Failed to search for 3D display\n"); shutdown_device(); return; } printf("Searching for 3D display\n"); }
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 xgendata_query(gboolean ok, GAtResult *result, gpointer user_data) { struct ofono_modem *modem = user_data; struct ifx_data *data = ofono_modem_get_data(modem); GAtResultIter iter; const char *gendata; DBG(""); if (!ok) goto error; g_at_result_iter_init(&iter, result); if (!g_at_result_iter_next(&iter, "+XGENDATA:")) goto error; if (!g_at_result_iter_next_string(&iter, &gendata)) goto error; DBG("\n%s", gendata); /* switch to GSM character set instead of IRA */ g_at_chat_send(data->dlcs[AUX_DLC], "AT+CSCS=\"GSM\"", none_prefix, NULL, NULL, NULL); /* disable UART for power saving */ g_at_chat_send(data->dlcs[AUX_DLC], "AT+XPOW=0,0,0", none_prefix, NULL, NULL, NULL); data->have_sim = FALSE; /* notify that the modem is ready so that pre_sim gets called */ ofono_modem_set_powered(modem, TRUE); g_at_chat_register(data->dlcs[AUX_DLC], "+XSIM:", xsim_notify, FALSE, modem, NULL); /* enable XSIM and XLOCK notifications */ g_at_chat_send(data->dlcs[AUX_DLC], "AT+XSIMSTATE=1", none_prefix, NULL, NULL, NULL); g_at_chat_send(data->dlcs[AUX_DLC], "AT+XSIMSTATE?", xsimstate_prefix, xsimstate_query, modem, NULL); return; error: shutdown_device(data); ofono_modem_set_powered(modem, FALSE); }
static void signal_callback(int signum, void *user_data) { static bool terminated = false; switch (signum) { case SIGINT: case SIGTERM: if (!terminated) { shutdown_device(); terminated = true; } break; } }
static void adv_data_callback(const void *data, uint8_t size, void *user_data) { uint8_t status = *((uint8_t *) data); if (status) { fprintf(stderr, "Failed to set advertising data\n"); shutdown_device(); return; } set_random_address(); set_adv_parameters(); set_adv_enable(); }
static void cfun_enable(gboolean ok, GAtResult *result, gpointer user_data) { struct ofono_modem *modem = user_data; struct ifx_data *data = ofono_modem_get_data(modem); DBG(""); if (!ok) { shutdown_device(data); ofono_modem_set_powered(modem, FALSE); return; } g_at_chat_send(data->dlcs[AUX_DLC], "AT+XGENDATA", xgendata_prefix, xgendata_query, modem, NULL); }
static void cfun_disable(gboolean ok, GAtResult *result, gpointer user_data) { struct ofono_modem *modem = user_data; struct ifx_data *data = ofono_modem_get_data(modem); DBG(""); if (data->dlc_poll_source > 0) { g_source_remove(data->dlc_poll_source); data->dlc_poll_source = 0; } shutdown_device(data); if (ok) ofono_modem_set_powered(modem, FALSE); }
static void set_slave_broadcast(const void *data, uint8_t size, void *user_data) { const struct bt_hci_rsp_set_slave_broadcast *rsp = data; struct bt_hci_cmd_read_clock cmd; if (rsp->status) { printf("Failed to set slave broadcast transmission\n"); shutdown_device(); return; } cmd.handle = cpu_to_le16(0x0000); cmd.type = 0x00; bt_hci_send(hci_dev, BT_HCI_CMD_READ_CLOCK, &cmd, sizeof(cmd), read_clock, NULL, NULL); }
static gboolean dlc_ready_check(gpointer user_data) { struct ofono_modem *modem = user_data; struct ifx_data *data = ofono_modem_get_data(modem); struct stat st; int i; DBG(""); data->dlc_poll_count++; if (stat(dlc_nodes[AUX_DLC], &st) < 0) { /* only possible error is ENOENT */ if (data->dlc_poll_count > 6) goto error; return TRUE; } for (i = 0; i < NUM_DLC; i++) { GIOChannel *channel = g_at_tty_open(dlc_nodes[i], NULL); data->dlcs[i] = create_chat(channel, modem, dlc_prefixes[i]); if (data->dlcs[i] == NULL) { ofono_error("Failed to open %s", dlc_nodes[i]); goto error; } } data->dlc_poll_source = 0; /* iterate through mainloop */ data->dlc_init_source = g_timeout_add_seconds(0, dlc_setup, modem); return FALSE; error: data->dlc_poll_source = 0; shutdown_device(data); ofono_modem_set_powered(modem, FALSE); return FALSE; }
static void read_local_version(const void *data, uint8_t size, void *user_data) { const struct bt_hci_rsp_read_local_version *rsp = data; if (rsp->status) { printf("Failed to read local version information\n"); shutdown_device(); return; } if (rsp->manufacturer == 15) { printf("Enabling receiver workaround for Broadcom\n"); bt_hci_register(hci_dev, BT_HCI_EVT_SYNC_TRAIN_RECEIVED, brcm_sync_train_received, NULL, NULL); } else { bt_hci_register(hci_dev, BT_HCI_EVT_SYNC_TRAIN_RECEIVED, sync_train_received, NULL, NULL); } }
static void truncated_page_complete(const void *data, uint8_t size, void *user_data) { const struct bt_hci_evt_truncated_page_complete *evt = data; struct bt_hci_cmd_receive_sync_train cmd; if (evt->status) { printf("Failed to contact 3D display\n"); shutdown_device(); return; } printf("Attempt to synchronize with 3D display\n"); memcpy(cmd.bdaddr, evt->bdaddr, 6); cmd.timeout = cpu_to_le16(0x4000); cmd.window = cpu_to_le16(0x0100); cmd.interval = cpu_to_le16(0x0080); bt_hci_send(hci_dev, BT_HCI_CMD_RECEIVE_SYNC_TRAIN, &cmd, sizeof(cmd), NULL, NULL, NULL); }
static void adv_tx_power_callback(const void *data, uint8_t size, void *user_data) { const struct bt_hci_rsp_le_read_adv_tx_power *rsp = data; struct bt_hci_cmd_le_set_adv_data cmd; if (rsp->status) { fprintf(stderr, "Failed to read advertising TX power\n"); shutdown_device(); return; } cmd.data[0] = 0x02; /* Field length */ cmd.data[1] = 0x01; /* Flags */ cmd.data[2] = 0x02; /* LE General Discoverable Mode */ cmd.data[2] |= 0x04; /* BR/EDR Not Supported */ cmd.data[3] = 0x1a; /* Field length */ cmd.data[4] = 0xff; /* Vendor field */ cmd.data[5] = 0x4c; /* Apple (76) - LSB */ cmd.data[6] = 0x00; /* Apple (76) - MSB */ cmd.data[7] = 0x02; /* iBeacon type */ cmd.data[8] = 0x15; /* Length */ memset(cmd.data + 9, 0, 16); /* UUID */ cmd.data[25] = 0x00; /* Major - LSB */ cmd.data[26] = 0x00; /* Major - MSB */ cmd.data[27] = 0x00; /* Minor - LSB */ cmd.data[28] = 0x00; /* Minor - MSB */ cmd.data[29] = 0xc5; /* TX power level */ cmd.data[30] = 0x00; /* Field terminator */ cmd.len = 1 + cmd.data[0] + 1 + cmd.data[3]; bt_hci_send(hci_dev, BT_HCI_CMD_LE_SET_ADV_DATA, &cmd, sizeof(cmd), adv_data_callback, NULL, NULL); }
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); }
/* * Function to support for shutdown detection * If below condition is met, the function will shut down * the device. Otherwise it will do nothing and return to * normal boot. * condition: * 1. it is triggered by power key && * 2. the power key is released before * (PWRKEY_LONG_PRESS_COUNT/MPM_SLEEP_TIMETICK_COUNT) seconds. */ void shutdown_detect() { /* * If it is booted by power key tirigger. * Initialize pon_timer and call long_press_pwrkey_timer_func * function to check if the power key is last press long enough. */ if (is_pwrkey_pon_reason()) { if(!pm8x41_get_pwrkey_is_pressed()){ shutdown_device(); } timer_initialize(&pon_timer); timer_set_oneshot(&pon_timer, 0,(timer_callback)long_press_pwrkey_timer_func, NULL); /* * Wait until long press power key timeout * * It will be confused to end users if we shutdown the device * after the splash screen displayed. But it can be moved the * wait here if the boot time is much more considered. */ wait_for_long_pwrkey_pressed(); } }
static void request_firmware(const char *path) { unsigned int cmd_num = 0; unsigned int evt_num = 0; struct stat st; ssize_t len; int fd; fd = open(path, O_RDONLY); if (fd < 0) { fprintf(stderr, "Failed to open firmware %s\n", path); shutdown_device(); return; } if (fstat(fd, &st) < 0) { fprintf(stderr, "Failed to get firmware size\n"); close(fd); shutdown_device(); return; } firmware_data = malloc(st.st_size); if (!firmware_data) { fprintf(stderr, "Failed to allocate firmware buffer\n"); close(fd); shutdown_device(); return; } len = read(fd, firmware_data, st.st_size); if (len < 0) { fprintf(stderr, "Failed to read firmware file\n"); close(fd); shutdown_device(); return; } close(fd); if (len < st.st_size) { fprintf(stderr, "Firmware size does not match buffer\n"); shutdown_device(); return; } firmware_size = len; if (firmware_data[0] == 0xff) firmware_offset = 1; while (firmware_offset < firmware_size) { uint16_t opcode; uint8_t evt, dlen; switch (firmware_data[firmware_offset]) { case 0x01: opcode = firmware_data[firmware_offset + 2] << 8 | firmware_data[firmware_offset + 1]; dlen = firmware_data[firmware_offset + 3]; if (opcode != CMD_MEMORY_WRITE) printf("Unexpected opcode 0x%02x\n", opcode); firmware_offset += dlen + 4; cmd_num++; break; case 0x02: evt = firmware_data[firmware_offset + 1]; dlen = firmware_data[firmware_offset + 2]; if (evt != BT_HCI_EVT_CMD_COMPLETE) printf("Unexpected event 0x%02x\n", evt); firmware_offset += dlen + 3; evt_num++; break; default: fprintf(stderr, "Invalid firmware file\n"); shutdown_device(); return; } } printf("Firmware with %u commands and %u events\n", cmd_num, evt_num); if (firmware_data[0] == 0xff) firmware_offset = 1; }
static void local_commands_callback(const void *data, uint8_t size, void *user_data) { shutdown_device(); }
static void menu_shutdown(void) { shutdown_device(); dprintf(CRITICAL,"Failed to shutdown\n"); }