Exemplo n.º 1
0
int nv_data_md5_check(struct ipc_client *client)
{
    struct stat nv_stat;
    uint8_t nv_data_md5_hash[MD5_DIGEST_LENGTH];
    char *nv_data_md5_hash_string = NULL;
    char *nv_data_md5_hash_read = NULL;
    void *nv_data_p = NULL;
    int fd;
    int rc;
    uint8_t *data_p;

    ipc_client_log(client, "nv_data_md5_check: enter\n");

    nv_data_md5_hash_string=malloc(MD5_STRING_SIZE);
    nv_data_md5_hash_read=malloc(MD5_STRING_SIZE);

    memset(nv_data_md5_hash_read, 0, MD5_STRING_SIZE);
    memset(nv_data_md5_hash_string, 0, MD5_STRING_SIZE);

    nv_data_p=ipc_client_file_read(client, nv_data_path(client),
        nv_data_size(client), nv_data_chunk_size(client));
    data_p=nv_data_p;

    nv_data_md5_compute(data_p, nv_data_size(client), nv_data_secret(client), nv_data_md5_hash);

    md5hash2string(nv_data_md5_hash_string, nv_data_md5_hash);

    free(nv_data_p);

    fd=open(nv_data_md5_path(client), O_RDONLY);

    /* Read the md5 stored in the file. */
    rc = read(fd, nv_data_md5_hash_read, MD5_STRING_SIZE);
    if (rc < 0)
    {
        ipc_client_log(client, "nv_data_md5_check: Can't read md5 hash from file\n");
        return -1;
    }

    /* Add 0x0 to end the string: not sure this is part of the file. */
    nv_data_md5_hash_read[MD5_STRING_SIZE - 1]='\0';

    ipc_client_log(client, "nv_data_md5_check: computed MD5: %s read MD5: %s\n", 
        nv_data_md5_hash_string, nv_data_md5_hash_read);

    if (strcmp(nv_data_md5_hash_string, nv_data_md5_hash_read) != 0)
    {
        ipc_client_log(client, "nv_data_md5_check: MD5 hash mismatch\n");
        nv_data_backup_restore(client);
    }

    if (nv_data_md5_hash_string != NULL)
        free(nv_data_md5_hash_string);
    if (nv_data_md5_hash_read != NULL)
        free(nv_data_md5_hash_read);

    ipc_client_log(client, "nv_data_md5_check: exit\n");

    return 0;
}
Exemplo n.º 2
0
int crespo_ipc_rfs_client_send(struct ipc_client *client, struct ipc_message_info *request)
{
    struct modem_io modem_data;
    int rc = 0;

    memset(&modem_data, 0, sizeof(struct modem_io));

    modem_data.id = request->mseq;
    modem_data.cmd = request->index;

    modem_data.size = request->length;
    modem_data.data = malloc(request->length);

    memcpy(modem_data.data, request->data, request->length);

    assert(client->handlers->write != NULL);

    ipc_client_log(client, "crespo_ipc_rfs_client_send: SEND RFS (id=%d cmd=%d size=%d)!", modem_data.id, modem_data.cmd, modem_data.size);
    ipc_client_log(client, "crespo_ipc_rfs_client_send: IPC request (mseq=0x%02x command=%s (0x%04x))", 
                    request->mseq, ipc_command_to_str(IPC_COMMAND(request)), IPC_COMMAND(request));

#ifdef DEBUG
    if(request->length > 0)
    {
        ipc_client_log(client, "==== RFS DATA DUMP ====");
        ipc_hex_dump(client, (void *) request->data, request->length);
    }
#endif

    ipc_client_log(client, "");

    rc = client->handlers->write((uint8_t*) &modem_data, sizeof(struct modem_io), client->handlers->write_data);
    return rc;
}
Exemplo n.º 3
0
void ipc_rfs_send_io_confirm_for_nv_write_item(struct ipc_client *client, struct ipc_message_info *info)
{
    struct ipc_rfs_io *rfs_io = (struct ipc_rfs_io *) info->data;
    struct ipc_rfs_io_confirm *rfs_io_conf;
    void *rfs_data;
    int rc;

    if (rfs_io == NULL)
    {
        ipc_client_log(client, "ERROR: Request message is invalid: aseq = %i", info->aseq);
        return;
    }

    rfs_data = info->data + sizeof(struct ipc_rfs_io);

#ifdef DEBUG
    ipc_client_log(client, "Write rfs_data dump:");
    ipc_client_hex_dump(client, rfs_data, rfs_io->length);
#endif

    ipc_client_log(client, "Asked to write 0x%x bytes at offset 0x%x", rfs_io->length, rfs_io->offset);
    rc = nv_data_write(client, rfs_io->offset, rfs_io->length, rfs_data);

    ipc_client_log(client, "Sending RFS IO Confirm message (rc is %d)", rc);
    rfs_io_conf = (struct ipc_rfs_io_confirm*) malloc(sizeof(struct ipc_rfs_io_confirm));
    rfs_io_conf->confirm = rc < 0 ? 0 : 1;
    rfs_io_conf->offset = rfs_io->offset;
    rfs_io_conf->length = rfs_io->length;

    ipc_client_send(client, IPC_RFS_NV_WRITE_ITEM, 0, (unsigned char*) rfs_io_conf,
                    sizeof(struct ipc_rfs_io_confirm), info->aseq);
    free(rfs_io_conf);
}
Exemplo n.º 4
0
static int maguro_modem_reboot(struct ipc_client *client,
    struct modemctl_io_data *io_data, bool hard)
{
    int ret;

    if (!hard)
        return 0;

    /* Disable the hardware to ensure consistent state */
    if ((ret = modemctl_modem_power(client, io_data, false)) < 0) {
        ipc_client_log(client, "Error: failed to disable modem power");
        goto fail;
    }
    else {
        ipc_client_log(client, "disabled modem power");
    }

    /* Now, initialize the hardware */
    if ((ret = modemctl_modem_power(client, io_data, true)) < 0) {
        ipc_client_log(client, "Error: failed to enable modem power");
        goto fail;
    }
    else {
        ipc_client_log(client, "enabled modem power");
    }

fail:
    return ret;
}
Exemplo n.º 5
0
static int maguro_send_image_data(struct ipc_client *client,
    struct modemctl_io_data *io_data, uint32_t addr,
    void *data, int data_len)
{
    int ret = 0;
    int count = 0;
    char *data_p = (char *) data;

    if ((ret = maguro_boot_cmd(client, io_data, ReqFlashSetAddress, &addr, 4)) < 0) {
        ipc_client_log(client, "Error: failed to send ReqFlashSetAddress");
        goto fail;
    }
    else {
        ipc_client_log(client, "sent ReqFlashSetAddress");
    }

    while (count < data_len) {
        int rest = data_len - count;
        int chunk = rest < SEC_DOWNLOAD_CHUNK ? rest : SEC_DOWNLOAD_CHUNK;

        ret = maguro_boot_cmd(client, io_data, ReqFlashWriteBlock, data_p, chunk);
        if (ret < 0) {
            ipc_client_log(client, "Error: failed to send data chunk");
            goto fail;
        }

        data_p += chunk;
        count += chunk;
    }

    usleep(SEC_DOWNLOAD_DELAY_US);

fail:
    return ret;
}
Exemplo n.º 6
0
static int maguro_send_ebl(struct ipc_client *client,
    struct modemctl_io_data *io_data)
{
    int ret;
    int fd = io_data->boot_fd;
    unsigned length = maguro_radio_parts[EBL].length;

    if ((ret = write(fd, "\x04\x00\x00\x00", 4)) != 4) {
        ipc_client_log(client, "Error: failed to write length of EBL length ('4') ");
        goto fail;
    }

