struct net_buf *bt_buf_get_acl(int32_t timeout) { struct net_buf *buf; buf = net_buf_alloc(&hci_rx_pool, timeout); if (buf) { bt_buf_set_type(buf, BT_BUF_ACL_IN); } return buf; }
static void test_get_single_buffer(void) { struct net_buf *buf; buf = net_buf_alloc(&bufs_pool, K_NO_WAIT); zassert_equal(buf->ref, 1, "Invalid refcount"); zassert_equal(buf->len, 0, "Invalid length"); zassert_equal(buf->flags, 0, "Invalid flags"); zassert_equal_ptr(buf->frags, NULL, "Frags not NULL"); }
struct net_buf *bt_buf_get_evt(uint8_t opcode, int timeout) { struct net_buf *buf; buf = net_buf_alloc(&hci_rx_pool, timeout); if (buf) { bt_buf_set_type(buf, BT_BUF_EVT); } return buf; }
static int send_response(struct zoap_packet *request, u8_t response_code) { struct net_pkt *pkt; struct net_buf *frag; struct zoap_packet response; u8_t code, type; u16_t id; int r; code = zoap_header_get_code(request); type = zoap_header_get_type(request); id = zoap_header_get_id(request); printk("*******\n"); printk("type: %u code %u id %u\n", type, code, id); printk("*******\n"); pkt = net_pkt_get_reserve(&zoap_pkt_slab, 0, K_NO_WAIT); if (!pkt) { return -ENOMEM; } frag = net_buf_alloc(&zoap_data_pool, K_NO_WAIT); if (!frag) { return -ENOMEM; } net_pkt_frag_add(pkt, frag); r = zoap_packet_init(&response, pkt); if (r < 0) { return -EINVAL; } zoap_header_set_version(&response, 1); zoap_header_set_type(&response, ZOAP_TYPE_ACK); zoap_header_set_code(&response, response_code); zoap_header_set_id(&response, id); do { r = mbedtls_ssl_write(curr_ctx, frag->data, frag->len); } while (r == MBEDTLS_ERR_SSL_WANT_READ || r == MBEDTLS_ERR_SSL_WANT_WRITE); if (r >= 0) { r = 0; } net_pkt_unref(pkt); return r; }
error_t net_buf_alloc_with_size(net_buf_t** res, size_t size) { error_t error; net_buf_t* nb; *res = NULL; error = net_buf_alloc(&nb); if (error_is_failure(error)) return error; nb->buf = mm_alloc(size); if (nb->buf == NULL) { net_buf_free(nb); return ERROR_NO_MEMORY; } nb->size = size; *res = nb; return ERROR_SUCCESS; }
struct net_buf *bt_buf_get_rx(int timeout) { return net_buf_alloc(&hci_rx_pool, timeout); }
inline static void handle_rx_interrupt(addr_t regs, ushort_t status) { /* todos . disable rx interrupts while processing the packet */ uint_t header; size_t rx_size; off_t rx_off; size_t pkt_size; ushort_t* capr; ushort_t* cbr; volatile uchar_t* cr; net_buf_t* nb; net_buf_t* pos; net_dev_t* net_dev; rtl8139_dev_t* rtk_dev; net_dev = g_device; rtk_dev = (rtl8139_dev_t*)net_dev->priv; /* get registers */ capr = (ushort_t*)(regs + RTL8139_REG_CAPR); cbr = (ushort_t*)(regs + RTL8139_REG_CBR); cr = (uchar_t*)(regs + RTL8139_REG_CR); /* not empty */ while (!(*cr & 1)) { /* current packet in ring */ rx_off = (*capr + RTL8139_CAPR_OFF) % RTL8139_RXBUF_LEN; header = *(uint_t*)(rtk_dev->rx_buf + rx_off); /* size include the status ushort_t, little endian */ rx_size = header >> 16; if (rx_size == 0xfff0) BUG(); /* current paket size */ pkt_size = rx_size - ETH_CRC_LEN; /* skip header */ rx_off += RTL8139_HEADER_LEN; /* create netbuf */ if (error_is_success(net_buf_alloc(&nb))) { net_buf_append(nb, rtk_dev->rx_buf + rx_off, pkt_size); /* link the netbuf */ nb->next = rtk_dev->nb_head; rtk_dev->nb_head = nb; } /* update capr */ rx_off = (rx_off + pkt_size + RTL8139_HEADER_LEN + 3) & ~3; if (rx_off >= RTL8139_RXBUF_LEN) rx_off = rx_off % RTL8139_RXBUF_LEN; *capr = rx_off - RTL8139_CAPR_OFF; } /* tell network interface something is available */ nb = rtk_dev->nb_head; while (nb != NULL) { pos = nb; nb = nb->next; if (net_dev->net_if != NULL) net_if_rx(net_dev->net_if, pos); else net_buf_free(pos); } rtk_dev->nb_head = NULL; }
static void bt_uart_isr(struct device *unused) { static int remaining; u8_t byte; int ret; static u8_t hdr[4]; ARG_UNUSED(unused); while (uart_irq_update(h5_dev) && uart_irq_is_pending(h5_dev)) { if (!uart_irq_rx_ready(h5_dev)) { if (uart_irq_tx_ready(h5_dev)) { BT_DBG("transmit ready"); } else { BT_DBG("spurious interrupt"); } /* Only the UART RX path is interrupt-enabled */ break; } ret = uart_fifo_read(h5_dev, &byte, sizeof(byte)); if (!ret) { continue; } switch (h5.rx_state) { case START: if (byte == SLIP_DELIMITER) { h5.rx_state = HEADER; remaining = sizeof(hdr); } break; case HEADER: /* In a case we confuse ending slip delimeter * with starting one. */ if (byte == SLIP_DELIMITER) { remaining = sizeof(hdr); continue; } if (h5_unslip_byte(&byte) < 0) { h5_reset_rx(); continue; } memcpy(&hdr[sizeof(hdr) - remaining], &byte, 1); remaining--; if (remaining) { break; } remaining = H5_HDR_LEN(hdr); switch (H5_HDR_PKT_TYPE(hdr)) { case HCI_EVENT_PKT: /* The buffer is allocated only once we know * the exact event type. */ h5.rx_state = PAYLOAD; break; case HCI_ACLDATA_PKT: h5.rx_buf = bt_buf_get_rx(BT_BUF_ACL_IN, K_NO_WAIT); if (!h5.rx_buf) { BT_WARN("No available data buffers"); h5_reset_rx(); continue; } h5.rx_state = PAYLOAD; break; case HCI_3WIRE_LINK_PKT: case HCI_3WIRE_ACK_PKT: h5.rx_buf = net_buf_alloc(&h5_pool, K_NO_WAIT); if (!h5.rx_buf) { BT_WARN("No available signal buffers"); h5_reset_rx(); continue; } h5.rx_state = PAYLOAD; break; default: BT_ERR("Wrong packet type %u", H5_HDR_PKT_TYPE(hdr)); h5.rx_state = END; break; } break; case PAYLOAD: if (h5_unslip_byte(&byte) < 0) { h5_reset_rx(); continue; } /* Allocate HCI event buffer now that we know the * exact event type. */ if (!h5.rx_buf) { h5.rx_buf = get_evt_buf(byte); if (!h5.rx_buf) { BT_WARN("No available event buffers"); h5_reset_rx(); continue; } } net_buf_add_mem(h5.rx_buf, &byte, sizeof(byte)); remaining--; if (!remaining) { h5.rx_state = END; } break; case END: if (byte != SLIP_DELIMITER) { BT_ERR("Missing ending SLIP_DELIMITER"); h5_reset_rx(); break; } BT_DBG("Received full packet: type %u", H5_HDR_PKT_TYPE(hdr)); /* Check when full packet is received, it can be done * when parsing packet header but we need to receive * full packet anyway to clear UART. */ if (H5_HDR_RELIABLE(hdr) && H5_HDR_SEQ(hdr) != h5.tx_ack) { BT_ERR("Seq expected %u got %u. Drop packet", h5.tx_ack, H5_HDR_SEQ(hdr)); h5_reset_rx(); break; } h5_process_complete_packet(hdr); h5.rx_state = START; break; } } }
void http_rx_tx(struct net_context *net_ctx, struct net_pkt *rx, int status, void *user_data) { struct http_server_ctx *http_ctx = NULL; struct net_buf *data = NULL; u16_t rcv_len; u16_t offset; int parsed_len; int rc; if (status) { printf("[%s:%d] Status code: %d, <%s>\n", __func__, __LINE__, status, RC_STR(status)); goto lb_exit; } if (!user_data) { printf("[%s:%d] User data is null\n", __func__, __LINE__); goto lb_exit; } http_ctx = (struct http_server_ctx *)user_data; if (http_ctx->net_ctx != net_ctx) { printf("[%s:%d] Wrong network context received\n", __func__, __LINE__); goto lb_exit; } if (!rx) { printf("[%s:%d] Connection closed by peer\n", __func__, __LINE__); goto lb_exit; } rcv_len = net_pkt_appdatalen(rx); if (rcv_len == 0) { /* don't print info about zero-length app data buffers */ goto lb_exit; } data = net_buf_alloc(&http_msg_pool, APP_SLEEP_MSECS); if (data == NULL) { printf("[%s:%d] Data buffer alloc error\n", __func__, __LINE__); goto lb_exit; } offset = net_pkt_get_len(rx) - rcv_len; rc = net_frag_linear_copy(data, rx->frags, offset, rcv_len); if (rc != 0) { printf("[%s:%d] Linear copy error\n", __func__, __LINE__); goto lb_exit; } data->data[min(data->size - 1, rcv_len)] = 0; parser_init(http_ctx); parsed_len = parser_parse_request(http_ctx, data); if (parsed_len <= 0) { printf("[%s:%d] Received: %u bytes, only parsed: %d bytes\n", __func__, __LINE__, rcv_len, parsed_len); } if (http_ctx->parser.http_errno != HPE_OK) { http_response_400(http_ctx, NULL); } else { http_tx(http_ctx); } lb_exit: net_pkt_frag_unref(data); net_pkt_unref(rx); http_ctx_release(http_ctx); }
void dtls_server(void) { int len, ret = 0; struct udp_context ctx; struct dtls_timing_context timer; struct zoap_packet zpkt; struct net_pkt *pkt; struct net_buf *frag; mbedtls_ssl_cookie_ctx cookie_ctx; mbedtls_entropy_context entropy; mbedtls_ctr_drbg_context ctr_drbg; mbedtls_ssl_context ssl; mbedtls_ssl_config conf; mbedtls_ctr_drbg_init(&ctr_drbg); mbedtls_platform_set_printf(printk); #if defined(MBEDTLS_DEBUG_C) mbedtls_debug_set_threshold(DEBUG_THRESHOLD); #endif /* * Initialize and setup */ mbedtls_ssl_init(&ssl); mbedtls_ssl_config_init(&conf); mbedtls_entropy_init(&entropy); mbedtls_entropy_add_source(&entropy, entropy_source, NULL, MBEDTLS_ENTROPY_MAX_GATHER, MBEDTLS_ENTROPY_SOURCE_STRONG); ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, (const unsigned char *)pers, strlen(pers)); if (ret != 0) { mbedtls_printf(" failed!\n" " mbedtls_ctr_drbg_seed returned -0x%x\n", -ret); goto exit; } ret = mbedtls_ssl_config_defaults(&conf, MBEDTLS_SSL_IS_SERVER, MBEDTLS_SSL_TRANSPORT_DATAGRAM, MBEDTLS_SSL_PRESET_DEFAULT); if (ret != 0) { mbedtls_printf(" failed!\n" " mbedtls_ssl_config_defaults returned -0x%x\n", -ret); goto exit; } /* Modify this to change the default timeouts for the DTLS handshake */ /* mbedtls_ssl_conf_handshake_timeout( &conf, min, max ); */ mbedtls_ssl_conf_rng(&conf, mbedtls_ctr_drbg_random, &ctr_drbg); mbedtls_ssl_conf_dbg(&conf, my_debug, NULL); #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) mbedtls_memory_buffer_alloc_init(heap, sizeof(heap)); #endif ret = mbedtls_ssl_cookie_setup(&cookie_ctx, mbedtls_ctr_drbg_random, &ctr_drbg); if (ret != 0) { mbedtls_printf(" failed!\n" " mbedtls_ssl_cookie_setup returned -0x%x\n", -ret); goto exit; } mbedtls_ssl_conf_dtls_cookies(&conf, mbedtls_ssl_cookie_write, mbedtls_ssl_cookie_check, &cookie_ctx); ret = mbedtls_ssl_setup(&ssl, &conf); if (ret != 0) { mbedtls_printf(" failed!\n" " mbedtls_ssl_setup returned -0x%x\n", -ret); goto exit; } ret = udp_init(&ctx); if (ret != 0) { mbedtls_printf(" failed!\n udp_init returned 0x%x\n", ret); goto exit; } reset: mbedtls_ssl_session_reset(&ssl); #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) ret = mbedtls_ssl_conf_psk(&conf, psk, strlen(psk), psk_id, strlen(psk_id)); if (ret != 0) { mbedtls_printf(" failed!\n mbedtls_ssl_conf_psk" " returned -0x%04X\n", -ret); goto exit; } #endif mbedtls_ssl_set_timer_cb(&ssl, &timer, dtls_timing_set_delay, dtls_timing_get_delay); mbedtls_ssl_set_bio(&ssl, &ctx, udp_tx, udp_rx, NULL); /* For HelloVerifyRequest cookies */ ctx.client_id = (char)ctx.remaining; ret = mbedtls_ssl_set_client_transport_id(&ssl, &ctx.client_id, sizeof(char)); if (ret != 0) { mbedtls_printf(" failed!\n" " mbedtls_ssl_set_client_transport_id()" " returned -0x%x\n", -ret); goto exit; } curr_ctx = &ssl; do { ret = mbedtls_ssl_handshake(&ssl); } while (ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE); if (ret == MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED) { ret = 0; goto reset; } if (ret != 0) { mbedtls_printf(" failed!\n" " mbedtls_ssl_handshake returned -0x%x\n", -ret); goto reset; } do { /* Read the request */ pkt = net_pkt_get_reserve(&zoap_pkt_slab, 0, K_NO_WAIT); if (!pkt) { mbedtls_printf("Could not get packet from slab\n"); goto exit; } frag = net_buf_alloc(&zoap_data_pool, K_NO_WAIT); if (!frag) { mbedtls_printf("Could not get frag from pool\n"); goto exit; } net_pkt_frag_add(pkt, frag); len = ZOAP_BUF_SIZE - 1; memset(frag->data, 0, ZOAP_BUF_SIZE); ret = mbedtls_ssl_read(&ssl, frag->data, len); if (ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE) { continue; } if (ret <= 0) { net_pkt_unref(pkt); switch (ret) { case MBEDTLS_ERR_SSL_TIMEOUT: mbedtls_printf(" timeout\n"); goto reset; case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY: mbedtls_printf(" connection was closed" " gracefully\n"); goto close_notify; default: mbedtls_printf(" mbedtls_ssl_read" " returned -0x%x\n", -ret); goto reset; } } len = ret; frag->len = len; ret = zoap_packet_parse(&zpkt, pkt); if (ret) { mbedtls_printf("Could not parse packet\n"); goto exit; } ret = zoap_handle_request(&zpkt, resources, (const struct sockaddr *)&ssl); if (ret < 0) { mbedtls_printf("No handler for such request (%d)\n", ret); } net_pkt_unref(pkt); } while (1); close_notify: /* No error checking, the connection might be closed already */ do { ret = mbedtls_ssl_close_notify(&ssl); } while (ret == MBEDTLS_ERR_SSL_WANT_WRITE); ret = 0; mbedtls_printf(" done\n"); goto reset; exit: mbedtls_ssl_free(&ssl); mbedtls_ssl_config_free(&conf); mbedtls_ctr_drbg_free(&ctr_drbg); mbedtls_entropy_free(&entropy); }
static int query_get(struct zoap_resource *resource, struct zoap_packet *request, const struct sockaddr *from) { struct zoap_option options[4]; struct net_pkt *pkt; struct net_buf *frag; struct zoap_packet response; u8_t *payload, code, type; u16_t len, id; int i, r; code = zoap_header_get_code(request); type = zoap_header_get_type(request); id = zoap_header_get_id(request); r = zoap_find_options(request, ZOAP_OPTION_URI_QUERY, options, 4); if (r <= 0) { return -EINVAL; } printk("*******\n"); printk("type: %u code %u id %u\n", type, code, id); printk("num queries: %d\n", r); for (i = 0; i < r; i++) { char str[16]; if (options[i].len + 1 > sizeof(str)) { printk("Unexpected length of query: " "%d (expected %zu)\n", options[i].len, sizeof(str)); break; } memcpy(str, options[i].value, options[i].len); str[options[i].len] = '\0'; printk("query[%d]: %s\n", i + 1, str); } printk("*******\n"); pkt = net_pkt_get_reserve(&zoap_pkt_slab, 0, K_NO_WAIT); if (!pkt) { return -ENOMEM; } frag = net_buf_alloc(&zoap_data_pool, K_NO_WAIT); if (!frag) { return -ENOMEM; } net_pkt_frag_add(pkt, frag); r = zoap_packet_init(&response, pkt); if (r < 0) { return -EINVAL; } /* FIXME: Could be that zoap_packet_init() sets some defaults */ zoap_header_set_version(&response, 1); zoap_header_set_type(&response, ZOAP_TYPE_ACK); zoap_header_set_code(&response, ZOAP_RESPONSE_CODE_CONTENT); zoap_header_set_id(&response, id); payload = zoap_packet_get_payload(&response, &len); if (!payload) { return -EINVAL; } /* The response that coap-client expects */ r = snprintk((char *)payload, len, "Type: %u\nCode: %u\nMID: %u\n", type, code, id); if (r < 0 || r > len) { return -EINVAL; } r = zoap_packet_set_used(&response, r); if (r) { return -EINVAL; } do { r = mbedtls_ssl_write(curr_ctx, frag->data, frag->len); } while (r == MBEDTLS_ERR_SSL_WANT_READ || r == MBEDTLS_ERR_SSL_WANT_WRITE); if (r >= 0) { r = 0; } net_pkt_unref(pkt); return r; }
static int piggyback_get(struct zoap_resource *resource, struct zoap_packet *request, const struct sockaddr *from) { struct net_pkt *pkt; struct net_buf *frag; struct zoap_packet response; u8_t *payload, code, type; u16_t len, id; int r; code = zoap_header_get_code(request); type = zoap_header_get_type(request); id = zoap_header_get_id(request); printk("*******\n"); printk("type: %u code %u id %u\n", type, code, id); printk("*******\n"); pkt = net_pkt_get_reserve(&zoap_pkt_slab, 0, K_NO_WAIT); if (!pkt) { return -ENOMEM; } frag = net_buf_alloc(&zoap_data_pool, K_NO_WAIT); if (!frag) { return -ENOMEM; } net_pkt_frag_add(pkt, frag); r = zoap_packet_init(&response, pkt); if (r < 0) { return -EINVAL; } zoap_header_set_version(&response, 1); zoap_header_set_type(&response, ZOAP_TYPE_ACK); zoap_header_set_code(&response, ZOAP_RESPONSE_CODE_CONTENT); zoap_header_set_id(&response, id); payload = zoap_packet_get_payload(&response, &len); if (!payload) { return -EINVAL; } /* The response that coap-client expects */ r = snprintk((char *)payload, len, "Type: %u\nCode: %u\nMID: %u\n", type, code, id); if (r < 0 || r > len) { return -EINVAL; } r = zoap_packet_set_used(&response, r); if (r) { return -EINVAL; } do { r = mbedtls_ssl_write(curr_ctx, frag->data, frag->len); } while (r == MBEDTLS_ERR_SSL_WANT_READ || r == MBEDTLS_ERR_SSL_WANT_WRITE); if (r >= 0) { r = 0; } net_pkt_unref(pkt); return r; }