Re: [RFC] net: New API for applications to send and receive data


Vinicius Costa Gomes
 

Hi Jukka,

Jukka Rissanen <jukka.rissanen(a)linux.intel.com> writes:

Signed-off-by: Jukka Rissanen <jukka.rissanen(a)linux.intel.com>
---
Hi,

current network application APIs in Zephyr are synchronous and a
bit of awkward to use in TCP. Because of these things, I propose
couple of new functions that are asynchronous and easier to use
by the application. These APIs require net_buf fragmentation support
that I sent earlier.
At least from Soletta side, what I feel is lacking from the Zephyr
network stack API-wise is this:

- net_writeto(struct net_context *context, struct net_buf *buf,
struct net_addr *to, uint16_t port)

- net_readfrom(struct net_context *context, struct net_buf *buf,
struct net_addr *from, uint16_t *port);

- net_context_add_addr(struct net_context *context,
struct net_addr *local_addr, uint16_t port);

See what Ivan needed to do here:

https://github.com/solettaproject/soletta/blob/master/src/lib/comms/sol-socket-impl-zephyr.c#L260

Cheers,
Jukka


include/net/net_socket.h | 141 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 141 insertions(+)

diff --git a/include/net/net_socket.h b/include/net/net_socket.h
index 88073b1..2451de3 100644
--- a/include/net/net_socket.h
+++ b/include/net/net_socket.h
@@ -143,6 +143,147 @@ int net_reply(struct net_context *context, struct net_buf *buf);
struct simple_udp_connection *
net_context_get_udp_connection(struct net_context *context);

+/**
+ * @brief Callback that is called when there is something received from
+ * the network.
+ *
+ * @details It is callback responsibility to release the net_buf when the
+ * data is no longer needed. The callback is called in fiber context.
+ *
+ * @param context Network context
+ * @param status 0 if ok, <0 if there is an error
+ * @param iov List of net_buf that contain data
+ * @param user_data User supplied data
+ */
+typedef void (*net_readv_cb_t)(struct net_context *context,
+ int status,
+ struct net_buf *iov,
+ void *user_data);
+
+/**
+ * @brief Register a receiver to get data from network.
+ *
+ * @details Application uses this to get data from network connection.
+ * Caller needs to specify a callback function that is called when data
+ * is received by the socket. When the IP stack has received data, it then
+ * calls user specified callback and it is callback responsibility to
+ * release the net_buf when the data is no longer needed.
+ * This function will return immediately as it only sets a callback to be
+ * called when new data is received. Application can remove the registered
+ * callback by calling the function with same context and setting cb to NULL.
+ *
+ * @param context Network context
+ * @param cb User supplied callback function
+ * @param user_data User supplied data
+ *
+ * @return 0 if cb registration was ok, <0 otherwise
+ */
+int net_readv(struct net_context *context,
+ net_readv_cb_t cb,
+ void *user_data);
+
+/**
+ * @brief Callback that is called when user can send
+ * data to the network.
+ *
+ * @details The first call to this function will set *status to 0 and
+ * bytes_sent to 0. Application can then prepare the data to be sent
+ * in net_buf fragment list. The data to be sent is returned to the
+ * caller of the function. If application does not wish to send anything
+ * it can just return NULL. In this case the caller will deallocate the
+ * iov list. Application should set the *status to <0 to indicate more
+ * detailed reason for the error if NULL is returned.
+ *
+ * For successfully sent UDP data, the IP stack will call this
+ * callback again with status set to 0 and bytes_sent telling how many bytes
+ * were sent. If the UDP data was not sent for some reason, then *status
+ * will have value < 0 and bytes_sent is set to 0.
+ *
+ * For TCP, the callback is called when the network connection has been
+ * established. In this case the *status is 0 and bytes_sent is 0.
+ * If there is a connection timeout, the status code will be -ETIMEDOUT
+ * and bytes_sent is set to 0. Other error codes are also possible in
+ * which case the *status < 0 and bytes_sent will tell how many bytes were
+ * successfully sent. If the *status is set to 0 then bytes_sent will tell
+ * how many bytes were sent to the peer.
+ *
+ * The iov fragment list does not contain data that has been successfully
+ * sent. Also the iov->frags->data of the first data fragment will point to
+ * first byte that has not yet been sent. If all the data was sent
+ * successfully, then the first item of iov list will have its frags pointer
+ * set to NULL. Application can send more data if it wishes by returning
+ * a new list of data fragments.
+ *
+ * The callback is called in fiber context.
+ *
+ * @param context Network context
+ * @param status 0 if ok, <0 if there is an error in stack side
+ * Application can return error code if needed via this pointer.
+ * @param bytes_sent How many bytes were sent.
+ * @param iov List of net_buf that contain data. If this is NULL, then
+ * allocate the buf and fill it with data. If non-NULL, then the protocol
+ * headers are already there and you can append the data.
+ * @param user_data User supplied data
+ *
+ * @return A valid net_buf that needs to be sent,
+ * NULL if user is not able to send anything.
+ */
+typedef struct net_buf *(*net_writev_cb_t)(struct net_context *context,
+ int *status,
+ int bytes_sent,
+ struct net_buf *iov,
+ void *user_data);
+
+/**
+ * @brief Send data to network.
+ *
+ * @details Application uses this to send data to a network connection.
+ * Caller needs to specify a callback function that is called when data
+ * is ready to be sent. The function will return immediately, the timeout
+ * is only used when calling the user callback. For UDP, the timeout is
+ * ignored. For TCP the callback is called after the TCP connection is
+ * established and user is able to send data, or if there is an error
+ * creating a connection or if the connection timeouts.
+ *
+ * @param context Network context
+ * @param timeout How long to wait until user can send data. This is only
+ * used in TCP.
+ * @param cb User supplied callback function
+ * @param user_data User supplied data
+ *
+ * @return 0 if cb registration was ok, <0 otherwise
+ */
+int net_writev(struct net_context *context,
+ int32_t timeout,
+ net_writev_cb_t cb,
+ void *user_data);
+
+/**
+ * @brief Reply data to sender.
+ *
+ * @details This is a helper that will help user to reply data to the
+ * sender. Application can use this function to reply data it received
+ * via net_readv().
+ *
+ * @param context Network context
+ * @param timeout How long to wait until user can send data. This is only
+ * used in TCP.
+ * @param iov Data to be sent
+ * @param cb User supplied callback function
+ * @param user_data User supplied data
+ *
+ * @return 0 if cb registration was ok, <0 otherwise
+ */
+int net_replyv(struct net_context *context,
+ int32_t timeout,
+ struct net_buf *iov,
+ net_writev_cb_t cb,
+ void *user_data);
+
#ifdef __cplusplus
}
#endif
--
2.5.5

Cheers,
--
Vinicius

Join devel@lists.zephyrproject.org to automatically receive all group messages.