    if ((ret = write(fd, &length, sizeof(length))) != sizeof(length)) {
        ipc_client_log(client, "Error: failed to write EBL length");
        goto fail;
    }

    if ((ret = expect_data(fd, I9250_GENERAL_ACK, 4)) < 0) {
        ipc_client_log(client, "Error: failed to wait for EBL length ACK");
        goto fail;
    }

    if ((ret = expect_data(fd, I9250_EBL_HDR_ACK_MAGIC, 4)) < 0) {
        ipc_client_log(client, "Error: failed to wait for EBL header ACK");
        goto fail;
    }

    length++;
    if ((ret = write(fd, &length, sizeof(length))) != sizeof(length)) {
        ipc_client_log(client, "Error: failed to write EBL length + 1");
        goto fail;
    }

    if ((ret = maguro_send_image(client, io_data, EBL)) < 0) {
        ipc_client_log(client, "Error: failed to send EBL image");
        goto fail;
    }
    else {
        ipc_client_log(client, "sent EBL image, waiting for ACK");
    }

    if ((ret = expect_data(fd, I9250_GENERAL_ACK, 4)) < 0) {
        ipc_client_log(client, "Error: failed to wait for EBL image general ACK");
        goto fail;
    }

    if ((ret = expect_data(fd, I9250_EBL_IMG_ACK_MAGIC, 4)) < 0) {
        ipc_client_log(client, "Error: failed to wait for EBL image ACK");
        goto fail;
    }
    else {
        ipc_client_log(client, "got EBL ACK");
    }

    return 0;

fail:
    return ret;
}
Exemplo n.º 7
0
int aries_ipc_fmt_client_recv(struct ipc_client *client, struct ipc_message_info *response)
{
    struct ipc_header *resphdr;
    void *data;
    int bread = 0;

    data = malloc(MAX_MODEM_DATA_SIZE);
    memset(data, 0, MAX_MODEM_DATA_SIZE);

    memset(response, 0, sizeof(struct ipc_message_info));

    assert(client->handlers->read != NULL);
    bread = client->handlers->read((uint8_t*) data, MAX_MODEM_DATA_SIZE, client->handlers->read_data);

    if (bread < 0)
    {
        ipc_client_log(client, "aries_ipc_fmt_client_recv: can't receive enough bytes from modem to process incoming response!");
        return -1;
    }

    if(data == NULL)
    {
        ipc_client_log(client, "aries_ipc_fmt_client_recv: we retrieve less (or fairly too much) bytes from the modem than we exepected!");
        return -1;
    }

    resphdr = (struct ipc_header *) data;

    response->mseq = resphdr->mseq;
    response->aseq = resphdr->aseq;
    response->group = resphdr->group;
    response->index = resphdr->index;
    response->type = resphdr->type;
    response->cmd = IPC_COMMAND(response);
    response->length = resphdr->length - sizeof(struct ipc_header);
    response->data = NULL;

    if(response->length > 0)
    {
        response->data = malloc(response->length);
        memcpy(response->data, (uint8_t *) data + sizeof(struct ipc_header), response->length);
    }

    free(data);

    ipc_client_log_recv(client, response, __func__);

    return 0;
}
Exemplo n.º 8
0
int aries_ipc_rfs_client_recv(struct ipc_client *client, struct ipc_message_info *response)
{
    void *data;
    int bread = 0;
    struct rfs_hdr *rfs_hdr;

    data = malloc(MAX_MODEM_DATA_SIZE);
    memset(data, 0, MAX_MODEM_DATA_SIZE);

    memset(response, 0, sizeof(struct ipc_message_info));

    assert(client->handlers->read != NULL);
    bread = client->handlers->read((uint8_t*) data, MAX_MODEM_DATA_SIZE, client->handlers->read_data);
    if (bread < 0)
    {
        ipc_client_log(client, "aries_ipc_rfs_client_recv: can't receive enough bytes from modem to process incoming response!");
        return -1;
    }

    rfs_hdr = (struct rfs_hdr *) data;

    if(rfs_hdr->len <= 0 || rfs_hdr->len >= MAX_MODEM_DATA_SIZE || data == NULL)
    {
        ipc_client_log(client, "aries_ipc_rfs_client_recv: we retrieve less (or fairly too much) bytes from the modem than we exepected!");
        return -1;
    }

    response->mseq = 0;
    response->aseq = rfs_hdr->id;
    response->group = IPC_GROUP_RFS;
    response->index = rfs_hdr->cmd;
    response->type = 0;
    response->length = rfs_hdr->len - sizeof(struct rfs_hdr);
    response->data = NULL;

    if(response->length > 0)
    {
        response->data = malloc(response->length);
        memcpy(response->data, (uint8_t *) (data + sizeof(struct rfs_hdr)), response->length);
    }

    free(data);

    ipc_client_log_recv(client, response, __func__);

    return 0;
}
Exemplo n.º 9
0
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;
}
Exemplo n.º 10
0
static int maguro_send_mps_data(struct ipc_client *client,
    struct modemctl_io_data *io_data)
{
    int ret = 0;
    int mps_fd = -1;
    char mps_data[I9250_MPS_LENGTH] = {};
    uint32_t addr = I9250_MPS_LOAD_ADDR;

    mps_fd = open(I9250_MPS_IMAGE_PATH, O_RDONLY);
    if (mps_fd < 0) {
        ipc_client_log(client, "Error: failed to open MPS data");
        goto fail;
    }
    else {
        ret = read(mps_fd, mps_data, I9250_MPS_LENGTH);
        if (ret < 0) {
            ipc_client_log(client, "Error: failed to read MPS data\n");
            goto fail;
        }
    }

    if ((ret = maguro_boot_cmd(client, io_data, ReqFlashSetAddress, &addr, 4)) < 0) {
        ipc_client_log(client, "Error: failed to send ReqFlashSetAddress");
        goto fail;
    }
    else {
        ipc_client_log(client, "sent ReqFlashSetAddress");
    }

    if ((ret = maguro_boot_cmd(client, io_data, ReqFlashWriteBlock,
        mps_data, I9250_MPS_LENGTH)) < 0) {
        ipc_client_log(client, "Error: failed to write MPS data to modem");
        goto fail;
    }


fail:
    if (mps_fd >= 0)
        close(mps_fd);

