int udp_tx(void *context, const unsigned char *buf, size_t size) { struct udp_context *ctx = context; struct net_context *net_ctx; struct net_pkt *send_pkt; int rc, len; net_ctx = ctx->net_ctx; send_pkt = net_pkt_get_tx(net_ctx, K_FOREVER); if (!send_pkt) { printk("cannot create pkt\n"); return -EIO; } rc = net_pkt_append_all(send_pkt, size, (u8_t *) buf, K_FOREVER); if (!rc) { printk("cannot write buf\n"); return -EIO; } len = net_pkt_get_len(send_pkt); rc = net_context_sendto(send_pkt, &net_ctx->remote, addrlen, NULL, K_FOREVER, NULL, NULL); if (rc < 0) { printk("Cannot send data to peer (%d)\n", rc); net_pkt_unref(send_pkt); return -EIO; } else { return len; } }
/* Send encrypted data */ static int ssl_tx(void *context, const unsigned char *buf, size_t size) { struct http_client_ctx *ctx = context; struct net_pkt *send_pkt; int ret, len; send_pkt = net_pkt_get_tx(ctx->tcp.ctx, BUF_ALLOC_TIMEOUT); if (!send_pkt) { return MBEDTLS_ERR_SSL_ALLOC_FAILED; } ret = net_pkt_append_all(send_pkt, size, (u8_t *)buf, BUF_ALLOC_TIMEOUT); if (!ret) { /* Cannot append data */ net_pkt_unref(send_pkt); return MBEDTLS_ERR_SSL_ALLOC_FAILED; } len = size; ret = net_context_send(send_pkt, ssl_sent, K_NO_WAIT, NULL, ctx); if (ret < 0) { net_pkt_unref(send_pkt); return ret; } k_sem_take(&ctx->https.mbedtls.ssl_ctx.tx_sem, K_FOREVER); return len; }
static int telnet_setup_out_pkt(struct net_context *client) { out_pkt = net_pkt_get_tx(client, K_FOREVER); if (!out_pkt) { /* Cannot happen atm, net_pkt waits indefinitely */ return -ENOBUFS; } return 0; }
static int transmitv(struct net_context *conn, int iovcnt, struct io_vec *iov) { struct net_pkt *pkt; int i; pkt = net_pkt_get_tx(conn, K_FOREVER); if (!pkt) { return -ENOMEM; } for (i = 0; i < iovcnt; i++) { if (!net_pkt_append_all(pkt, iov[i].len, iov[i].base, K_FOREVER)) { net_pkt_unref(pkt); return -ENOMEM; } } return net_context_send(pkt, NULL, K_NO_WAIT, NULL, NULL); }
static struct net_pkt *build_reply_pkt(const char *name, struct net_context *context, struct net_pkt *pkt) { struct net_pkt *reply_pkt; struct net_buf *tmp; int header_len, recv_len, reply_len; printk("%s received %d bytes", name, net_pkt_appdatalen(pkt)); reply_pkt = net_pkt_get_tx(context, K_FOREVER); recv_len = net_pkt_get_len(pkt); tmp = pkt->frags; /* Remove frag link so original pkt can be unrefed */ pkt->frags = NULL; /* First fragment will contain IP header so move the data * down in order to get rid of it. */ header_len = net_pkt_appdata(pkt) - tmp->data; /* After this pull, the tmp->data points directly to application * data. */ net_buf_pull(tmp, header_len); /* Add the entire chain into reply */ net_pkt_frag_add(reply_pkt, tmp); reply_len = net_pkt_get_len(reply_pkt); printk("Received %d bytes, sending %d bytes", recv_len - header_len, reply_len); return reply_pkt; }
int http_request(struct http_client_ctx *ctx, struct http_client_request *req, s32_t timeout) { const char *method = http_method_str(req->method); struct net_pkt *pkt; int ret = -ENOMEM; pkt = net_pkt_get_tx(ctx->tcp.ctx, timeout); if (!pkt) { return -ENOMEM; } if (!net_pkt_append_all(pkt, strlen(method), (u8_t *)method, timeout)) { goto out; } /* Space after method string. */ if (!net_pkt_append_all(pkt, 1, (u8_t *)" ", timeout)) { goto out; } if (!net_pkt_append_all(pkt, strlen(req->url), (u8_t *)req->url, timeout)) { goto out; } if (!net_pkt_append_all(pkt, strlen(req->protocol), (u8_t *)req->protocol, timeout)) { goto out; } if (req->host) { if (!net_pkt_append_all(pkt, strlen(HTTP_HOST), (u8_t *)HTTP_HOST, timeout)) { goto out; } if (!net_pkt_append_all(pkt, strlen(req->host), (u8_t *)req->host, timeout)) { goto out; } if (!net_pkt_append_all(pkt, strlen(HTTP_CRLF), (u8_t *)HTTP_CRLF, timeout)) { goto out; } } if (req->header_fields) { if (!net_pkt_append_all(pkt, strlen(req->header_fields), (u8_t *)req->header_fields, timeout)) { goto out; } } if (req->content_type_value) { if (!net_pkt_append_all(pkt, strlen(HTTP_CONTENT_TYPE), (u8_t *)HTTP_CONTENT_TYPE, timeout)) { goto out; } if (!net_pkt_append_all(pkt, strlen(req->content_type_value), (u8_t *)req->content_type_value, timeout)) { goto out; } } if (req->payload && req->payload_size) { char content_len_str[HTTP_CONT_LEN_SIZE]; ret = snprintk(content_len_str, HTTP_CONT_LEN_SIZE, HTTP_CRLF "Content-Length: %u" HTTP_CRLF HTTP_CRLF, req->payload_size); if (ret <= 0 || ret >= HTTP_CONT_LEN_SIZE) { ret = -ENOMEM; goto out; } if (!net_pkt_append_all(pkt, ret, (u8_t *)content_len_str, timeout)) { ret = -ENOMEM; goto out; } if (!net_pkt_append_all(pkt, req->payload_size, (u8_t *)req->payload, timeout)) { ret = -ENOMEM; goto out; } } else { if (!net_pkt_append_all(pkt, strlen(HTTP_EOF), (u8_t *)HTTP_EOF, timeout)) { goto out; } } #if defined(CONFIG_NET_IPV6) if (net_pkt_family(pkt) == AF_INET6) { net_pkt_set_appdatalen(pkt, net_pkt_get_len(pkt) - net_pkt_ip_hdr_len(pkt) - net_pkt_ipv6_ext_opt_len(pkt)); } else #endif { net_pkt_set_appdatalen(pkt, net_pkt_get_len(pkt) - net_pkt_ip_hdr_len(pkt)); } ret = ctx->tcp.send_data(pkt, NULL, timeout, NULL, ctx); if (ret == 0) { return 0; } out: net_pkt_unref(pkt); return ret; }
static struct net_pkt *build_reply_pkt(const char *name, struct net_context *context, struct net_pkt *pkt) { struct net_pkt *reply_pkt; struct net_buf *frag, *tmp; int header_len, recv_len, reply_len; NET_INFO("%s received %d bytes", name, net_pkt_appdatalen(pkt)); if (net_pkt_appdatalen(pkt) == 0) { return NULL; } reply_pkt = net_pkt_get_tx(context, K_FOREVER); NET_ASSERT(reply_pkt); recv_len = net_pkt_get_len(pkt); tmp = pkt->frags; /* First fragment will contain IP header so move the data * down in order to get rid of it. */ header_len = net_pkt_appdata(pkt) - tmp->data; NET_ASSERT(header_len < CONFIG_NET_BUF_DATA_SIZE); /* After this pull, the tmp->data points directly to application * data. */ net_buf_pull(tmp, header_len); while (tmp) { frag = net_pkt_get_data(context, K_FOREVER); if (!net_buf_headroom(tmp)) { /* If there is no link layer headers in the * received fragment, then get rid of that also * in the sending fragment. We end up here * if MTU is larger than fragment size, this * is typical for ethernet. */ net_buf_push(frag, net_buf_headroom(frag)); frag->len = 0; /* to make fragment empty */ /* Make sure to set the reserve so that * in sending side we add the link layer * header if needed. */ net_pkt_set_ll_reserve(reply_pkt, 0); } NET_ASSERT(net_buf_tailroom(frag) >= tmp->len); memcpy(net_buf_add(frag, tmp->len), tmp->data, tmp->len); net_pkt_frag_add(reply_pkt, frag); tmp = net_pkt_frag_del(pkt, NULL, tmp); } reply_len = net_pkt_get_len(reply_pkt); NET_ASSERT_INFO((recv_len - header_len) == reply_len, "Received %d bytes, sending %d bytes", recv_len - header_len, reply_len); return reply_pkt; }