Пример #1
0
/** Prepare a write request (WRQ) with filename
 *
 * \return Zero on success, otherwise a negative error code.
 */
int ec_foe_prepare_wrq_send(
        ec_fsm_foe_t *fsm, /**< Finite state machine. */
        ec_datagram_t *datagram /**< Datagram to use. */
        )
{
    size_t current_size;
    uint8_t *data;

    fsm->tx_buffer_offset = 0;
    fsm->tx_current_size = 0;
    fsm->tx_packet_no = 0;
    fsm->tx_last_packet = 0;

    current_size = fsm->tx_filename_len;

    data = ec_slave_mbox_prepare_send(fsm->slave, datagram,
            EC_MBOX_TYPE_FILEACCESS, current_size + EC_FOE_HEADER_SIZE);
    if (IS_ERR(data)) {
        return -1;
    }

    EC_WRITE_U16( data, EC_FOE_OPCODE_WRQ); // fsm write request
    EC_WRITE_U32( data + 2, fsm->tx_packet_no );

    memcpy(data + EC_FOE_HEADER_SIZE, fsm->tx_filename, current_size);

    return 0;
}
Пример #2
0
/** Prepare a read request (RRQ) with filename
 *
 * \return Zero on success, otherwise a negative error code.
 */
int ec_foe_prepare_rrq_send(
        ec_fsm_foe_t *fsm, /**< Finite state machine. */
        ec_datagram_t *datagram /**< Datagram to use. */
        )
{
    size_t current_size;
    uint8_t *data;

    current_size = fsm->rx_filename_len;

    data = ec_slave_mbox_prepare_send(fsm->slave, datagram,
            EC_MBOX_TYPE_FILEACCESS, current_size + EC_FOE_HEADER_SIZE);
    if (IS_ERR(data)) {
        return -1;
    }

    EC_WRITE_U16(data, EC_FOE_OPCODE_RRQ); // fsm read request
    EC_WRITE_U32(data + 2, 0x00000000); // no passwd
    memcpy(data + EC_FOE_HEADER_SIZE, fsm->rx_filename, current_size);

    if (fsm->slave->master->debug_level) {
        EC_SLAVE_DBG(fsm->slave, 1, "FoE Read Request:\n");
        ec_print_data(data, current_size + EC_FOE_HEADER_SIZE);
    }

    return 0;
}
Пример #3
0
/** Sends a file or the next fragment.
 *
 * \return Zero on success, otherwise a negative error code.
 */
int ec_foe_prepare_data_send(
        ec_fsm_foe_t *fsm, /**< Finite state machine. */
        ec_datagram_t *datagram /**< Datagram to use. */
        )
{
    size_t remaining_size, current_size;
    uint8_t *data;

    remaining_size = fsm->tx_buffer_size - fsm->tx_buffer_offset;

    if (remaining_size < fsm->slave->configured_tx_mailbox_size
            - EC_MBOX_HEADER_SIZE - EC_FOE_HEADER_SIZE) {
        current_size = remaining_size;
        fsm->tx_last_packet = 1;
    } else {
        current_size = fsm->slave->configured_tx_mailbox_size
            - EC_MBOX_HEADER_SIZE - EC_FOE_HEADER_SIZE;
    }

    data = ec_slave_mbox_prepare_send(fsm->slave,
            datagram, EC_MBOX_TYPE_FILEACCESS,
            current_size + EC_FOE_HEADER_SIZE);
    if (IS_ERR(data)) {
        return -1;
    }

    EC_WRITE_U16(data, EC_FOE_OPCODE_DATA);    // OpCode = DataBlock req.
    EC_WRITE_U32(data + 2, fsm->tx_packet_no); // PacketNo, Password

    memcpy(data + EC_FOE_HEADER_SIZE,
            fsm->tx_buffer + fsm->tx_buffer_offset, current_size);
    fsm->tx_current_size = current_size;

    return 0;
}
Пример #4
0
/** Prepare to send an acknowledge.
 *
 * \return Zero on success, otherwise a negative error code.
 */
int ec_foe_prepare_send_ack(
        ec_fsm_foe_t *fsm, /**< FoE statemachine. */
        ec_datagram_t *datagram /**< Datagram to use. */
        )
{
    uint8_t *data;

    data = ec_slave_mbox_prepare_send(fsm->slave, datagram,
            EC_MBOX_TYPE_FILEACCESS, EC_FOE_HEADER_SIZE);
    if (IS_ERR(data)) {
        return -1;
    }

    EC_WRITE_U16(data, EC_FOE_OPCODE_ACK);
    EC_WRITE_U32(data + 2, fsm->rx_expected_packet_no);

    return 0;
}
Пример #5
0
/** Prepare a set IP parameters operation.
 *
 * \return 0 on success, otherwise a negative error code.
 */
int ec_fsm_eoe_prepare_set(
        ec_fsm_eoe_t *fsm, /**< finite state machine */
        ec_datagram_t *datagram /**< Datagram to use. */
        )
{
    uint8_t *data, *cur;
    ec_slave_t *slave = fsm->slave;
    ec_master_t *master = slave->master;
    ec_eoe_request_t *req = fsm->request;
    size_t size = 8;

    if (req->mac_address_included) {
        size += ETH_ALEN;
    }

    if (req->ip_address_included) {
        size += 4;
    }

    if (req->subnet_mask_included) {
        size += 4;
    }

    if (req->gateway_included) {
        size += 4;
    }

    if (req->dns_included) {
        size += 4;
    }

    if (req->name_included) {
        size += EC_MAX_HOSTNAME_SIZE;
    }

    data = ec_slave_mbox_prepare_send(slave, datagram, EC_MBOX_TYPE_EOE,
            size);
    if (IS_ERR(data)) {
        return PTR_ERR(data);
    }

    EC_WRITE_U8(data, EC_EOE_FRAMETYPE_SET_IP_REQ); // Set IP parameter req.
    EC_WRITE_U8(data + 1, 0x01); // last fragment, no timestamps
    EC_WRITE_U16(data + 2, 0x0000); // fragment no., offset, frame no.

    EC_WRITE_U32(data + 4,
            ((req->mac_address_included != 0) << 0) |
            ((req->ip_address_included != 0) << 1) |
            ((req->subnet_mask_included != 0) << 2) |
            ((req->gateway_included != 0) << 3) |
            ((req->dns_included != 0) << 4) |
            ((req->name_included != 0) << 5)
            );

    cur = data + 8;

    if (req->mac_address_included) {
        memcpy(cur, req->mac_address, ETH_ALEN);
        cur += ETH_ALEN;
    }

    if (req->ip_address_included) {
        memcpy(cur, &req->ip_address, 4);
        cur += 4;
    }

    if (req->subnet_mask_included) {
        memcpy(cur, &req->subnet_mask, 4);
        cur += 4;
    }

    if (req->gateway_included) {
        memcpy(cur, &req->gateway, 4);
        cur += 4;
    }

    if (req->dns_included) {
        memcpy(cur, &req->dns, 4);
        cur += 4;
    }

    if (req->name_included) {
        memcpy(cur, req->name, EC_MAX_HOSTNAME_SIZE);
        cur += EC_MAX_HOSTNAME_SIZE;
    }

    if (master->debug_level) {
        EC_SLAVE_DBG(slave, 0, "Set IP parameter request:\n");
        ec_print_data(data, cur - data);
    }

    fsm->request->jiffies_sent = jiffies;

    return 0;
}