    return ret;
}
Exemplo n.º 11
0
int crespo_ipc_fmt_client_send(struct ipc_client *client, struct ipc_message_info *request)
{
    struct modem_io modem_data;
    struct ipc_header reqhdr;
    int rc = 0;

    memset(&modem_data, 0, sizeof(struct modem_io));
    modem_data.size = request->length + sizeof(struct ipc_header);

    reqhdr.mseq = request->mseq;
    reqhdr.aseq = request->aseq;
    reqhdr.group = request->group;
    reqhdr.index = request->index;
    reqhdr.type = request->type;
    reqhdr.length = (uint16_t) (request->length + sizeof(struct ipc_header));

    modem_data.data = malloc(reqhdr.length);

    memcpy(modem_data.data, &reqhdr, sizeof(struct ipc_header));
    memcpy((unsigned char *) (modem_data.data + sizeof(struct ipc_header)), request->data, request->length);

    assert(client->handlers->write != NULL);

    ipc_client_log(client, "crespo_ipc_fmt_client_send: SEND FMT (id=%d cmd=%d size=%d)!", modem_data.id, modem_data.cmd, modem_data.size);
    ipc_client_log(client, "crespo_ipc_fmt_client_send: IPC request (mseq=0x%02x command=%s (0x%04x) type=%s)", 
                    request->mseq, ipc_command_to_str(IPC_COMMAND(request)), IPC_COMMAND(request), ipc_request_type_to_str(request->type));

#ifdef DEBUG
    if(request->length > 0)
    {
        ipc_client_log(client, "==== FMT DATA DUMP ====");
        ipc_hex_dump(client, (void *) request->data, request->length);
    }
#endif

    ipc_client_log(client, "");

    rc = client->handlers->write((uint8_t*) &modem_data, sizeof(struct modem_io), client->handlers->write_data);
    return rc;
}
Exemplo n.º 12
0
int crespo_ipc_fmt_client_recv(struct ipc_client *client, struct ipc_message_info *response)
{
    struct modem_io modem_data;
    struct ipc_header *resphdr;
    int bread = 0;

    memset(&modem_data, 0, sizeof(struct modem_io));
    modem_data.data = malloc(MAX_MODEM_DATA_SIZE);
    modem_data.size = MAX_MODEM_DATA_SIZE;

    memset(response, 0, sizeof(struct ipc_message_info));

    wake_lock("secril_fmt-interface", 20);

    assert(client->handlers->read != NULL);
    bread = client->handlers->read((uint8_t*) &modem_data, sizeof(struct modem_io) + MAX_MODEM_DATA_SIZE, client->handlers->read_data);
    if (bread < 0)
    {
        ipc_client_log(client, "crespo_ipc_fmt_client_recv: can't receive enough bytes from modem to process incoming response!");
        return -1;
    }

    if(modem_data.size <= 0 || modem_data.size >= MAX_MODEM_DATA_SIZE || modem_data.data == NULL)
    {
        ipc_client_log(client, "crespo_ipc_fmt_client_recv: we retrieve less (or fairly too much) bytes from the modem than we exepected!");
        return -1;
    }

    resphdr = (struct ipc_header *) modem_data.data;

    response->mseq = resphdr->mseq;
    response->aseq = resphdr->aseq;
    response->group = resphdr->group;
    response->index = resphdr->index;
    response->type = resphdr->type;
    response->length = modem_data.size - sizeof(struct ipc_header);
    response->data = NULL;

    ipc_client_log(client, "crespo_ipc_fmt_client_recv: RECV FMT (id=%d cmd=%d size=%d)!", modem_data.id, modem_data.cmd, modem_data.size);
    ipc_client_log(client, "crespo_ipc_fmt_client_recv: IPC response (aseq=0x%02x command=%s (0x%04x) type=%s)", 
                    response->aseq, ipc_command_to_str(IPC_COMMAND(response)), IPC_COMMAND(response), ipc_response_type_to_str(response->type));

    if(response->length > 0)
    {
#ifdef DEBUG
        ipc_client_log(client, "==== FMT DATA DUMP ====");
        ipc_hex_dump(client, (void *) (modem_data.data + sizeof(struct ipc_header)), response->length);
#endif
        response->data = malloc(response->length);
        memcpy(response->data, (uint8_t *) modem_data.data + sizeof(struct ipc_header), response->length);
    }

    free(modem_data.data);

    ipc_client_log(client, "");

    wake_unlock("secril_fmt-interface", 20);

    return 0;
}
Exemplo n.º 13
0
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;
}
int xmm626_sec_modem_rfs_send(struct ipc_client *client,
    struct ipc_message *message)
{
    struct ipc_rfs_header header;
    void *buffer;
    size_t length;
    size_t count;
    unsigned char *p;
    int rc;

    if (client == NULL || client->handlers == NULL || client->handlers->write == NULL || message == NULL)
        return -1;

    ipc_rfs_header_setup(&header, message);

    length = header.length;
    buffer = calloc(1, length);

    memcpy(buffer, &header, sizeof(struct ipc_rfs_header));
    if (message->data != NULL && message->size > 0)
        memcpy((void *) ((unsigned char *) buffer + sizeof(struct ipc_rfs_header)), message->data, message->size);

    ipc_client_log_send(client, message, __func__);

    p = (unsigned char *) buffer;

    count = 0;
    while (count < length) {
        rc = client->handlers->write(client->handlers->transport_data, p, length - count);
        if (rc <= 0) {
            ipc_client_log(client, "Writing RFS data failed");
            goto error;
        }

        count += rc;
        p += rc;
    }

    rc = 0;
    goto complete;

error:
    rc = -1;

complete:
    if (buffer != NULL)
        free(buffer);

    return rc;
}
Exemplo n.º 15
0
static int maguro_send_psi(struct ipc_client *client,
    struct modemctl_io_data *io_data)
{
    int ret = -1;

    if ((ret = write(io_data->boot_fd, I9250_PSI_START_MAGIC, 4)) < 0) {
        ipc_client_log(client, "%s: failed to write header, ret %d", __func__, ret);
        goto fail;
    }

    if ((ret = maguro_send_image(client, io_data, PSI)) < 0) {
        ipc_client_log(client, "Error: failed to send PSI image");
        goto fail;
    }

    char expected_acks[4][4] = {
        "\xff\xff\xff\x01",
        "\xff\xff\xff\x01",
        "\x02\x00\x00\x00",
        "\x01\xdd\x00\x00",
    };

    unsigned i;
    for (i = 0; i < ARRAY_SIZE(expected_acks); i++) {
        ret = expect_data(io_data->boot_fd, expected_acks[i], 4);
        if (ret < 0) {
            ipc_client_log(client, "failed to wait for ack %d", i);
            goto fail;
        }
    }
    ipc_client_log(client, "received PSI ACK");

