static inline void udps_write(TCPIPS* tcpips, HANDLE handle, IO* io) { IO* cur; unsigned int offset, size; unsigned short remote_port; IP dst; UDP_STACK* udp_stack; UDP_HEADER* udp; UDP_HANDLE* uh = so_get(&tcpips->udps.handles, handle); if (uh == NULL) return; #if (ICMP) if (uh->err != ERROR_OK) { error(uh->err); return; } #endif //ICMP //listening socket if (uh->remote_port == 0) { if (io->stack_size < sizeof(UDP_STACK)) { error(ERROR_INVALID_PARAMS); return; } udp_stack = io_stack(io); remote_port = udp_stack->remote_port; dst.u32.ip = udp_stack->remote_addr.u32.ip; io_pop(io, sizeof(UDP_STACK)); } else { remote_port = uh->remote_port; dst.u32.ip = uh->remote_addr.u32.ip; } for (offset = 0; offset < io->data_size; offset += size) { size = UDP_FRAME_MAX_DATA_SIZE; if (size > io->data_size - offset) size = io->data_size - offset; cur = ips_allocate_io(tcpips, size + sizeof(UDP_HEADER), PROTO_UDP); if (cur == NULL) return; //copy data memcpy((uint8_t*)io_data(cur) + sizeof(UDP_HEADER), (uint8_t*)io_data(io) + offset, size); udp = io_data(cur); // correct size cur->data_size = size + sizeof(UDP_HEADER); //format header short2be(udp->src_port_be, uh->local_port); short2be(udp->dst_port_be, remote_port); short2be(udp->len_be, size + sizeof(UDP_HEADER)); short2be(udp->checksum_be, 0); short2be(udp->checksum_be, udp_checksum(io_data(cur), cur->data_size, &tcpips->ips.ip, &dst)); ips_tx(tcpips, cur, &dst); } }
/** * Updates the parser. * * Takes all available bytes from the incoming buffer and * then puts them in the parser. * @todo Abort when parser_add_byte fails, or better get a * test function to check for more space. */ void parser_update(void) { uint8_t value = 0, times = 255 - io_get_free_buffer_size(); for (; 0 < times; times--) { io_get(&value); if (parser_add_byte(value) == 0) { io_pop(); } else { break; } } }
static inline void lpc_sdmmc_io(CORE* core, HANDLE process, HANDLE user, IO* io, unsigned int size, bool read) { SHA1_CTX sha1; unsigned int count; STORAGE_STACK* stack = io_stack(io); io_pop(io, sizeof(STORAGE_STACK)); if (!core->sdmmc.active) { error(ERROR_NOT_CONFIGURED); return; } if (core->sdmmc.state != SDMMC_STATE_IDLE) { error(ERROR_IN_PROGRESS); return; } if ((user != core->sdmmc.user) || (size == 0)) { error(ERROR_INVALID_PARAMS); return; } //erase if (!read && ((stack->flags & STORAGE_MASK_MODE) == 0)) { sdmmcs_erase(&core->sdmmc.sdmmcs, stack->sector, size); return; } if (size % core->sdmmc.sdmmcs.sector_size) { error(ERROR_INVALID_PARAMS); return; } count = size / core->sdmmc.sdmmcs.sector_size; core->sdmmc.total = size; if (core->sdmmc.total > LPC_SDMMC_TOTAL_SIZE) { error(ERROR_INVALID_PARAMS); return; } if ((core->sdmmc.activity != INVALID_HANDLE) && !(stack->flags & STORAGE_FLAG_IGNORE_ACTIVITY_ON_REQUEST)) { ipc_post_inline(core->sdmmc.activity, HAL_CMD(HAL_SDMMC, STORAGE_NOTIFY_ACTIVITY), core->sdmmc.user, read ? 0 : STORAGE_FLAG_WRITE, 0); core->sdmmc.activity = INVALID_HANDLE; } core->sdmmc.io = io; core->sdmmc.process = process; lpc_sdmmc_prepare_descriptors(core); if (read) { io->data_size = 0; core->sdmmc.state = SDMMC_STATE_READ; if (sdmmcs_read(&core->sdmmc.sdmmcs, stack->sector, count)) error(ERROR_SYNC); } else { switch (stack->flags & STORAGE_MASK_MODE) { case STORAGE_FLAG_WRITE: core->sdmmc.state = SDMMC_STATE_WRITE; if (sdmmcs_write(&core->sdmmc.sdmmcs, stack->sector, count)) error(ERROR_SYNC); break; default: //verify/verify write sha1_init(&sha1); sha1_update(&sha1, io_data(io), core->sdmmc.total); sha1_final(&sha1, core->sdmmc.hash); core->sdmmc.sector = stack->sector; switch (stack->flags & STORAGE_MASK_MODE) { case STORAGE_FLAG_VERIFY: core->sdmmc.state = SDMMC_STATE_VERIFY; if (sdmmcs_read(&core->sdmmc.sdmmcs, stack->sector, count)) error(ERROR_SYNC); break; case (STORAGE_FLAG_VERIFY | STORAGE_FLAG_WRITE): core->sdmmc.state = SDMMC_STATE_WRITE_VERIFY; if (sdmmcs_write(&core->sdmmc.sdmmcs, stack->sector, count)) error(ERROR_SYNC); break; default: error(ERROR_NOT_SUPPORTED); return; } } } }