static u8_t *recv_cb(u8_t *buf, size_t *off) { struct btp_hdr *cmd = (void *) buf; u8_t *new_buf; u16_t len; if (*off < sizeof(*cmd)) { return buf; } len = sys_le16_to_cpu(cmd->len); if (len > BTP_MTU - sizeof(*cmd)) { SYS_LOG_ERR("BT tester: invalid packet length"); *off = 0; return buf; } if (*off < sizeof(*cmd) + len) { return buf; } new_buf = k_fifo_get(&avail_queue, K_NO_WAIT); if (!new_buf) { SYS_LOG_ERR("BT tester: RX overflow"); *off = 0; return buf; } k_fifo_put(&cmds_queue, buf); *off = 0; return new_buf; }
/* Allocate and send data to USB Host */ static void send_data(u8_t *cfg, u8_t *data, size_t len) { struct net_pkt *pkt; struct net_buf *buf; pkt = net_pkt_get_reserve_rx(0, K_NO_WAIT); if (!pkt) { SYS_LOG_DBG("No pkt available"); return; } buf = net_pkt_get_frag(pkt, K_NO_WAIT); if (!buf) { SYS_LOG_DBG("No fragment available"); net_pkt_unref(pkt); return; } net_pkt_frag_insert(pkt, buf); SYS_LOG_DBG("queue pkt %p buf %p len %u", pkt, buf, len); /* Add configuration id */ memcpy(net_buf_add(buf, 2), cfg, 2); memcpy(net_buf_add(buf, len), data, len); /* simulate LQI */ net_buf_add(buf, 1); /* simulate FCS */ net_buf_add(buf, 2); k_fifo_put(&tx_queue, pkt); }
/** * @brief Attempts to process a received byte as part of an mcumgr frame. * * @param cmd The console command currently being received. * @param byte The byte just received. * * @return true if the command being received is an mcumgr frame; false if it * is a plain console command. */ static bool handle_mcumgr(struct console_input *cmd, uint8_t byte) { int mcumgr_state; mcumgr_state = read_mcumgr_byte(byte); if (mcumgr_state == CONSOLE_MCUMGR_STATE_NONE) { /* Not an mcumgr command; let the normal console handling * process the byte. */ cmd->is_mcumgr = 0; return false; } /* The received byte is part of an mcumgr command. Process the byte * and return true to indicate that normal console handling should * ignore it. */ if (cur + end < sizeof(cmd->line) - 1) { cmd->line[cur++] = byte; } if (mcumgr_state == CONSOLE_MCUMGR_STATE_PAYLOAD && byte == '\n') { cmd->line[cur + end] = '\0'; cmd->is_mcumgr = 1; k_fifo_put(lines_queue, cmd); clear_mcumgr(); cmd = NULL; cur = 0; end = 0; } return true; }
static void interrupt_handler(struct device *unused) { while (uart_irq_update(uart_dev) && uart_irq_is_pending(uart_dev)) { if (uart_irq_tx_ready(uart_dev)) data_transmitted = true; if (uart_irq_rx_ready(uart_dev)) { int len = uart_fifo_read(uart_dev, rx_buffer, sizeof(rx_buffer)); if (len == 0) { printf("RX data ZERO\n"); continue; } else { uart_buf_t *rx_buf = &buf_pool[pool_index]; memcpy(rx_buf->data, rx_buffer, len); rx_buf->len = len; printf("FIFO put (%d): %d bytes\n", pool_index, len); k_fifo_put(&rx_fifo, rx_buf); pool_index++; if (pool_index == BUF_COUNT) pool_index = 0; } } else { printf("ISR: spurious\n"); //break; } } }
static void line_queue_init(void) { int i; for (i = 0; i < MAX_CMD_QUEUED; i++) { k_fifo_put(&avail_queue, &buf[i]); } }
int net_recv_data(struct net_if *iface, struct net_pkt *pkt) { SYS_LOG_DBG("Got data, pkt %p, frags->len %d", pkt, net_pkt_get_len(pkt)); k_fifo_put(&tx_queue, pkt); return 0; }
static void alarm_handler(struct device *dev) { /* Unblock LMT application thread. */ k_fifo_put(&fifo, NULL); /* Send a dummy message to ARC so the ARC application * thread can be unblocked. */ ipm_send(ipm, 0, 0, NULL, 0); }
/* a thread is started with a delay, then it reports that it ran via a fifo */ static void delayed_thread(void *num, void *arg2, void *arg3) { struct timeout_order *timeout = &timeouts[(int)num]; ARG_UNUSED(arg2); ARG_UNUSED(arg3); TC_PRINT(" thread (q order: %d, t/o: %d) is running\n", timeout->q_order, timeout->timeout); k_fifo_put(&timeout_order_fifo, timeout); }
void tester_init(void) { int i; for (i = 0; i < CMD_QUEUED; i++) { k_fifo_put(&avail_queue, &cmd_buf[i * BTP_MTU]); } k_thread_create(&cmd_thread, stack, STACKSIZE, cmd_handler, NULL, NULL, NULL, K_PRIO_COOP(7), 0, K_NO_WAIT); uart_pipe_register(k_fifo_get(&avail_queue, K_NO_WAIT), BTP_MTU, recv_cb); tester_send(BTP_SERVICE_ID_CORE, CORE_EV_IUT_READY, BTP_INDEX_NONE, NULL, 0); }
static void shell(void *p1, void *p2, void *p3) { ARG_UNUSED(p1); ARG_UNUSED(p2); ARG_UNUSED(p3); while (1) { struct console_input *cmd; printk("%s", get_prompt()); cmd = k_fifo_get(&cmds_queue, K_FOREVER); shell_exec(cmd->line); k_fifo_put(&avail_queue, cmd); } }
static void interrupt_handler(struct device *dev) { while (uart_irq_update(dev) && uart_irq_is_pending(dev)) { #ifdef VERBOSE_DEBUG SYS_LOG_DBG(""); #endif if (uart_irq_tx_ready(dev)) { #ifdef VERBOSE_DEBUG SYS_LOG_DBG("TX ready interrupt"); #endif k_sem_give(&tx_sem); } if (uart_irq_rx_ready(dev)) { unsigned char byte; #ifdef VERBOSE_DEBUG SYS_LOG_DBG("RX ready interrupt"); #endif while (uart_fifo_read(dev, &byte, sizeof(byte))) { if (slip_process_byte(byte)) { /** * slip_process_byte() returns 1 on * SLIP_END, even after receiving full * packet */ if (!pkt_curr) { SYS_LOG_DBG("Skip SLIP_END"); continue; } SYS_LOG_DBG("Full packet %p", pkt_curr); k_fifo_put(&rx_queue, pkt_curr); pkt_curr = NULL; } } } } }
static inline void telnet_handle_input(struct net_pkt *pkt) { struct console_input *input; size_t len; len = net_pkt_remaining_data(pkt); if (len > CONSOLE_MAX_LINE_LEN || len < TELNET_MIN_MSG) { return; } if (telnet_handle_command(pkt)) { return; } if (!avail_queue || !input_queue) { return; } input = k_fifo_get(avail_queue, K_NO_WAIT); if (!input) { return; } len = MIN(len, CONSOLE_MAX_LINE_LEN); if (net_pkt_read_new(pkt, (u8_t *)input->line, len)) { return; } /* LF/CR will be removed if only the line is not NUL terminated */ if (input->line[len - 1] != NVT_NUL) { if (input->line[len - 1] == NVT_LF) { input->line[len - 1] = NVT_NUL; } if (input->line[len - 2] == NVT_CR) { input->line[len - 2] = NVT_NUL; } } k_fifo_put(input_queue, input); }
static void cmd_handler(void *p1, void *p2, void *p3) { while (1) { struct btp_hdr *cmd; u16_t len; cmd = k_fifo_get(&cmds_queue, K_FOREVER); len = sys_le16_to_cpu(cmd->len); /* TODO * verify if service is registered before calling handler */ switch (cmd->service) { case BTP_SERVICE_ID_CORE: handle_core(cmd->opcode, cmd->index, cmd->data, len); break; case BTP_SERVICE_ID_GAP: tester_handle_gap(cmd->opcode, cmd->index, cmd->data, len); break; case BTP_SERVICE_ID_GATT: tester_handle_gatt(cmd->opcode, cmd->index, cmd->data, len); break; #if defined(CONFIG_BLUETOOTH_L2CAP_DYNAMIC_CHANNEL) case BTP_SERVICE_ID_L2CAP: tester_handle_l2cap(cmd->opcode, cmd->index, cmd->data, len); #endif /* CONFIG_BLUETOOTH_L2CAP_DYNAMIC_CHANNEL */ break; default: tester_rsp(cmd->service, cmd->opcode, cmd->index, BTP_STATUS_FAILED); break; } k_fifo_put(&avail_queue, cmd); } }
/* Receive encrypted data from network. Put that data into fifo * that will be read by https thread. */ static void ssl_received(struct net_context *context, struct net_pkt *pkt, int status, void *user_data) { struct http_client_ctx *http_ctx = user_data; struct rx_fifo_block *rx_data = NULL; struct k_mem_block block; int ret; ARG_UNUSED(context); ARG_UNUSED(status); if (pkt && !net_pkt_appdatalen(pkt)) { net_pkt_unref(pkt); return; } ret = k_mem_pool_alloc(http_ctx->https.pool, &block, sizeof(struct rx_fifo_block), BUF_ALLOC_TIMEOUT); if (ret < 0) { if (pkt) { net_pkt_unref(pkt); } return; } rx_data = block.data; rx_data->pkt = pkt; /* For freeing memory later */ memcpy(&rx_data->block, &block, sizeof(struct k_mem_block)); k_fifo_put(&http_ctx->https.mbedtls.ssl_ctx.rx_fifo, (void *)rx_data); /* Let the ssl_rx() to run */ k_yield(); }
static inline void telnet_handle_input(struct net_pkt *pkt) { struct console_input *input; u16_t len, offset, pos; len = net_pkt_appdatalen(pkt); if (len > CONSOLE_MAX_LINE_LEN || len < TELNET_MIN_MSG) { return; } if (telnet_handle_command(pkt)) { return; } if (!avail_queue || !input_queue) { return; } input = k_fifo_get(avail_queue, K_NO_WAIT); if (!input) { return; } offset = net_pkt_get_len(pkt) - len; net_frag_read(pkt->frags, offset, &pos, len, input->line); /* LF/CR will be removed if only the line is not NUL terminated */ if (input->line[len-1] != NVT_NUL) { if (input->line[len-1] == NVT_LF) { input->line[len-1] = NVT_NUL; } if (input->line[len-2] == NVT_CR) { input->line[len-2] = NVT_NUL; } } k_fifo_put(input_queue, input); }
/* Called by driver when an IP packet has been received */ int net_recv_data(struct net_if *iface, struct net_pkt *pkt) { NET_ASSERT(pkt && pkt->frags); NET_ASSERT(iface); if (!pkt->frags) { return -ENODATA; } if (!atomic_test_bit(iface->flags, NET_IF_UP)) { return -ENETDOWN; } NET_DBG("fifo %p iface %p pkt %p len %zu", &rx_queue, iface, pkt, net_pkt_get_len(pkt)); net_pkt_set_iface(pkt, iface); k_fifo_put(&rx_queue, pkt); return 0; }
void uart_console_isr(struct device *unused) { ARG_UNUSED(unused); while (uart_irq_update(uart_console_dev) && uart_irq_is_pending(uart_console_dev)) { static struct console_input *cmd; u8_t byte; int rx; if (!uart_irq_rx_ready(uart_console_dev)) { continue; } /* Character(s) have been received */ rx = read_uart(uart_console_dev, &byte, 1); if (rx < 0) { return; } #ifdef CONFIG_UART_CONSOLE_DEBUG_SERVER_HOOKS if (debug_hook_in != NULL && debug_hook_in(byte) != 0) { /* * The input hook indicates that no further processing * should be done by this handler. */ return; } #endif if (!cmd) { cmd = k_fifo_get(avail_queue, K_NO_WAIT); if (!cmd) { return; } } #ifdef CONFIG_UART_CONSOLE_MCUMGR /* Divert this byte from normal console handling if it is part * of an mcumgr frame. */ if (handle_mcumgr(cmd, byte)) { continue; } #endif /* CONFIG_UART_CONSOLE_MCUMGR */ /* Handle ANSI escape mode */ if (atomic_test_bit(&esc_state, ESC_ANSI)) { handle_ansi(byte, cmd->line); continue; } /* Handle escape mode */ if (atomic_test_and_clear_bit(&esc_state, ESC_ESC)) { if (byte == ANSI_ESC) { atomic_set_bit(&esc_state, ESC_ANSI); atomic_set_bit(&esc_state, ESC_ANSI_FIRST); } continue; } /* Handle special control characters */ if (!isprint(byte)) { switch (byte) { case DEL: if (cur > 0) { del_char(&cmd->line[--cur], end); } break; case ESC: atomic_set_bit(&esc_state, ESC_ESC); break; case '\r': cmd->line[cur + end] = '\0'; uart_poll_out(uart_console_dev, '\r'); uart_poll_out(uart_console_dev, '\n'); cur = 0; end = 0; k_fifo_put(lines_queue, cmd); cmd = NULL; break; case '\t': if (completion_cb && !end) { cur += completion_cb(cmd->line, cur); } break; default: break; } continue; } /* Ignore characters if there's no more buffer space */ if (cur + end < sizeof(cmd->line) - 1) { insert_char(&cmd->line[cur++], byte, end); } } }
int http_client_send_req(struct http_client_ctx *ctx, struct http_client_request *req, http_response_cb_t cb, u8_t *response_buf, size_t response_buf_len, void *user_data, s32_t timeout) { int ret; if (!response_buf || response_buf_len == 0) { return -EINVAL; } ctx->rsp.response_buf = response_buf; ctx->rsp.response_buf_len = response_buf_len; client_reset(ctx); /* HTTPS connection is established in https_handler() */ if (!ctx->is_https) { ret = tcp_connect(ctx); if (ret < 0 && ret != -EALREADY) { NET_DBG("TCP connect error (%d)", ret); return ret; } } if (!req->host) { req->host = ctx->server; } ctx->req.host = req->host; ctx->req.method = req->method; ctx->req.user_data = user_data; ctx->rsp.cb = cb; #if defined(CONFIG_HTTPS) if (ctx->is_https) { struct tx_fifo_block *tx_data; struct k_mem_block block; ret = start_https(ctx); if (ret != 0 && ret != -EALREADY) { NET_ERR("HTTPS init failed (%d)", ret); goto out; } ret = k_mem_pool_alloc(ctx->https.pool, &block, sizeof(struct tx_fifo_block), BUF_ALLOC_TIMEOUT); if (ret < 0) { goto out; } tx_data = block.data; tx_data->req = req; memcpy(&tx_data->block, &block, sizeof(struct k_mem_block)); /* We need to pass the HTTPS request to HTTPS thread because * of the mbedtls API stack size requirements. */ k_fifo_put(&ctx->https.mbedtls.ssl_ctx.tx_fifo, (void *)tx_data); /* Let the https_handler() to start to process the message. * * Note that if the timeout > 0 or is K_FOREVER, then this * yield is not really necessary as the k_sem_take() will * let the https handler thread to run. But if the timeout * is K_NO_WAIT, then we need to let the https handler to * run now. */ k_yield(); } else #endif /* CONFIG_HTTPS */ { print_info(ctx, ctx->req.method); ret = http_request(ctx, req, BUF_ALLOC_TIMEOUT); if (ret < 0) { NET_DBG("Send error (%d)", ret); goto out; } } if (timeout != 0 && k_sem_take(&ctx->req.wait, timeout)) { ret = -ETIMEDOUT; goto out; } if (timeout == 0) { return -EINPROGRESS; } return 0; out: tcp_disconnect(ctx); return ret; }