    return 0;

fail:
    return ret;
}
Exemplo n.º 16
0
void nv_data_md5_generate(struct ipc_client *client)
{
    uint8_t nv_data_md5_hash[MD5_DIGEST_LENGTH];
    char *nv_data_md5_hash_string = NULL;
    void *nv_data_p = NULL;
    int fd;
    int rc;

    ipc_client_log(client, "nv_data_md5_generate: enter\n");

    ipc_client_log(client, "nv_data_md5_generate: generating MD5 hash\n");
    nv_data_p=ipc_client_file_read(client, nv_data_path(client),
        nv_data_size(client), nv_data_chunk_size(client));
    nv_data_md5_compute(nv_data_p, nv_data_size(client), nv_data_secret(client), nv_data_md5_hash);
    free(nv_data_p);

    /* Alloc the memory for the md5 hash string. */
    nv_data_md5_hash_string = malloc(MD5_STRING_SIZE);
    memset(nv_data_md5_hash_string, 0, MD5_STRING_SIZE);

    md5hash2string(nv_data_md5_hash_string, nv_data_md5_hash);

    ipc_client_log(client, "nv_data_md5_generate: new MD5 hash is %s\n", nv_data_md5_hash_string);

    ipc_client_log(client, "nv_data_md5_generate: writing MD5 hash\n");

    /* Write the MD5 hash in nv_data.bin.md5. */
    fd = open(nv_data_md5_path(client), O_RDWR | O_CREAT | O_TRUNC, 0644);
    if (fd < 0)
    {
        ipc_client_log(client, "nv_data_md5_generate: fd open failed\n");
        goto exit;
    }

    rc = write(fd, nv_data_md5_hash_string, MD5_STRING_SIZE);
    if (rc < 0)
    {
        ipc_client_log(client, "nv_data_md5_generate: failed to write MD5 hash to file\n");
        close(fd);
        goto exit;
    }

    close(fd);

exit:
    if (nv_data_md5_hash_string != NULL)
        free(nv_data_md5_hash_string);

    ipc_client_log(client, "nv_data_md5_generate: exit\n");
}
Exemplo n.º 17
0
int h1_ipc_send(struct ipc_client *client, struct ipc_message_info *request)
{
    struct hdlc_header *hdlc;
    unsigned char *frame;
    unsigned char *payload;
    int frame_length;

    /* Frame length: HDLC/IPC header + payload length + HDLC flags (2) */
    frame_length = (sizeof(*hdlc) + request->length + 2);

    frame = (unsigned char*)malloc(frame_length);
    frame[0] = FRAME_START;
    frame[frame_length-1] = FRAME_END;

    /* Setup HDLC header */
    hdlc = (struct hdlc_header*)(frame + 1);

    hdlc->length = (sizeof(*hdlc) + request->length);
    hdlc->unknown = 0;

    /* IPC header */
    hdlc->ipc.length = (sizeof(hdlc->ipc) + request->length);
    hdlc->ipc.mseq = request->mseq;
    hdlc->ipc.aseq = request->aseq;
    hdlc->ipc.group = request->group;
    hdlc->ipc.index = request->index;
    hdlc->ipc.type = request->type;

    /* IPC payload */
    payload = (frame + 1 + sizeof(*hdlc));
    memcpy(payload, request->data, request->length);

    ipc_client_log(client, "sending %s %s\n",
            ipc_command_to_str(IPC_COMMAND(request)),
            ipc_response_type_to_str(request->type));

    ipc_hex_dump(client, frame, frame_length);

    client->handlers->write(frame, frame_length,  client->handlers->write_data);

    free(frame);

    return 0;
}
Exemplo n.º 18
0
int nv_data_write(struct ipc_client *client, int offset, int length, char *buf)
{
    int fd;
    int rc;

    ipc_client_log(client, "nv_data_write: enter\n");

    if(offset < 0 || length <= 0) {
        ipc_client_log(client, "nv_data_write: offset or length <= 0\n");
        return -1;
    }

    if (buf == NULL) {
        ipc_client_log(client, "nv_data_write: provided input buf is NULL\n");
        return -1;
    }

    if (nv_data_check(client) < 0)
        return -1;

    fd = open(nv_data_path(client), O_WRONLY);

    if (fd < 0) {
        ipc_client_log(client, "nv_data_write: nv_data file fd is negative\n");
        return -1;
    }

    lseek(fd, offset, SEEK_SET);

    rc = write(fd, buf, length);

    close(fd);

    if (rc < length) {
        ipc_client_log(client, "nv_data_write: wrote less (%d) than what we expected (%d), error: %s, restoring backup\n", rc, length, strerror(errno));
        nv_data_backup_restore(client);
        return -1;
    }

    ipc_client_log(client, "nv_data_write: writing new md5sum\n");
    nv_data_md5_generate(client);

    ipc_client_log(client, "nv_data_write: exit\n");

    return 0;
}
Exemplo n.º 19
0
int modemctl_link_set_enabled(struct ipc_client *client,
    struct modemctl_io_data *io_data, bool enabled)
{
    unsigned status = enabled;
    int ret;
    unsigned long ioctl_code;

    ioctl_code = IOCTL_LINK_CONTROL_ENABLE;
    ret = ioctl(io_data->link_fd, ioctl_code, &status);

    if (ret < 0) {
        ipc_client_log(client, "failed to set link state to %d", enabled);
        goto fail;
    }

