/** 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; }
/** 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; }
/** 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; }
/** 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; }
/** 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; }