void test_keepalive() { boost::asio::io_service ios; using socket = boost::asio::ip::tcp::socket; socket s (ios); if (! connect (s, "127.0.0.1", testPort)) return; if (! write (s, "GET / HTTP/1.1\r\n" "Connection: Keep-Alive\r\n" "\r\n")) return; if (! expect_read (s, "Hello, world!\n")) return ; if (! write (s, "GET / HTTP/1.1\r\n" "Connection: close\r\n" "\r\n")) return; if (! expect_read (s, "Hello, world!\n")) return ; boost::system::error_code ec; s.shutdown(socket::shutdown_both, ec); }
static int maguro_boot_info_ack(struct ipc_client *client, struct modemctl_io_data *io_data) { int ret = -1; uint32_t boot_info_length; char *boot_info = 0; if ((ret = expect_read(io_data->boot_fd, &boot_info_length, 4)) < 0) { ipc_client_log(client, "Error: failed to receive boot info length"); goto fail; } ipc_client_log(client, "Boot Info length=0x%x", boot_info_length); boot_info = (char*)malloc(boot_info_length); if (!boot_info) { ipc_client_log(client, "Error: failed to allocate memory for boot info"); goto fail; } memset(boot_info, 0, boot_info_length); size_t boot_chunk = 4; size_t boot_chunk_count = (boot_info_length + boot_chunk - 1) / boot_chunk; unsigned i; for (i = 0; i < boot_chunk_count; i++) { ret = expect_read(io_data->boot_fd, boot_info + (i * boot_chunk), boot_chunk); if (ret < 0) { ipc_client_log(client, "Error: failed to receive Boot Info chunk %i ret=%d", i, ret); goto fail; } } ipc_client_log(client, "received Boot Info"); ret = maguro_boot_cmd(client, io_data, SetPortConf, boot_info, boot_info_length); if (ret < 0) { ipc_client_log(client, "Error: failed to send SetPortConf command"); goto fail; } else { ipc_client_log(client, "sent SetPortConf command"); } ret = 0; fail: if (boot_info) free(boot_info); return ret; }
static void test_mtd_get_dev_info1(void **state) { struct libmtd *lib = mock_libmtd_open(); struct mtd_dev_info info; int dev_num = 0; memset(&info, 0, sizeof(info)); expect_open(SYSFS_ROOT "/class/mtd/mtd0/dev", O_RDONLY, 0); expect_read_real(50,0); expect_read(1,0); expect_close(3,1); expect_open(SYSFS_ROOT "/class/mtd/mtd0/name", O_RDONLY, 0); expect_read_real(128,0); expect_read(1,0); expect_close(3,1); expect_open(SYSFS_ROOT "/class/mtd/mtd0/type", O_RDONLY, 4); expect_read(65,0); expect_read(1,0); expect_close(4,0); expect_open(SYSFS_ROOT "/class/mtd/mtd0/erasesize", O_RDONLY, 0); expect_read_real(50, 0); expect_close(3,1); expect_open(SYSFS_ROOT "/class/mtd/mtd0/size", O_RDONLY, 0); expect_read_real(50,0); expect_close(3,1); expect_open(SYSFS_ROOT "/class/mtd/mtd0/writesize", O_RDONLY, 0); expect_read_real(50,0); expect_close(3,1); expect_open(SYSFS_ROOT "/class/mtd/mtd0/subpagesize", O_RDONLY, 0); expect_read_real(50,0); expect_close(3,1); expect_open(SYSFS_ROOT "/class/mtd/mtd0/oobsize", O_RDONLY, 0); expect_read_real(50,0); expect_close(3,1); expect_open(SYSFS_ROOT "/class/mtd/mtd0/oobavail", O_RDONLY, 0); expect_read_real(50,0); expect_close(3,1); expect_open(SYSFS_ROOT "/class/mtd/mtd0/numeraseregions", O_RDONLY, 0); expect_read_real(50,0); expect_close(3,1); expect_open(SYSFS_ROOT "/class/mtd/mtd0/flags", O_RDONLY, 0); expect_read_real(50,0); expect_close(3,1); int r = mtd_get_dev_info1(lib, dev_num, &info); assert_int_equal(r, 0); /* TODO check values */ libmtd_close(lib); (void)state; }
void test_request() { testcase("request"); boost::asio::io_service ios; typedef boost::asio::ip::tcp::socket socket; socket s (ios); if (! connect (s, "127.0.0.1", testPort)) return; if (! write (s, "GET / HTTP/1.1\r\n" "Connection: close\r\n" "\r\n")) return; if (! expect_read (s, "Hello, world!\n")) return ; try { s.shutdown (socket::shutdown_both); pass(); } catch (std::exception const& e) { fail (e.what()); } std::this_thread::sleep_for (std::chrono::seconds (1)); }
int piranha_ebl_set(struct ipc_client *client, struct modemctl_io_data *io_data) { unsigned char *data = NULL; unsigned char *p = NULL; int count, length; int chunk = 4; int rc; rc = expect_read(io_data->boot_fd, &length, sizeof(length)); if (rc != sizeof(length)) { ipc_client_log(client, "%s: Failed to read EBL set length", __func__); goto fail; } data = calloc(1, length); p = data; count = 0; while (count < length) { rc = expect_read(io_data->boot_fd, p, chunk < length - count ? chunk : length - count); if (rc < 0) { ipc_client_log(client, "%s: Failed to read EBL set data", __func__); goto fail; } p += rc; count += rc; } rc = piranha_boot_cmd_send(client, io_data, SetPortConf, data, length); if (rc < 0) { ipc_client_log(client, "%s: Failed to send EBL set data", __func__); goto fail; } return 0; fail: if (data != NULL) free(data); return -1; }
void test_keepalive() { testcase("keepalive"); boost::asio::io_service ios; typedef boost::asio::ip::tcp::socket socket; socket s (ios); if (! connect (s, "127.0.0.1", testPort)) return; if (! write (s, "GET / HTTP/1.1\r\n" "Connection: Keep-Alive\r\n" "\r\n")) return; if (! expect_read (s, "Hello, world!\n")) return ; if (! write (s, "GET / HTTP/1.1\r\n" "Connection: close\r\n" "\r\n")) return; if (! expect_read (s, "Hello, world!\n")) return ; try { s.shutdown (socket::shutdown_both); pass(); } catch (std::exception const& e) { fail (e.what()); } }
int piranha_ack_read(struct ipc_client *client, int fd, int ack) { int c, v; int rc; v = 0; for (c=0 ; c < 10 ; c++) { rc = expect_read(fd, &v, sizeof(v)); if ((v & 0xffff) == ack) break; } if (rc <= 0 || (v & 0xffff) != ack) return -1; return 0; }
static void test_mtd_read(void **state) { int mock_fd = 4; int eb = 0xE0; int offs = 43; int len = 28; off_t seek; char buf[28]; struct mtd_dev_info mtd; memset(&mtd, 0, sizeof(mtd)); mtd.bb_allowed = 1; mtd.eb_cnt = 1024; mtd.eb_size = 128; seek = (off_t)eb * mtd.eb_size + offs; expect_lseek(seek, SEEK_SET, seek); expect_read(len, len); int r = mtd_read(&mtd, mock_fd, eb, offs, &buf, len); assert_int_equal(r, 0); (void) state; }
void test_request() { boost::asio::io_service ios; using socket = boost::asio::ip::tcp::socket; socket s (ios); if (! connect (s, "127.0.0.1", testPort)) return; if (! write (s, "GET / HTTP/1.1\r\n" "Connection: close\r\n" "\r\n")) return; if (! expect_read (s, "Hello, world!\n")) return ; boost::system::error_code ec; s.shutdown(socket::shutdown_both, ec); std::this_thread::sleep_for (std::chrono::seconds (1)); }
int maguro_modem_bootstrap(struct ipc_client *client) { int ret = -1, n = 0, fd = -1, i; struct modemctl_io_data io_data; memset(&io_data, 0, sizeof(client, io_data)); io_data.radio_fd = -1; for (n = 0; n < I9250_RADIO_IMAGE_PATHS_NUM; n++) { fd = open(i9250_radio_image_paths[n], O_RDONLY); if (fd > 0) { io_data.radio_fd = fd; ipc_client_log(client, "opened radio image %s, fd=%d", i9250_radio_image_paths[n], io_data.radio_fd); break; } } if (io_data.radio_fd < 0) { ipc_client_log(client, "Error: failed to open radio firmware"); goto fail; } if (fstat(io_data.radio_fd, &io_data.radio_stat) < 0) { ipc_client_log(client, "Error: failed to stat radio image, error %s", strerror(errno)); goto fail; } io_data.radio_data = mmap(0, RADIO_MAP_SIZE, PROT_READ, MAP_SHARED, io_data.radio_fd, 0); if (io_data.radio_data == MAP_FAILED) { ipc_client_log(client, "Error: failed to mmap radio image, error %s", strerror(errno)); goto fail; } io_data.boot_fd = open(BOOT_DEV, O_RDWR | O_NOCTTY | O_NONBLOCK); if (io_data.boot_fd < 0) { ipc_client_log(client, "Error: failed to open boot device"); goto fail; } else { ipc_client_log(client, "opened boot device %s, fd=%d", BOOT_DEV, io_data.boot_fd); } if (maguro_modem_reboot(client, &io_data, true) < 0) { ipc_client_log(client, "Error: failed to hard reset modem"); goto fail; } else { ipc_client_log(client, "modem hard reset done"); } /* Now, actually load the firmware */ for (i = 0; i < 2; i++) { if (write(io_data.boot_fd, "ATAT", 4) != 4) { ipc_client_log(client, "Error: failed to write ATAT to boot socket"); goto fail; } else { ipc_client_log(client, "written ATAT to boot socket, waiting for ACK"); } if (expect(io_data.boot_fd, 100) < 0) { ipc_client_log(client, "failed to select before next ACK, ignoring"); } } /* FIXME: make sure it does not timeout or add the retry in the ril library */ if ((ret = expect(io_data.boot_fd, 100)) < 0) { ipc_client_log(client, "Error: failed to wait for bootloader ready state"); goto fail; } else { ipc_client_log(client, "ready for PSI upload"); } ret = -ETIMEDOUT; for (i = 0; i < I9250_BOOT_REPLY_MAX; i++) { uint32_t id_buf; if ((ret = expect_read(io_data.boot_fd, (void*)&id_buf, 4)) != 4) { ipc_client_log(client, "Error: failed receiving bootloader reply"); goto fail; } ipc_client_log(client, "got bootloader reply %08x", id_buf); if ((id_buf & I9250_BOOT_LAST_MASK) == I9250_BOOT_LAST_MASK) { ret = 0; break; } } if (ret < 0) { ipc_client_log(client, "Error: bootloader id marker not received"); goto fail; } else { ipc_client_log(client, "got bootloader id marker"); } if ((ret = maguro_send_psi(client, &io_data)) < 0) { ipc_client_log(client, "Error: failed to upload PSI"); goto fail; } else { ipc_client_log(client, "PSI download complete"); } close(io_data.boot_fd); io_data.boot_fd = open(I9250_SECOND_BOOT_DEV, O_RDWR | O_NOCTTY | O_NONBLOCK); if (io_data.boot_fd < 0) { ipc_client_log(client, "Error: failed to open " I9250_SECOND_BOOT_DEV " control device"); goto fail; } else { ipc_client_log(client, "opened second boot device %s, fd=%d", I9250_SECOND_BOOT_DEV, io_data.boot_fd); } if ((ret = write(io_data.boot_fd, I9250_PSI_CMD_EXEC, 4)) < 0) { ipc_client_log(client, "Error: failed writing cmd_load_exe_EBL"); goto fail; } if ((ret = write(io_data.boot_fd, I9250_PSI_EXEC_DATA, 8)) < 0) { ipc_client_log(client, "Error: failed writing 8 bytes to boot1"); goto fail; } if ((ret = expect_data(io_data.boot_fd, I9250_GENERAL_ACK, 4)) < 0) { ipc_client_log(client, "Error: failed to receive cmd_load_exe_EBL ack"); goto fail; } if ((ret = expect_data(io_data.boot_fd, I9250_PSI_READY_ACK, 4)) < 0) { ipc_client_log(client, "Error: failed to receive PSI ready ack"); goto fail; } if ((ret = maguro_send_ebl(client, &io_data)) < 0) { ipc_client_log(client, "Error: failed to upload EBL"); goto fail; } else { ipc_client_log(client, "EBL download complete"); } if ((ret = maguro_boot_info_ack(client, &io_data)) < 0) { ipc_client_log(client, "Error: failed to receive Boot Info"); goto fail; } else { ipc_client_log(client, "Boot Info ACK done"); } if ((ret = maguro_send_image_addrs(client, &io_data)) < 0) { ipc_client_log(client, "Error: failed to upload Secure Image"); goto fail; } else { ipc_client_log(client, "Secure Image download complete"); } if ((ret = modemctl_wait_modem_online(client, &io_data))) { ipc_client_log(client, "Error: failed to wait for modem to become online"); goto fail; } /* This restores UART MUX to GPS */ modemctl_modem_boot_power(client, &io_data, false); ipc_client_log(client, "Modem is online!"); ret = 0; fail: if (io_data.radio_data != MAP_FAILED) munmap(io_data.radio_data, RADIO_MAP_SIZE); if (io_data.radio_fd >= 0) close(io_data.radio_fd); if (io_data.boot_fd >= 0) close(io_data.boot_fd); return ret; }
static int maguro_boot_cmd(struct ipc_client *client, struct modemctl_io_data *io_data, enum xmm6260_boot_cmd cmd, void *data, size_t data_size) { int ret = 0; char *cmd_data = 0; uint32_t ack_length; if (cmd >= ARRAY_SIZE(maguro_boot_cmd_desc)) { ipc_client_log(client, "Error: bad command %x\n", cmd); goto done_or_fail; } unsigned cmd_code = maguro_boot_cmd_desc[cmd].code; uint16_t checksum = (data_size & 0xffff) + cmd_code; unsigned char *ptr = (unsigned char*)data; size_t i; for (i = 0; i < data_size; i++) { checksum += ptr[i]; } DECLARE_BOOT_CMD_HEADER(header, cmd_code, data_size); DECLARE_BOOT_TAIL_HEADER(tail, checksum); size_t tail_size = sizeof(tail); if (!maguro_boot_cmd_desc[cmd].long_tail) { tail_size -= 2; } size_t cmd_buffer_size = data_size + sizeof(header) + tail_size; ipc_client_log(client, "data_size %d [%d] checksum 0x%x", data_size, cmd_buffer_size, checksum); cmd_data = (char*)malloc(cmd_buffer_size); if (!cmd_data) { ipc_client_log(client, "Error: failed to allocate command buffer"); ret = -ENOMEM; goto done_or_fail; } memset(cmd_data, 0, cmd_buffer_size); memcpy(cmd_data, &header, sizeof(header)); memcpy(cmd_data + sizeof(header), data, data_size); memcpy(cmd_data + sizeof(header) + data_size, &tail, tail_size); if ((ret = write(io_data->boot_fd, cmd_data, cmd_buffer_size)) < 0) { ipc_client_log(client, "Error: failed to write command to socket"); goto done_or_fail; } if ((unsigned)ret < cmd_buffer_size) { ipc_client_log(client, "Error: written %d bytes of %d", ret, cmd_buffer_size); ret = -EINVAL; goto done_or_fail; } if (maguro_boot_cmd_desc[cmd].no_ack) { ipc_client_log(client, "not waiting for ACK"); goto done_or_fail; } if ((ret = expect_read(io_data->boot_fd, &ack_length, 4)) < 0) { ipc_client_log(client, "Error: failed to receive ack header length"); goto done_or_fail; } if (ack_length + 4 > cmd_buffer_size) { free(cmd_data); cmd_data = NULL; cmd_data = malloc(ack_length + 4); if (!cmd_data) { ipc_client_log(client, "Error: failed to allocate the buffer for ack data"); goto done_or_fail; } } memset(cmd_data, 0, ack_length); memcpy(cmd_data, &ack_length, 4); for (i = 0; i < (ack_length + 3) / 4; i++) { if ((ret = expect_read(io_data->boot_fd, cmd_data + ((i + 1) << 2), 4)) < 0) { ipc_client_log(client, "Error: failed to receive ack chunk"); goto done_or_fail; } } ipc_client_log(client, "received ack"); struct maguro_boot_cmd_header *ack_hdr = (struct maguro_boot_cmd_header*)cmd_data; struct maguro_boot_tail_header *ack_tail = (struct maguro_boot_tail_header*) (cmd_data + ack_length + 4 - sizeof(struct maguro_boot_tail_header)); ipc_client_log(client, "ack code 0x%x checksum 0x%x", ack_hdr->cmd, ack_tail->checksum); if (ack_hdr->cmd != header.cmd) { ipc_client_log(client, "Error: request and ack command codes do not match"); ret = -1; goto done_or_fail; } ret = 0; done_or_fail: if (cmd_data) free(cmd_data); return ret; }
int piranha_boot_cmd_send(struct ipc_client *client, struct modemctl_io_data *io_data, int cmd, void *data, int size) { struct piranha_boot_cmd *boot_cmd; struct piranha_boot_cmd_header *header_p; unsigned char *p; struct piranha_boot_cmd_header header; struct piranha_boot_cmd_tail tail; int tail_length; void *cmd_data = NULL; int cmd_length = 0; void *ack_data = NULL; int ack_length = 0; int count, length; int chunk = 4; int rc; boot_cmd = piranha_boot_cmd_get(cmd); if (boot_cmd == NULL) goto fail; piranha_boot_cmd_header_fill(&header, boot_cmd->code, size); piranha_boot_cmd_tail_fill(&tail, boot_cmd->code, data, size); tail_length = sizeof(tail); if (boot_cmd->flags & PIRANHA_FLAG_SHORT_TAIL) tail_length -= 2; cmd_length = sizeof(header) + size + tail_length; cmd_data = calloc(1, cmd_length); p = (unsigned char *) cmd_data; memcpy(p, &header, sizeof(header)); p += sizeof(header); memcpy(p, data, size); p += size; memcpy(p, &tail, tail_length); rc = write(io_data->boot_fd, cmd_data, cmd_length); if (rc != cmd_length) goto fail; if (boot_cmd->flags & PIRANHA_FLAG_NO_ACK) goto done; rc = expect_read(io_data->boot_fd, &ack_length, sizeof(ack_length)); if (rc != sizeof(ack_length) || ack_length <= 0) goto fail; // Add short tail ack_length += sizeof(tail) - 2; if (ack_length % 4 != 0) ack_length += ack_length % 4; ack_data = calloc(1, ack_length); p = (unsigned char *) ack_data; memcpy(p, &ack_length, sizeof(ack_length)); p += sizeof(ack_length); length = ack_length; count = sizeof(ack_length); while (count < length) { rc = expect_read(io_data->boot_fd, p, chunk < length - count ? chunk : length - count); if (rc < 0) goto fail; p += rc; count += rc; } header_p = (struct piranha_boot_cmd_header *) ack_data; if (header_p->code != boot_cmd->code) goto fail; rc = 0; goto done; fail: rc = -1; done: if (cmd_data != NULL) free(cmd_data); if (ack_data != NULL) free(ack_data); return rc; }