    return 0;
fail:
    return ret;
}
Exemplo n.º 20
0
int h1_ipc_recv(struct ipc_client *client, struct ipc_message_info *response)
{
    unsigned char buf[4];
    unsigned char *data;
    unsigned short *frame_length;
    struct ipc_header *ipc;
    int num_read;
    int left;

    num_read = client->handlers->read((void*)buf, sizeof(buf),  client->handlers->read_data);

    if(num_read == sizeof(buf) && *buf == FRAME_START) {
        frame_length = (unsigned short*)&buf[1];
        left = (*frame_length - 3 + 1);

        data = (unsigned char*)malloc(left);
        num_read = client->handlers->read((void*)data, left,  client->handlers->read_data);

        if(num_read == left && data[left-1] == FRAME_END) {
            ipc = (struct ipc_header*)data;
            response->mseq = ipc->mseq;
            response->aseq = ipc->aseq;
            response->group = ipc->group;
            response->index = ipc->index;
            response->type = ipc->type;
            response->length = (ipc->length - sizeof(*ipc));

            response->data = (unsigned char*)malloc(response->length);
            memcpy(response->data, (data + sizeof(*ipc)), response->length);

            ipc_client_log(client, "received %s %s\n",
                    ipc_command_to_str(IPC_COMMAND(response)),
                    ipc_response_type_to_str(response->type));

            ipc_hex_dump(client, data, num_read-1);

            return 0;
        }
    }

    return 0;
}
Exemplo n.º 21
0
int nv_data_read(struct ipc_client *client, int offset, int length, char *buf)
{
    int fd;
    int rc;

    ipc_client_log(client, "nv_data_read: enter\n");

    if(offset < 0 || length <= 0) {
        ipc_client_log(client, "nv_data_read: offset < 0 or length <= 0\n");
        return -1;
    }

    if (buf == NULL) {
        ipc_client_log(client, "nv_data_read: provided output buf is NULL\n");
        return -1;
    }

    if (nv_data_check(client) < 0)
        return -1;

    fd = open(nv_data_path(client), O_RDONLY);

    if (fd < 0) {
        ipc_client_log(client, "nv_data_read: nv_data file fd is negative\n");
        return -1;
    }

    lseek(fd, offset, SEEK_SET);

    rc = read(fd, buf, length);

    if (rc < length) {
        ipc_client_log(client, "nv_data_read: read less than what we expected\n");
        return -1;
    }

    ipc_client_log(client, "nv_data_read: exit\n");

    return 0;
}
Exemplo n.º 22
0
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;
}
Exemplo n.º 23
0
int aries_modem_bootstrap(struct ipc_client *client)
{
    int s3c2410_serial3_fd = -1;
    int onedram_fd = -1;

    /* Control variables. */
    int rc = 0;

    /* Boot variables */
    uint8_t *radio_img_p = NULL;
    uint32_t onedram_data = 0;
    uint8_t bootcore_version = 0;
    uint8_t info_size = 0;
    uint8_t crc_byte = 0;
    int block_size = 0;

    /* s3c2410 serial setup variables. */
    struct termios termios;
    int serial;

    /* fds maniplation variables */
    struct timeval timeout;
    fd_set fds;

    /* nv_data variables */
    void *nv_data_p;
    void *onedram_p;

    /* General purpose variables. */
    uint8_t data;
    uint16_t data_16;
    uint8_t *data_p;
    int i;

    ipc_client_log(client, "aries_ipc_bootstrap: enter");

    /* Read the radio.img image. */
    ipc_client_log(client, "aries_ipc_bootstrap: reading radio image");
    radio_img_p = ipc_client_mtd_read(client, "/dev/block/bml12", RADIO_IMG_READ_SIZE, RADIO_IMG_READ_SIZE);
    ipc_client_log(client, "aries_ipc_bootstrap: radio image read");

    ipc_client_log(client, "aries_ipc_bootstrap: open onedram");
    onedram_fd=open("/dev/onedram", O_RDWR);
    if(onedram_fd < 0)
        goto error;

    /* Reset the modem before init to send the first part of modem.img. */
    ipc_client_log(client, "aries_ipc_bootstrap: turning %s iface down", PHONET_IFACE);
    rc = phonet_iface_ifdown();
    if(rc < 0)
        goto error;

    ipc_client_power_off(client);
    ipc_client_log(client, "aries_ipc_bootstrap: sent PHONE \"off\" command");
    usleep(1000);

    ipc_client_power_on(client);
    ipc_client_log(client, "aries_ipc_bootstrap: sent PHONE \"on\" command");
    usleep(200000);

    ipc_client_log(client, "aries_ipc_bootstrap: open s3c2410_serial3");
    s3c2410_serial3_fd=open("/dev/s3c2410_serial3", O_RDWR);
    if(s3c2410_serial3_fd < 0)
        goto error;

    /* Setup the s3c2410 serial. */
    ipc_client_log(client, "aries_ipc_bootstrap: setup s3c2410_serial3");
    tcgetattr(s3c2410_serial3_fd, &termios);

    cfmakeraw(&termios);
    cfsetispeed(&termios, B115200);
    cfsetospeed(&termios, B115200);

    tcsetattr(s3c2410_serial3_fd, TCSANOW, &termios);

    /* Send 'AT' in ASCII. */
    ipc_client_log(client, "aries_ipc_bootstrap: sending AT in ASCII");
    for(i=0 ; i < 20 ; i++)
    {
        rc = write(s3c2410_serial3_fd, "AT", 2);
        usleep(50000);
    }
    ipc_client_log(client, "aries_ipc_bootstrap: sending AT in ASCII done");

    usleep(50000); //FIXME

    /* Write the first part of modem.img. */
    FD_ZERO(&fds);
    FD_SET(s3c2410_serial3_fd, &fds);

    timeout.tv_sec=5;
    timeout.tv_usec=0;

    if(select(FD_SETSIZE, &fds, NULL, NULL, &timeout) == 0)
    {
        ipc_client_log(client, "aries_ipc_bootstrap: select timeout passed");
        goto error;
    }

    /* Get and check bootcore version. */
    read(s3c2410_serial3_fd, &bootcore_version, sizeof(bootcore_version));
    ipc_client_log(client, "aries_ipc_bootstrap: got bootcore version: 0x%x", bootcore_version);

    if(bootcore_version != BOOTCORE_VERSION)
        goto error;

    timeout.tv_sec=5;
    timeout.tv_usec=0;

    if(select(FD_SETSIZE, &fds, NULL, NULL, &timeout) == 0)
    {
        ipc_client_log(client, "aries_ipc_bootstrap: select timeout passed");
        goto error;
    }

    /* Get info_size. */
    read(s3c2410_serial3_fd, &info_size, sizeof(info_size));
    ipc_client_log(client, "aries_ipc_bootstrap: got info_size: 0x%x", info_size);

    timeout.tv_sec=5;
    timeout.tv_usec=0;

    if(select(FD_SETSIZE, NULL, &fds, NULL, &timeout) == 0)
    {
        ipc_client_log(client, "aries_ipc_bootstrap: select timeout passed");
        goto error;
    }

    /* Send PSI magic. */
    data=PSI_MAGIC;
    write(s3c2410_serial3_fd, &data, sizeof(data));
    ipc_client_log(client, "aries_ipc_bootstrap: sent PSI_MAGIC (0x%x)", PSI_MAGIC);

    /* Send PSI data len. */
    data_16=PSI_DATA_LEN;
    data_p=(uint8_t *)&data_16;

    for(i=0 ; i < 2 ; i++)
    {
        write(s3c2410_serial3_fd, data_p, 1);
        data_p++;
    }
    ipc_client_log(client, "aries_ipc_bootstrap: sent PSI_DATA_LEN (0x%x)", PSI_DATA_LEN);

    timeout.tv_sec=5;
    timeout.tv_usec=0;

    data_p=radio_img_p;

    ipc_client_log(client, "aries_ipc_bootstrap: sending the first part of radio.img");

    for(i=0 ; i < PSI_DATA_LEN ; i++)
    {
        if(select(FD_SETSIZE, NULL, &fds, NULL, &timeout) == 0)
        {
            ipc_client_log(client, "aries_ipc_bootstrap: select timeout passed");
            goto error;
        }

        write(s3c2410_serial3_fd, data_p, 1);
        crc_byte=crc_byte ^ *data_p;

        data_p++;
    }

    ipc_client_log(client, "aries_ipc_bootstrap: first part of radio.img sent; crc_byte is 0x%x", crc_byte);

    timeout.tv_sec=5;
    timeout.tv_usec=0;

    if(select(FD_SETSIZE, NULL, &fds, NULL, &timeout) == 0)
    {
        ipc_client_log(client, "aries_ipc_bootstrap: select timeout passed");
        goto error;
    }

    write(s3c2410_serial3_fd, &crc_byte, sizeof(crc_byte));

    ipc_client_log(client, "aries_ipc_bootstrap: crc_byte sent");

    data = 0;
    for(i = 0 ; data != 0x01 ; i++)
    {
        timeout.tv_sec=5;
        timeout.tv_usec=0;

        if(select(FD_SETSIZE, &fds, NULL, NULL, &timeout) == 0)
        {
            ipc_client_log(client, "aries_ipc_bootstrap: select timeout passed");
            goto error;
        }

        read(s3c2410_serial3_fd, &data, sizeof(data));

        if(i > 50)
        {
            ipc_client_log(client, "aries_ipc_bootstrap: fairly too much attempts to get ACK");
            goto error;
        }
    }

    ipc_client_log(client, "aries_ipc_bootstrap: close s3c2410_serial3");
    close(s3c2410_serial3_fd);

    FD_ZERO(&fds);
    FD_SET(onedram_fd, &fds);

    timeout.tv_sec=5;
    timeout.tv_usec=0;

    ipc_client_log(client, "aries_ipc_bootstrap: wait for 0x12341234 from onedram");
    if(select(FD_SETSIZE, &fds, NULL, NULL, &timeout) == 0)
    {
        ipc_client_log(client, "aries_ipc_bootstrap: select timeout passed");
        goto error;
    }

    read(onedram_fd, &onedram_data, sizeof(onedram_data));

    if(onedram_data != ONEDRAM_INIT_READ)
    {
        ipc_client_log(client, "aries_ipc_bootstrap: wrong onedram init magic (got 0x%04x)", onedram_data);
        goto error;
    }

    ipc_client_log(client, "aries_ipc_bootstrap: got 0x%04x", onedram_data);

    ipc_client_log(client, "aries_ipc_bootstrap: writing the rest of modem.img to onedram.");

    /* Pointer to the remaining part of radio.img. */
    data_p=radio_img_p + PSI_DATA_LEN;

    onedram_p = mmap(NULL, ONENAND_MAP_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, onedram_fd, 0);

    if(onedram_p == NULL || onedram_p < 0 || onedram_p == 0xffffffff)
    {
        ipc_client_log(client, "aries_ipc_bootstrap: could not map onedram to memory");
        goto error;
    }
 
    // it sometimes hangs here

    memcpy(onedram_p, data_p, RADIO_IMG_READ_SIZE - PSI_DATA_LEN);

    free(radio_img_p);

    /* nv_data part. */

    /* Check if all the nv_data files are ok. */
    if (nv_data_check(client) < 0)
        goto error;

    /* Check if the MD5 is ok. */
    if (nv_data_md5_check(client) < 0)
        goto error;

    /* Write nv_data.bin to modem_ctl. */
    ipc_client_log(client, "aries_ipc_bootstrap: write nv_data to onedram");

    nv_data_p = ipc_client_file_read(client, nv_data_path(client), nv_data_size(client), nv_data_chunk_size(client));
    if (nv_data_p == NULL)
        goto error;
    data_p = nv_data_p;

    memcpy(onedram_p + RADIO_IMG_MAX_SIZE, data_p, nv_data_size(client));

    free(nv_data_p);

    munmap(onedram_p, ONENAND_MAP_SIZE);

    if(ioctl(onedram_fd, ONEDRAM_REL_SEM) < 0)
    {
        ipc_client_log(client, "aries_ipc_bootstrap: ONEDRAM_REL_SEM ioctl on onedram failed");
        goto error;
    }

    onedram_data = ONEDRAM_DEINIT_CMD;

    timeout.tv_sec=5;
    timeout.tv_usec=0;

    ipc_client_log(client, "aries_ipc_bootstrap: send 0x%04x", onedram_data);
    write(onedram_fd, &onedram_data, sizeof(onedram_data));

    if(select(FD_SETSIZE, &fds, NULL, NULL, &timeout) == 0)
    {
        ipc_client_log(client, "aries_ipc_bootstrap: select timeout passed");
        goto error;
    }

    read(onedram_fd, &onedram_data, sizeof(onedram_data));

    if(onedram_data != ONEDRAM_DEINIT_READ)
    {
        ipc_client_log(client, "aries_ipc_bootstrap: wrong onedram deinit magic (got 0x%04x)", onedram_data);
        goto error;
    }

    ipc_client_log(client, "aries_ipc_bootstrap: got 0x%04x", onedram_data);

    close(onedram_fd);

    rc = 0;
    goto exit;

error:
    ipc_client_log(client, "aries_ipc_bootstrap: something went wrong");
    rc = -1;

exit:
    ipc_client_log(client, "aries_ipc_bootstrap: exit");
    return rc;
}
Exemplo n.º 24
0
static int maguro_send_image_addrs(struct ipc_client *client,
    struct modemctl_io_data *io_data)
{
    int ret = 0;

    uint32_t sec_off = maguro_radio_parts[SECURE_IMAGE].offset;
    uint32_t sec_len = maguro_radio_parts[SECURE_IMAGE].length;
    void *sec_img = io_data->radio_data + sec_off;
    void *nv_data = NULL;

    if ((ret = maguro_boot_cmd(client, io_data, ReqSecStart, sec_img, sec_len)) < 0) {
        ipc_client_log(client, "Error: failed to write ReqSecStart");
        goto fail;
    }
    else {
        ipc_client_log(client, "sent ReqSecStart");
    }

    if ((ret = maguro_send_image_addr(client, io_data, FW_LOAD_ADDR, FIRMWARE)) < 0) {
        ipc_client_log(client, "Error: failed to send FIRMWARE image");
        goto fail;
    }
    else {
        ipc_client_log(client, "sent FIRMWARE image");
    }

    if (nv_data_check(client) < 0)
        goto fail;

    if (nv_data_md5_check(client) < 0)
        goto fail;

    nv_data = ipc_client_file_read(client, nv_data_path(client), 2 << 20, 1024);
    if (nv_data == NULL) {
        ipc_client_log(client, "Error: failed to read NVDATA image");
        goto fail;
    }

    if ((ret = maguro_send_image_data(client, io_data, NVDATA_LOAD_ADDR, nv_data, 2 << 20)) < 0) {
        ipc_client_log(client, "Error: failed to send NVDATA image");
        goto fail;
    }
    else {
        ipc_client_log(client, "sent NVDATA image");
    }

    free(nv_data);

    if ((ret = maguro_send_mps_data(client, io_data)) < 0) {
        ipc_client_log(client, "Error: failed to send MPS data");
        goto fail;
    }
    else {
        ipc_client_log(client, "sent MPS data");
    }

    if ((ret = maguro_boot_cmd(client, io_data, ReqSecEnd,
        BL_END_MAGIC, BL_END_MAGIC_LEN)) < 0)
    {
        ipc_client_log(client, "Error: failed to write ReqSecEnd");
        goto fail;
    }
    else {
        ipc_client_log(client, "sent ReqSecEnd");
    }

    ret = maguro_boot_cmd(client, io_data, ReqForceHwReset,
        BL_RESET_MAGIC, BL_RESET_MAGIC_LEN);
    if (ret < 0) {
        ipc_client_log(client, "Error: failed to write ReqForceHwReset");
        goto fail;
    }
    else {
        ipc_client_log(client, "sent ReqForceHwReset");
    }

fail:
    return ret;
}
Exemplo n.º 25
0
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;
}
Exemplo n.º 26
0
int nv_data_check(struct ipc_client *client)
{
    struct stat nv_stat;
    int nv_state_fd=-1;
    int nv_state=0;
    int rc;

    ipc_client_log(client, "nv_data_check: enter\n");

    if (stat(nv_data_path(client), &nv_stat) < 0)
    {
        ipc_client_log(client, "nv_data_check: nv_data.bin missing\n");
        nv_data_backup_restore(client);
        stat(nv_data_path(client), &nv_stat);
    }

    if (nv_stat.st_size != nv_data_size(client))
    {
        ipc_client_log(client, "nv_data_check: wrong nv_data.bin size\n");
        nv_data_backup_restore(client);
    }

    if (stat(nv_data_md5_path(client), &nv_stat) < 0)
    {
        ipc_client_log(client, "nv_data_check: nv_data.bin.md5 missing\n");
        nv_data_backup_restore(client);
    }

    if (stat(nv_data_bak_path(client), &nv_stat) < 0 || stat(nv_data_md5_bak_path(client), &nv_stat) < 0)
    {
        ipc_client_log(client, "nv_data_check: .nv_data.bak or .nv_data.bak.md5 missing\n");
        nv_data_backup_create(client);
    }

    nv_state_fd=open(nv_state_path(client), O_RDONLY);

    if (nv_state_fd < 0 || fstat(nv_state_fd, &nv_stat) < 0)
    {
        ipc_client_log(client, "nv_data_check: .nv_state missing\n");
        nv_data_backup_restore(client);
    }

    rc = read(nv_state_fd, &nv_state, sizeof(nv_state));
    if (rc < 0)
    {
        ipc_client_log(client, "nv_data_check: couldn't read state of NV item from file\n");
        return -1;
    }

    close(nv_state_fd);

    if (nv_state != '1')
    {
        ipc_client_log(client, "nv_data_check: bad nv_state\n");
        nv_data_backup_restore(client);
    }

    ipc_client_log(client, "nv_data_check: everything should be alright\n");
    ipc_client_log(client, "nv_data_check: exit\n");

    return 0;
}
Exemplo n.º 27
0
void nv_data_backup_restore(struct ipc_client *client)
{
    uint8_t nv_data_md5_hash[MD5_DIGEST_LENGTH];
    char *nv_data_md5_hash_string = NULL;
    char *nv_data_md5_hash_read = NULL;
    int nv_data_write_tries = 0;

    struct stat nv_stat;
    void *nv_data_p = NULL;
    void *nv_data_bak_p = NULL;
    uint8_t data;

    int fd;
    int rc;
    int i;

    ipc_client_log(client, "nv_data_backup_restore: enter\n");

    if (stat(nv_data_bak_path(client), &nv_stat) < 0)
    {
        ipc_client_log(client, "nv_data_backup_restore: .nv_data.bak missing\n");
        nv_data_generate(client);
        nv_data_backup_create(client);
        return;
    }

    if (nv_stat.st_size != nv_data_size(client))
    {
        ipc_client_log(client, "nv_data_backup_restore: wrong .nv_data.bak size\n");
        nv_data_generate(client);
        nv_data_backup_create(client);
        return;
    }

    if (stat(nv_data_md5_bak_path(client), &nv_stat) < 0)
    {
        ipc_client_log(client, "nv_data_backup_restore: .nv_data.bak.md5 missing\n");
        nv_data_generate(client);
        nv_data_backup_create(client);
        return;
    }

    /* Alloc the memory for the md5 hashes strings. */
    nv_data_md5_hash_string=malloc(MD5_STRING_SIZE);
    nv_data_md5_hash_read=malloc(MD5_STRING_SIZE);

    memset(nv_data_md5_hash_read, 0, MD5_STRING_SIZE);
    memset(nv_data_md5_hash_string, 0, MD5_STRING_SIZE);

    /* Read the content of the backup file. */
    nv_data_bak_p=ipc_client_file_read(client, nv_data_bak_path(client),
        nv_data_size(client), nv_data_chunk_size(client));

    /* Compute the backup file MD5 hash. */
    nv_data_md5_compute(nv_data_bak_p, nv_data_size(client), nv_data_secret(client), nv_data_md5_hash);
    md5hash2string(nv_data_md5_hash_string, nv_data_md5_hash);

    /* Read the stored backup file MD5 hash. */
    fd=open(nv_data_md5_bak_path(client), O_RDONLY);
    rc = read(fd, nv_data_md5_hash_read, MD5_STRING_SIZE);
    if (rc < 0)
    {
        ipc_client_log(client, "nv_data_backup_restore: Failed to read md5 hash for stored back file\n");
        close(fd);
        goto exit;
    }

    close(fd);

    /* Add 0x0 to end the string: not sure this is always part of the file. */
    nv_data_md5_hash_read[MD5_STRING_SIZE - 1]='\0';

    ipc_client_log(client, "nv_data_backup_restore: backup file computed MD5: %s read MD5: %s\n",
        nv_data_md5_hash_string, nv_data_md5_hash_read);

    if (strcmp(nv_data_md5_hash_string, nv_data_md5_hash_read) != 0)
    {
        ipc_client_log(client, "nv_data_backup_restore: MD5 hash mismatch on backup file\n");
        ipc_client_log(client, "nv_data_backup_restore: Consider the computed one as correct\n");

        fd = open(nv_data_md5_bak_path(client), O_WRONLY);
        if (fd < 0)
        {
            ipc_client_log(client, "nv_data_backup_restore: failed to open MD5 hash backup file\n");
            goto exit;
        }

        rc = read(fd, nv_data_md5_hash_string, MD5_STRING_SIZE);
        if (rc < 0)
        {
            ipc_client_log(client, "nv_data_backup_restore: failed to read MD5 hash from backup file\n");
            close(fd);
            goto exit;
        }

        close(fd);

        /*
        nv_data_backup_generate(client);
        nv_data_backup_create(client);
        return;
        */
    }

    /* Assume the read string is the computated one */
    memcpy(nv_data_md5_hash_read, nv_data_md5_hash_string, MD5_STRING_SIZE);
    memset(nv_data_md5_hash_string, 0, MD5_STRING_SIZE);

nv_data_backup_restore_write:
   while (nv_data_write_tries < 5)
    {
        ipc_client_log(client, "nv_data_backup_restore: nv_data.bin write try #%d\n", nv_data_write_tries + 1);

        fd=open(nv_data_path(client), O_RDWR | O_CREAT | O_TRUNC, 0644);
        if (fd < 0)
        {
            ipc_client_log(client, "nv_data_backup_restore: negative fd while opening /efs/nv_data.bin, error: %s\n", strerror(errno));
            nv_data_write_tries++;
            continue;
        }

        rc = write(fd, nv_data_bak_p, nv_data_size(client));
        if (rc < nv_data_size(client))
        {
            ipc_client_log(client, "nv_data_backup_restore: wrote less (%d) than what we expected (%d) on /efs/nv_data.bin, error: %s\n", strerror(errno));
            close(fd);
            nv_data_write_tries++;
            continue;
        }

        close(fd);
        break;
    }

    if (nv_data_write_tries == 5)
    {
        ipc_client_log(client, "nv_data_backup_restore: writing the backup to nv_data.bin failed too many times\n");
        unlink(nv_data_path(client));
        goto exit;
    }

    /* Read the newly-written nv_data.bin. */
    nv_data_p=ipc_client_file_read(client, nv_data_path(client),
        nv_data_size(client), nv_data_chunk_size(client));

    /* Compute the MD5 hash for nv_data.bin. */
    nv_data_md5_compute(nv_data_p, nv_data_size(client), nv_data_secret(client), nv_data_md5_hash);
    md5hash2string(nv_data_md5_hash_string, nv_data_md5_hash);

    if (nv_data_p != NULL)
    {
        free(nv_data_p);
        nv_data_p = NULL;
    }

    ipc_client_log(client, "nv_data_backup_restore: written file computed MD5: %s read MD5: %s\n",
        nv_data_md5_hash_string, nv_data_md5_hash_read);

    /* Make sure both hashes are the same. */
    if (strcmp(nv_data_md5_hash_string, nv_data_md5_hash_read) != 0)
    {
        ipc_client_log(client, "nv_data_backup_restore: MD5 hash mismatch on written file\n");
        ipc_client_log(client, "nv_data_backup_restore: Writing again\n");

        goto nv_data_backup_restore_write;
    }

    /* Write the MD5 hash in nv_data.bin.md5. */
    fd = open(nv_data_md5_path(client), O_WRONLY | O_CREAT | O_TRUNC, 0644);
    if (fd < 0)
    {
        ipc_client_log(client, "nv_data_backup_restore: failed to open file with MD5 hash\n");
        goto exit;
    }

    rc = write(fd, nv_data_md5_hash_read, MD5_STRING_SIZE);
    if (rc < 0)
    {
        ipc_client_log(client, "nv_data_backup_restore: failed to write MD5 hash to file\n");
        close(fd);
        goto exit;
    }
    close(fd);

    /* Write the correct .nv_state. */
    fd = open(nv_state_path(client), O_WRONLY | O_CREAT | O_TRUNC, 0644);
    if (fd < 0)
    {
        ipc_client_log(client, "nv_data_backup_restore: failed to open NV state file\n");
        goto exit;
    }

    data='1';
    rc = write(fd, &data, sizeof(data));
    if (rc <  0)
    {
        ipc_client_log(client, "nv_data_backup_restore: failed to write state to file\n");
        close(fd);
        goto exit;
    }

    close(fd);

exit:
    if (nv_data_bak_p != NULL)
        free(nv_data_bak_p);
    if (nv_data_md5_hash_string != NULL)
        free(nv_data_md5_hash_string);
    if (nv_data_md5_hash_read != NULL)
        free(nv_data_md5_hash_read);

    ipc_client_log(client, "nv_data_backup_restore: exit\n");
}
Exemplo n.º 28
0
void nv_data_generate(struct ipc_client *client)
{
    ipc_client_log(client, "This feature isn't present yet\n");

//  nv_data_backup_create();
}
Exemplo n.º 29
0
int crespo_modem_bootstrap(struct ipc_client *client)
{
    int s3c2410_serial3_fd = -1;
    int modem_ctl_fd = -1;

    /* Control variables. */
    int boot_tries_count = 0;
    int rc = 0;

    /* Boot variables */
    uint8_t *radio_img_p = NULL;
    uint8_t bootcore_version = 0;
    uint8_t info_size = 0;
    uint8_t crc_byte = 0;
    int block_size = 0;

    /* s3c2410 serial setup variables. */
    struct termios termios;
    int serial;

    /* fds maniplation variables */
    struct timeval timeout;
    fd_set fds;

    /* nv_data variables */
    void *nv_data_p;

    /* General purpose variables. */
    uint8_t data;
    uint16_t data_16;
    uint8_t *data_p;
    int i;

    ipc_client_log(client, "crespo_ipc_bootstrap: enter");

boot_loop_start:
    if(boot_tries_count > 5)
    {
        ipc_client_log(client, "crespo_ipc_bootstrap: boot has failed too many times.");
        goto error;
    }

    /* Read the radio.img image. */
    ipc_client_log(client, "crespo_ipc_bootstrap: reading radio image");
    radio_img_p = ipc_mtd_read(client, "/dev/mtd/mtd5ro", RADIO_IMG_SIZE, 0x1000);
    if (radio_img_p == NULL) {
        radio_img_p = ipc_mtd_read(client, "/dev/mtd5ro", RADIO_IMG_SIZE, 0x1000);
        if (radio_img_p == NULL)
            goto error;
    }
    ipc_client_log(client, "crespo_ipc_bootstrap: radio image read");

    ipc_client_log(client, "crespo_ipc_bootstrap: open modem_ctl");
    modem_ctl_fd=open("/dev/modem_ctl", O_RDWR | O_NDELAY);
    if(modem_ctl_fd < 0)
        goto error_loop;

    /* Reset the modem before init to send the first part of modem.img. */
    ioctl(modem_ctl_fd, IOCTL_MODEM_RESET);
    usleep(400000);

    ipc_client_log(client, "crespo_ipc_bootstrap: open s3c2410_serial3");
    s3c2410_serial3_fd=open("/dev/s3c2410_serial3", O_RDWR | O_NDELAY);
    if(s3c2410_serial3_fd < 0)
        goto error_loop;

    /* Setup the s3c2410 serial. */
    ipc_client_log(client, "crespo_ipc_bootstrap: setup s3c2410_serial3");
    tcgetattr(s3c2410_serial3_fd, &termios);

    cfmakeraw(&termios);
    cfsetispeed(&termios, B115200);
    cfsetospeed(&termios, B115200);

    tcsetattr(s3c2410_serial3_fd, TCSANOW, &termios);

    /* Send 'AT' in ASCII. */
    ipc_client_log(client, "crespo_ipc_bootstrap: sending AT in ASCII");
    for(i=0 ; i < 20 ; i++)
    {
        rc = write(s3c2410_serial3_fd, "AT", 2);
        usleep(50000);
    }
    ipc_client_log(client, "crespo_ipc_bootstrap: sending AT in ASCII done");

    usleep(50000); //FIXME

    /* Get and check bootcore version. */
    read(s3c2410_serial3_fd, &bootcore_version, sizeof(bootcore_version));
    ipc_client_log(client, "crespo_ipc_bootstrap: got bootcore version: 0x%x", bootcore_version);

    if(bootcore_version != BOOTCORE_VERSION)
        goto error_loop;

    /* Get info_size. */
    read(s3c2410_serial3_fd, &info_size, sizeof(info_size));
    ipc_client_log(client, "crespo_ipc_bootstrap: got info_size: 0x%x", info_size);

    /* Send PSI magic. */
    data=PSI_MAGIC;
    write(s3c2410_serial3_fd, &data, sizeof(data));
    ipc_client_log(client, "crespo_ipc_bootstrap: sent PSI_MAGIC (0x%x)", PSI_MAGIC);

    /* Send PSI data len. */
    data_16=PSI_DATA_LEN;
    data_p=(uint8_t *)&data_16;

    for(i=0 ; i < 2 ; i++)
    {
        write(s3c2410_serial3_fd, data_p, 1);
        data_p++;
    }
    ipc_client_log(client, "crespo_ipc_bootstrap: sent PSI_DATA_LEN (0x%x)", PSI_DATA_LEN);

    /* Write the first part of modem.img. */
    FD_ZERO(&fds);
    FD_SET(s3c2410_serial3_fd, &fds);

    timeout.tv_sec=4;
    timeout.tv_usec=0;

    data_p=radio_img_p;

    ipc_client_log(client, "crespo_ipc_bootstrap: sending the first part of radio.img");

    for(i=0 ; i < PSI_DATA_LEN ; i++)
    {
        if(select(FD_SETSIZE, NULL, &fds, NULL, &timeout) == 0)
        {
            ipc_client_log(client, "crespo_ipc_bootstrap: select timeout passed");
            goto error_loop;
        }

        write(s3c2410_serial3_fd, data_p, 1);
        crc_byte=crc_byte ^ *data_p;

        data_p++;
    }

    ipc_client_log(client, "crespo_ipc_bootstrap: first part of radio.img sent; crc_byte is 0x%x", crc_byte);

    if(select(FD_SETSIZE, NULL, &fds, NULL, &timeout) == 0)
    {
        ipc_client_log(client, "crespo_ipc_bootstrap: select timeout passed");
        goto error_loop;
    }

    write(s3c2410_serial3_fd, &crc_byte, sizeof(crc_byte));

    ipc_client_log(client, "crespo_ipc_bootstrap: crc_byte sent");

    data = 0;
    for(i = 0 ; data != 0x01 ; i++)
    {
        if(select(FD_SETSIZE, &fds, NULL, NULL, &timeout) == 0)
        {
            ipc_client_log(client, "crespo_ipc_bootstrap: select timeout passed");
            goto error_loop;
        }

        read(s3c2410_serial3_fd, &data, sizeof(data));

        if(i > 50)
        {
            ipc_client_log(client, "crespo_ipc_bootstrap: fairly too much attempts to get ACK");
            goto error_loop;
        }
    }

    ipc_client_log(client, "crespo_ipc_bootstrap: close s3c2410_serial3");
    close(s3c2410_serial3_fd);

    ipc_client_log(client, "crespo_ipc_bootstrap: writing the rest of radio.img to modem_ctl.");
    /* Seek to the begining of modem_ctl_fd (should already be so). */
    lseek(modem_ctl_fd, 0, SEEK_SET);

    /* Pointer to the remaining part of radio.img. */
    data_p=radio_img_p + PSI_DATA_LEN;

    FD_ZERO(&fds);
    FD_SET(modem_ctl_fd, &fds);

    block_size = 0x100000;

    for(i=0 ; i < (RADIO_IMG_SIZE - PSI_DATA_LEN) / block_size ; i++)
    {
        if(select(FD_SETSIZE, NULL, &fds, NULL, &timeout) == 0)
        {
            ipc_client_log(client, "crespo_ipc_bootstrap: select timeout passed");
            goto error_loop;
        }

        write(modem_ctl_fd, data_p, block_size);
        data_p += block_size;
    }

    free(radio_img_p);

    /* nv_data part. */

    /* Check if all the nv_data files are ok. */
    nv_data_check(client);

    /* Check if the MD5 is ok. */
    nv_data_md5_check(client);

    /* Write nv_data.bin to modem_ctl. */
    ipc_client_log(client, "crespo_ipc_bootstrap: write nv_data to modem_ctl");

    nv_data_p = ipc_file_read(client, "/efs/nv_data.bin", NV_DATA_SIZE, 1024);
    if (nv_data_p == NULL)
        goto error;
    data_p = nv_data_p;

    lseek(modem_ctl_fd, RADIO_IMG_SIZE, SEEK_SET);

    for(i=0 ; i < 2 ; i++)
    {
        write(modem_ctl_fd, data_p, NV_DATA_SIZE / 2);
        data_p += NV_DATA_SIZE / 2;
    }

    free(nv_data_p);

    close(modem_ctl_fd);

    rc = 0;
    goto exit;

error_loop:
    ipc_client_log(client, "%s: something went wrong", __func__);
    boot_tries_count++;
    sleep(2);

    goto boot_loop_start;

error:
    ipc_client_log(client, "%s: something went wrong", __func__);
    rc = -1;
exit:
    ipc_client_log(client, "crespo_ipc_bootstrap: exit");
    return rc;
}
Exemplo n.º 30
0
void ipc_parse_dbg(struct ipc_client *client, struct modem_io *ipc_frame)
{
	ipc_client_log(client, "AMSS debugstring - %s\n", (char *)(ipc_frame->data));
}