You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
800 lines
32 KiB
800 lines
32 KiB
\section{Socket calls} |
|
|
|
% Short description/overview of module functions |
|
With the socket calls, the user can open, close, bind, \ldots sockets and do read |
|
or write operations. The provided transport protocols are UDP and TCP. |
|
|
|
\subsection{pico$\_$socket$\_$open} |
|
|
|
\subsubsection*{Description} |
|
This function will be called to open a socket from the application level. The created |
|
socket will be unbound and not connected. |
|
|
|
\subsubsection*{Function prototype} |
|
\begin{verbatim} |
|
struct pico_socket *pico_socket_open(uint16_t net, uint16_t proto, |
|
void (*wakeup)(uint16_t ev, struct pico_socket *s)); |
|
\end{verbatim} |
|
|
|
\subsubsection*{Parameters} |
|
\begin{itemize}[noitemsep] |
|
\item \texttt{net} - Network protocol, \texttt{PICO$\_$PROTO$\_$IPV4} = 0, \texttt{PICO$\_$PROTO$\_$IPV6} = 41 |
|
\item \texttt{proto} - Transport protocol, \texttt{PICO$\_$PROTO$\_$TCP} = 6, \texttt{PICO$\_$PROTO$\_$UDP} = 17 |
|
\item \texttt{wakeup} - Callback function that accepts 2 parameters: |
|
\begin{itemize}[noitemsep] |
|
\item \texttt{ev} - Events that apply to that specific socket, see further |
|
\item \texttt{s} - Pointer to a socket of type struct \texttt{pico$\_$socket} |
|
\end{itemize} |
|
\end{itemize} |
|
|
|
\subsubsection*{Possible events for sockets} |
|
\begin{itemize}[noitemsep] |
|
\item \texttt{PICO$\_$SOCK$\_$EV$\_$RD} - triggered when new data arrives on the socket. A new receive action can be taken by the socket owner because this event indicates there is new data to receive. |
|
\item \texttt{PICO$\_$SOCK$\_$EV$\_$WR} - triggered when ready to write to the socket. Issuing a write/send call will now succeed if the buffer has enough space to allocate new outstanding data. |
|
\item \texttt{PICO$\_$SOCK$\_$EV$\_$CONN} - triggered when connection is established (TCP only). This event is received either after a successful call to \texttt{pico$\_$socket$\_$connect} to indicate that the connection has been established, or on a listening socket, indicating that a call to \texttt{pico$\_$socket$\_$accept} may now be issued in order to accept the incoming connection from a remote host. |
|
\item \texttt{PICO$\_$SOCK$\_$EV$\_$CLOSE} - triggered when a FIN segment is received (TCP only). This event indicates that the other endpont has closed the connection, so the local TCP layer is only allowed to send new data until a local shutdown or close is initiated. PicoTCP is able to keep the connection half-open (only for sending) after the FIN packet has been received, allowing new data to be sent in the TCP CLOSE$\_$WAIT state. |
|
\item \texttt{PICO$\_$SOCK$\_$EV$\_$FIN} - triggered when the socket is closed. No further communication is possible from this point on the socket. |
|
\item \texttt{PICO$\_$SOCK$\_$EV$\_$ERR} - triggered when an error occurs. |
|
\end{itemize} |
|
|
|
\subsubsection*{Return value} |
|
On success, this call returns a pointer to the declared socket (\texttt{struct pico$\_$socket *}). |
|
On error the socket is not created, \texttt{NULL} is returned, and \texttt{pico$\_$err} is set appropriately. |
|
|
|
\subsubsection*{Errors} |
|
\begin{itemize}[noitemsep] |
|
\item \texttt{PICO$\_$ERR$\_$EINVAL} - invalid argument |
|
\item \texttt{PICO$\_$ERR$\_$EPROTONOSUPPORT} - protocol not supported |
|
\item \texttt{PICO$\_$ERR$\_$ENETUNREACH} - network unreachable |
|
\end{itemize} |
|
|
|
\subsubsection*{Example} |
|
\begin{verbatim} |
|
sk_tcp = pico_socket_open(PICO_PROTO_IPV4, PICO_PROTO_TCP, &wakeup); |
|
\end{verbatim} |
|
|
|
|
|
\subsection{pico$\_$socket$\_$read} |
|
|
|
\subsubsection*{Description} |
|
This function will be called to read data from a connected socket. The function checks that the socket is bound and connected before attempting to receive data. |
|
|
|
\subsubsection*{Function prototype} |
|
\begin{verbatim} |
|
int pico_socket_read(struct pico_socket *s, void *buf, int len); |
|
\end{verbatim} |
|
|
|
\subsubsection*{Parameters} |
|
\begin{itemize}[noitemsep] |
|
\item \texttt{s} - Pointer to socket of type \texttt{struct pico$\_$socket} |
|
\item \texttt{buf} - Void pointer to the start of the buffer where the received data will be stored |
|
\item \texttt{len} - Length of the buffer (in bytes), represents the maximum amount of bytes that can be read |
|
\end{itemize} |
|
|
|
\subsubsection*{Return value} |
|
On success, this call returns an integer representing the number of bytes read. |
|
On error, -1 is returned, and \texttt{pico$\_$err} is set appropriately. |
|
|
|
\subsubsection*{Errors} |
|
\begin{itemize}[noitemsep] |
|
\item \texttt{PICO$\_$ERR$\_$EINVAL} - invalid argument |
|
\item \texttt{PICO$\_$ERR$\_$EIO} - input/output error |
|
\item \texttt{PICO$\_$ERR$\_$ESHUTDOWN} - cannot read after transport endpoint shutdown |
|
\end{itemize} |
|
|
|
\subsubsection*{Example} |
|
\begin{verbatim} |
|
bytesRead = pico_socket_read(sk_tcp, buffer, bufferLength); |
|
\end{verbatim} |
|
|
|
|
|
|
|
\subsection{pico$\_$socket$\_$write} |
|
|
|
\subsubsection*{Description} |
|
This function will be called to write the content of a buffer to a socket that has been previously connected. |
|
This function checks that the socket is bound, connected and that it is allowed to send data, i.e. there hasn't been a local shutdown. |
|
This is the preferred function to use when writing data from the application to a connected stream. |
|
|
|
\subsubsection*{Function prototype} |
|
\begin{verbatim} |
|
int pico_socket_write(struct pico_socket *s, void *buf, int len); |
|
\end{verbatim} |
|
|
|
\subsubsection*{Parameters} |
|
\begin{itemize}[noitemsep] |
|
\item \texttt{s} - Pointer to socket of type \texttt{struct pico$\_$socket} |
|
\item \texttt{buf} - Void pointer to the start of a (constant) buffer where the data is stored |
|
\item \texttt{len} - Length of the data buffer \texttt{buf} |
|
\end{itemize} |
|
|
|
\subsubsection*{Return value} |
|
On success, this call returns an integer representing the number of bytes written to the socket. |
|
On error, -1 is returned, and \texttt{pico$\_$err} is set appropriately. |
|
|
|
\subsubsection*{Errors} |
|
\begin{itemize}[noitemsep] |
|
\item \texttt{PICO$\_$ERR$\_$EINVAL} - invalid argument |
|
\item \texttt{PICO$\_$ERR$\_$EIO} - input/output error |
|
\item \texttt{PICO$\_$ERR$\_$ENOTCONN} - the socket is not connected |
|
\item \texttt{PICO$\_$ERR$\_$ESHUTDOWN} - cannot send after transport endpoint shutdown |
|
\item \texttt{PICO$\_$ERR$\_$EADDRNOTAVAIL} - address not available |
|
\item \texttt{PICO$\_$ERR$\_$EHOSTUNREACH} - host is unreachable |
|
\item \texttt{PICO$\_$ERR$\_$ENOMEM} - not enough space |
|
\item \texttt{PICO$\_$ERR$\_$EAGAIN} - resource temporarily unavailable |
|
\end{itemize} |
|
|
|
\subsubsection*{Example} |
|
\begin{verbatim} |
|
bytesWritten = pico_socket_write(sk_tcp, buffer, bufLength); |
|
\end{verbatim} |
|
|
|
|
|
\subsection{pico$\_$socket$\_$sendto} |
|
|
|
\subsubsection*{Description} |
|
This function sends data from the local address to the remote address, without checking |
|
whether the remote endpoint is connected. Specifying the destination is particularly useful while sending single datagrams |
|
to different destinations upon consecutive calls. This is the preferred mechanism to send datagrams to a remote destination |
|
using a UDP socket. |
|
|
|
\subsubsection*{Function prototype} |
|
\begin{verbatim} |
|
int pico_socket_sendto(struct pico_socket *s, const void *buf, int len, |
|
void *dst, uint16_t remote_port); |
|
\end{verbatim} |
|
|
|
\subsubsection*{Parameters} |
|
\begin{itemize}[noitemsep] |
|
\item \texttt{s} - Pointer to socket of type \texttt{struct pico$\_$socket} |
|
\item \texttt{buf} - Void pointer to the start of the buffer |
|
\item \texttt{len} - Length of the buffer \texttt{buf} |
|
\item \texttt{dst} - Pointer to the origin of the IPv4/IPv6 frame header |
|
\item \texttt{remote$\_$port} - Portnumber of the receiving socket |
|
\end{itemize} |
|
|
|
\subsubsection*{Return value} |
|
On success, this call returns an integer representing the number of bytes written to the socket. |
|
On error, -1 is returned, and \texttt{pico$\_$err} is set appropriately. |
|
|
|
\subsubsection*{Errors} |
|
\begin{itemize}[noitemsep] |
|
\item \texttt{PICO$\_$ERR$\_$EADDRNOTAVAIL} - address not available |
|
\item \texttt{PICO$\_$ERR$\_$EINVAL} - invalid argument |
|
\item \texttt{PICO$\_$ERR$\_$EHOSTUNREACH} - host is unreachable |
|
\item \texttt{PICO$\_$ERR$\_$ENOMEM} - not enough space |
|
\item \texttt{PICO$\_$ERR$\_$EAGAIN} - resource temporarily unavailable |
|
\end{itemize} |
|
|
|
\subsubsection*{Example} |
|
\begin{verbatim} |
|
bytesWritten = pico_socket_sendto(sk_tcp, buf, len, &sk_tcp->remote_addr, |
|
sk_tcp->remote_port); |
|
\end{verbatim} |
|
|
|
|
|
\subsection{pico$\_$socket$\_$recvfrom} |
|
|
|
\subsubsection*{Description} |
|
This function is called to receive data from the specified socket. |
|
It is useful when called in the context of a non-connected socket, to receive |
|
the information regarding the origin of the data, namely the origin address and |
|
the remote port number. |
|
|
|
\subsubsection*{Function prototype} |
|
\begin{verbatim} |
|
int pico_socket_recvfrom(struct pico_socket *s, void *buf, int len, |
|
void *orig, uint16_t *remote_port); |
|
\end{verbatim} |
|
|
|
\subsubsection*{Parameters} |
|
\begin{itemize}[noitemsep] |
|
\item \texttt{s} - Pointer to socket of type \texttt{struct pico$\_$socket} |
|
\item \texttt{buf} - Void pointer to the start of the buffer |
|
\item \texttt{len} - Maximum allowed length for the data to be stored in the buffer \texttt{buf} |
|
\item \texttt{orig} - Pointer to the origin of the IPv4/IPv6 frame, (peer IP address), can be NULL |
|
\item \texttt{remote$\_$port} - Pointer to the port number of the sender socket, can be NULL |
|
\end{itemize} |
|
|
|
\subsubsection*{Return value} |
|
On success, this call returns an integer representing the number of bytes read from the socket. On success, if \texttt{orig} |
|
is not NULL, The address of the remote endpoint is stored in the memory area pointed by \texttt{orig}. |
|
In the same way, \texttt{remote$\_$port} will contain the portnumber of the sending socket, unless a NULL is passed |
|
from the caller. |
|
|
|
On error, -1 is returned, and \texttt{pico$\_$err} is set appropriately. |
|
|
|
\subsubsection*{Errors} |
|
\begin{itemize}[noitemsep] |
|
\item \texttt{PICO$\_$ERR$\_$EINVAL} - invalid argument |
|
\item \texttt{PICO$\_$ERR$\_$ESHUTDOWN} - cannot read after transport endpoint shutdown |
|
\item \texttt{PICO$\_$ERR$\_$EADDRNOTAVAIL} - address not available |
|
\end{itemize} |
|
|
|
\subsubsection*{Example} |
|
\begin{verbatim} |
|
bytesRcvd = pico_socket_recvfrom(sk_tcp, buf, bufLen, &peer, &port); |
|
\end{verbatim} |
|
|
|
\subsection{Extended Socket operations} |
|
The interface provided by sendto/recvfrom can be extended to include more information about the network communication. |
|
This is especially useful in UDP communication, and whenever extended information is needed about the single datagram and its encapsulation in the networking layer. |
|
|
|
PicoTCP offers an extra structure that can be used to set and retrieve message information while transmitting and receiving datagrams, respectively. The structure \texttt{pico$\_$msginfo} is defined as follows: |
|
\begin{verbatim} |
|
struct pico_msginfo { |
|
struct pico_device *dev; |
|
uint8_t ttl; |
|
uint8_t tos; |
|
}; |
|
\end{verbatim} |
|
|
|
|
|
|
|
\subsection{pico$\_$socket$\_$sendto$\_$extended} |
|
|
|
\subsubsection*{Description} |
|
This function is an extension of the \texttt{pico$\_$socket$\_$sendto} function described above. It's exactly the same but it adds up an additional argument to set TTL and QOS information on the outgoing packet which contains the datagram. |
|
|
|
The usage of the extended argument makes sense in UDP context only, as the information is set at packet level, and only with UDP there is a 1:1 correspondence between datagrams and IP packets. |
|
|
|
\subsubsection*{Function prototype} |
|
\begin{verbatim} |
|
int pico_socket_sendto_extended(struct pico_socket *s, const void *buf, int len, |
|
void *dst, uint16_t remote_port, struct pico_msginfo *info); |
|
\end{verbatim} |
|
|
|
\subsubsection*{Parameters} |
|
\begin{itemize}[noitemsep] |
|
\item \texttt{s} - Pointer to socket of type \texttt{struct pico$\_$socket} |
|
\item \texttt{buf} - Void pointer to the start of the buffer |
|
\item \texttt{len} - Length of the data that is stored in the buffer (in bytes) |
|
\item \texttt{dst} - IPv4 or IPv6 address of the destination peer where th frame is sent |
|
\item \texttt{remote$\_$port} - Port number of the receiving socket at the remote endpoint |
|
\item \texttt{info} - Extended information about the packet containing this datagram. Only the fields "ttl" and "tos" are taken into consideeration, while "dev" is ignored. |
|
|
|
\end{itemize} |
|
|
|
\subsubsection*{Return value} |
|
On success, this call returns an integer representing the number of bytes written to the socket. |
|
On error, -1 is returned, and \texttt{pico$\_$err} is set appropriately. |
|
|
|
\subsubsection*{Errors} |
|
\begin{itemize}[noitemsep] |
|
\item \texttt{PICO$\_$ERR$\_$EADDRNOTAVAIL} - address not available |
|
\item \texttt{PICO$\_$ERR$\_$EINVAL} - invalid argument |
|
\item \texttt{PICO$\_$ERR$\_$EHOSTUNREACH} - host is unreachable |
|
\item \texttt{PICO$\_$ERR$\_$ENOMEM} - not enough space |
|
\item \texttt{PICO$\_$ERR$\_$EAGAIN} - resource temporarily unavailable |
|
\end{itemize} |
|
|
|
\subsubsection*{Example} |
|
\begin{verbatim} |
|
struct pico_msginfo info = { }; |
|
info.ttl = 5; |
|
bytesWritten = pico_socket_sendto_extended(sk_tcp, buf, len, &sk_tcp->remote_addr, |
|
sk_tcp->remote_port, &info); |
|
\end{verbatim} |
|
|
|
|
|
\subsection{pico$\_$socket$\_$recvfrom$\_$extended} |
|
|
|
\subsubsection*{Description} |
|
This function is an extension to the normal \texttt{pico$\_$socket$\_$recvfrom} function, which allows to retrieve additional information about the networking layer that has been involved in the delivery of the datagram. |
|
|
|
\subsubsection*{Function prototype} |
|
\begin{verbatim} |
|
int pico_socket_recvfrom_extended(struct pico_socket *s, void *buf, int len, |
|
void *orig, uint16_t *remote_port, struct pico_msginfo *info); |
|
\end{verbatim} |
|
|
|
\subsubsection*{Parameters} |
|
\begin{itemize}[noitemsep] |
|
\item \texttt{s} - Pointer to socket of type \texttt{struct pico$\_$socket} |
|
\item \texttt{buf} - Void pointer to the start of the buffer |
|
\item \texttt{len} - Maximum allowed length for the data to be stored in the buffer \texttt{buf} |
|
\item \texttt{orig} - Pointer to the origin of the IPv4/IPv6 frame header, can be NULL |
|
\item \texttt{remote$\_$port} - Pointer to the port number of the sender socket, can be NULL |
|
\item \texttt{info} - Extended information about the incoming packet containing this datagram. The device where the packet was received is pointed by info->dev, the maximum TTL for the packet is stored in info->ttl, and finally the field info->tos keeps track of the flags in IP header's QoS. |
|
\end{itemize} |
|
|
|
\subsubsection*{Return value} |
|
On success, this call returns an integer representing the number of bytes read from the socket. On success, if \texttt{orig} |
|
is not NULL, The address of the remote endpoint is stored in the memory area pointed by \texttt{orig}. |
|
In the same way, \texttt{remote$\_$port} will contain the portnumber of the sending socket, unless a NULL is passed |
|
from the caller. |
|
|
|
On error, -1 is returned, and \texttt{pico$\_$err} is set appropriately. |
|
|
|
\subsubsection*{Errors} |
|
\begin{itemize}[noitemsep] |
|
\item \texttt{PICO$\_$ERR$\_$EINVAL} - invalid argument |
|
\item \texttt{PICO$\_$ERR$\_$ESHUTDOWN} - cannot read after transport endpoint shutdown |
|
\item \texttt{PICO$\_$ERR$\_$EADDRNOTAVAIL} - address not available |
|
\end{itemize} |
|
|
|
\subsubsection*{Example} |
|
\begin{verbatim} |
|
struct pico_msginfo info; |
|
bytesRcvd = pico_socket_recvfrom_extended(sk_tcp, buf, bufLen, &peer, &port, &info); |
|
if (info && info->dev) { |
|
printf("Socket received a datagram via device %s, ttl:%d, tos: %08x\n", |
|
info->dev->name, info->ttl, info->tos); |
|
} |
|
\end{verbatim} |
|
|
|
|
|
\subsection{pico$\_$socket$\_$send} |
|
|
|
\subsubsection*{Description} |
|
This function is called to send data to the specified socket. |
|
It checks if the socket is connected and then calls the |
|
\texttt{pico$\_$socket$\_$sendto} function. |
|
|
|
\subsubsection*{Function prototype} |
|
\begin{verbatim} |
|
int pico_socket_send(struct pico_socket *s, const void *buf, int len); |
|
\end{verbatim} |
|
|
|
|
|
\subsubsection*{Parameters} |
|
\begin{itemize}[noitemsep] |
|
\item \texttt{s} - Pointer to socket of type \texttt{struct pico$\_$socket} |
|
\item \texttt{buf} - Void pointer to the start of the buffer |
|
\item \texttt{len} - Length of the buffer \texttt{buf} |
|
\end{itemize} |
|
|
|
\subsubsection*{Return value} |
|
On success, this call returns an integer representing the number of bytes written to |
|
the socket. On error, -1 is returned, and \texttt{pico$\_$err} is set appropriately. |
|
|
|
\subsubsection*{Errors} |
|
\begin{itemize}[noitemsep] |
|
\item \texttt{PICO$\_$ERR$\_$EINVAL} - invalid argument |
|
\item \texttt{PICO$\_$ERR$\_$ENOTCONN} - the socket is not connected |
|
\item \texttt{PICO$\_$ERR$\_$EADDRNOTAVAIL} - address not available |
|
\item \texttt{PICO$\_$ERR$\_$EHOSTUNREACH} - host is unreachable |
|
\item \texttt{PICO$\_$ERR$\_$ENOMEM} - not enough space |
|
\item \texttt{PICO$\_$ERR$\_$EAGAIN} - resource temporarily unavailable |
|
\end{itemize} |
|
|
|
\subsubsection*{Example} |
|
\begin{verbatim} |
|
bytesRcvd = pico_socket_send(sk_tcp, buf, bufLen); |
|
\end{verbatim} |
|
|
|
|
|
\subsection{pico$\_$socket$\_$recv} |
|
|
|
\subsubsection*{Description} |
|
This function directly calls the \texttt{pico$\_$socket$\_$recvfrom} function. |
|
|
|
\subsubsection*{Function prototype} |
|
\begin{verbatim} |
|
int pico_socket_recv(struct pico_socket *s, void *buf, int len); |
|
\end{verbatim} |
|
|
|
\subsubsection*{Parameters} |
|
\begin{itemize}[noitemsep] |
|
\item \texttt{s} - Pointer to socket of type \texttt{struct pico$\_$socket} |
|
\item \texttt{buf} - Void pointer to the start of the buffer |
|
\item \texttt{len} - Maximum allowed length for the data to be stored in the buffer \texttt{buf} |
|
\end{itemize} |
|
|
|
\subsubsection*{Return value} |
|
On success, this call returns an integer representing the number of bytes read |
|
from the socket. On error, -1 is returned, and \texttt{pico$\_$err} is set appropriately. |
|
|
|
\subsubsection*{Errors} |
|
\begin{itemize}[noitemsep] |
|
\item \texttt{PICO$\_$ERR$\_$EINVAL} - invalid argument |
|
\item \texttt{PICO$\_$ERR$\_$ESHUTDOWN} - cannot read after transport endpoint shutdown |
|
\item \texttt{PICO$\_$ERR$\_$EADDRNOTAVAIL} - address not available |
|
\end{itemize} |
|
|
|
\subsubsection*{Example} |
|
\begin{verbatim} |
|
bytesRcvd = pico_socket_recv(sk_tcp, buf, bufLen); |
|
\end{verbatim} |
|
|
|
|
|
\subsection{pico$\_$socket$\_$bind} |
|
|
|
\subsubsection*{Description} |
|
This function binds a local IP-address and port to the specified socket. |
|
|
|
\subsubsection*{Function prototype} |
|
\begin{verbatim} |
|
int pico_socket_bind(struct pico_socket *s, void *local_addr, uint16_t *port); |
|
\end{verbatim} |
|
|
|
|
|
\subsubsection*{Parameters} |
|
\begin{itemize}[noitemsep] |
|
\item \texttt{s} - Pointer to socket of type \texttt{struct pico$\_$socket} |
|
\item \texttt{local$\_$addr} - Void pointer to the local IP-address |
|
\item \texttt{port} - Local portnumber to bind with the socket |
|
\end{itemize} |
|
|
|
\subsubsection*{Return value} |
|
On success, this call returns 0 after a succesfull bind. |
|
On error, -1 is returned, and \texttt{pico$\_$err} is set appropriately. |
|
|
|
\subsubsection*{Errors} |
|
\begin{itemize}[noitemsep] |
|
\item \texttt{PICO$\_$ERR$\_$EINVAL} - invalid argument |
|
\item \texttt{PICO$\_$ERR$\_$ENOMEM} - not enough space |
|
\item \texttt{PICO$\_$ERR$\_$ENXIO} - no such device or address |
|
\end{itemize} |
|
|
|
\subsubsection*{Example} |
|
\begin{verbatim} |
|
errMsg = pico_socket_bind(sk_tcp, &sockaddr4->addr, &sockaddr4->port); |
|
\end{verbatim} |
|
|
|
\subsection{pico$\_$socket$\_$getname} |
|
|
|
\subsubsection*{Description} |
|
This function returns the local IP-address and port previously bound to the specified socket. |
|
|
|
\subsubsection*{Function prototype} |
|
\begin{verbatim} |
|
int pico_socket_getname(struct pico_socket *s, void *local_addr, uint16_t *port, |
|
uint16_t *proto); |
|
\end{verbatim} |
|
|
|
|
|
\subsubsection*{Parameters} |
|
\begin{itemize}[noitemsep] |
|
\item \texttt{s} - Pointer to socket of type \texttt{struct pico$\_$socket} |
|
\item \texttt{local$\_$addr} - Address (IPv4 or IPv6) previously associated to this socket |
|
\item \texttt{port} - Local portnumber associated to the socket |
|
\item \texttt{proto} - Proto of the address returned in the \texttt{local$\_$addr} field. Can be either \texttt{PICO$\_$PROTO$\_$IPV4} or \texttt{PICO$\_$PROTO$\_$IPV6} |
|
\end{itemize} |
|
|
|
\subsubsection*{Return value} |
|
On success, this call returns 0 and populates the three fields {local$\_$addr} \texttt{port} and \texttt{proto} accordingly. |
|
On error, -1 is returned, and \texttt{pico$\_$err} is set appropriately. |
|
|
|
\subsubsection*{Errors} |
|
\begin{itemize}[noitemsep] |
|
\item \texttt{PICO$\_$ERR$\_$EINVAL} - invalid argument(s) provided |
|
\end{itemize} |
|
|
|
\subsubsection*{Example} |
|
\begin{verbatim} |
|
errMsg = pico_socket_getname(sk_tcp, address, &port, &proto); |
|
if (errMsg == 0) { |
|
if (proto == PICO_PROTO_IPV4) |
|
addr4 = (struct pico_ip4 *)address; |
|
else |
|
addr6 = (struct pico_ip6 *)address; |
|
} |
|
\end{verbatim} |
|
|
|
\subsection{pico$\_$socket$\_$getpeername} |
|
|
|
\subsubsection*{Description} |
|
This function returns the IP-address of the remote peer connected to the specified socket. |
|
|
|
\subsubsection*{Function prototype} |
|
\begin{verbatim} |
|
int pico_socket_getpeername(struct pico_socket *s, void *remote_addr, uint16_t *port, |
|
uint16_t *proto); |
|
\end{verbatim} |
|
|
|
|
|
\subsubsection*{Parameters} |
|
\begin{itemize}[noitemsep] |
|
\item \texttt{s} - Pointer to socket of type \texttt{struct pico$\_$socket} |
|
\item \texttt{remote$\_$addr} - Address (IPv4 or IPv6) associated to the socket remote endpoint |
|
\item \texttt{port} - Local portnumber associated to the socket |
|
\item \texttt{proto} - Proto of the address returned in the \texttt{local$\_$addr} field. Can be either \texttt{PICO$\_$PROTO$\_$IPV4} or \texttt{PICO$\_$PROTO$\_$IPV6} |
|
\end{itemize} |
|
|
|
\subsubsection*{Return value} |
|
On success, this call returns 0 and populates the three fields {local$\_$addr} \texttt{port} and \texttt{proto} accordingly. |
|
On error, -1 is returned, and \texttt{pico$\_$err} is set appropriately. |
|
|
|
\subsubsection*{Errors} |
|
\begin{itemize}[noitemsep] |
|
\item \texttt{PICO$\_$ERR$\_$EINVAL} - invalid argument(s) provided |
|
\item \texttt{PICO$\_$ERR$\_$ENOTCONN} - the socket is not connected to any peer |
|
\end{itemize} |
|
|
|
\subsubsection*{Example} |
|
\begin{verbatim} |
|
errMsg = pico_socket_getpeername(sk_tcp, address, &port, &proto); |
|
if (errMsg == 0) { |
|
if (proto == PICO_PROTO_IPV4) |
|
addr4 = (struct pico_ip4 *)address; |
|
else |
|
addr6 = (struct pico_ip6 *)address; |
|
} |
|
\end{verbatim} |
|
|
|
|
|
\subsection{pico$\_$socket$\_$connect} |
|
|
|
\subsubsection*{Description} |
|
This function connects a local socket to a remote socket of a server that is listening, or permanently associate a remote UDP peer as default receiver for any further outgoing traffic through this socket. |
|
|
|
\subsubsection*{Function prototype} |
|
\begin{verbatim} |
|
int pico_socket_connect(struct pico_socket *s, void *srv_addr, |
|
uint16_t remote_port); |
|
\end{verbatim} |
|
|
|
|
|
\subsubsection*{Parameters} |
|
\begin{itemize}[noitemsep] |
|
\item \texttt{s} - Pointer to socket of type \texttt{struct pico$\_$socket} |
|
\item \texttt{srv$\_$addr} - Void pointer to the remote IP-address to connect to |
|
\item \texttt{remote$\_$port} - Remote port number on which the socket will be connected to |
|
\end{itemize} |
|
|
|
\subsubsection*{Return value} |
|
On success, this call returns 0 after a succesfull connect. |
|
On error, -1 is returned, and \texttt{pico$\_$err} is set appropriately. |
|
|
|
\subsubsection*{Errors} |
|
\begin{itemize}[noitemsep] |
|
\item \texttt{PICO$\_$ERR$\_$EPROTONOSUPPORT} - protocol not supported |
|
\item \texttt{PICO$\_$ERR$\_$EINVAL} - invalid argument |
|
\item \texttt{PICO$\_$ERR$\_$EHOSTUNREACH} - host is unreachable |
|
\end{itemize} |
|
|
|
\subsubsection*{Example} |
|
\begin{verbatim} |
|
errMsg = pico_socket_connect(sk_tcp, &sockaddr4->addr, sockaddr4->port); |
|
\end{verbatim} |
|
|
|
|
|
\subsection{pico$\_$socket$\_$listen} |
|
|
|
\subsubsection*{Description} |
|
A server can use this function when a socket is opened and bound to start listening to it. |
|
|
|
\subsubsection*{Function prototype} |
|
\begin{verbatim} |
|
int pico_socket_listen(struct pico_socket *s, int backlog); |
|
\end{verbatim} |
|
|
|
|
|
\subsubsection*{Parameters} |
|
\begin{itemize}[noitemsep] |
|
\item \texttt{s} - Pointer to socket of type \texttt{struct pico$\_$socket} |
|
\item \texttt{backlog} - Maximum connection requests |
|
\end{itemize} |
|
|
|
\subsubsection*{Return value} |
|
On success, this call returns 0 after a succesfull listen start. |
|
On error, -1 is returned, and \texttt{pico$\_$err} is set appropriately. |
|
|
|
\subsubsection*{Errors} |
|
\begin{itemize}[noitemsep] |
|
\item \texttt{PICO$\_$ERR$\_$EINVAL} - invalid argument |
|
\item \texttt{PICO$\_$ERR$\_$EISCONN} - socket is connected |
|
\end{itemize} |
|
|
|
\subsubsection*{Example} |
|
\begin{verbatim} |
|
errMsg = pico_socket_listen(sk_tcp, 3); |
|
\end{verbatim} |
|
|
|
|
|
\subsection{pico$\_$socket$\_$accept} |
|
|
|
\subsubsection*{Description} |
|
When a server is listening on a socket and the client is trying to connect. |
|
The server on its side will wakeup and acknowledge the connection by calling the this function. |
|
|
|
\subsubsection*{Function prototype} |
|
\begin{verbatim} |
|
struct pico_socket *pico_socket_accept(struct pico_socket *s, void *orig, |
|
uint16_t *local_port); |
|
\end{verbatim} |
|
|
|
\subsubsection*{Parameters} |
|
\begin{itemize}[noitemsep] |
|
\item \texttt{s} - Pointer to socket of type \texttt{struct pico$\_$socket} |
|
\item \texttt{orig} - Pointer to the origin of the IPv4/IPv6 frame header |
|
\item \texttt{local$\_$port} - Portnumber of the local socket (pointer) |
|
\end{itemize} |
|
|
|
\subsubsection*{Return value} |
|
On success, this call returns the pointer to a \texttt{struct pico$\_$socket} that |
|
represents the client thas was just connected. Also \texttt{orig} will contain the requesting |
|
IP-address and \texttt{remote$\_$port} will contain the portnumber of the requesting socket. |
|
On error, \texttt{NULL} is returned, and \texttt{pico$\_$err} is set appropriately. |
|
|
|
\subsubsection*{Errors} |
|
\begin{itemize}[noitemsep] |
|
\item \texttt{PICO$\_$ERR$\_$EINVAL} - invalid argument |
|
\item \texttt{PICO$\_$ERR$\_$EAGAIN} - resource temporarily unavailable |
|
\end{itemize} |
|
|
|
\subsubsection*{Example} |
|
\begin{verbatim} |
|
client = pico_socket_accept(sk_tcp, &peer, &port); |
|
\end{verbatim} |
|
|
|
|
|
\subsection{pico$\_$socket$\_$shutdown} |
|
|
|
\subsubsection*{Description} |
|
Used by the \texttt{pico$\_$socket$\_$close} function to shutdown read and write mode for |
|
the specified socket. With this function one can close a socket for reading |
|
and/or writing. |
|
|
|
\subsubsection*{Function prototype} |
|
\begin{verbatim} |
|
int pico_socket_shutdown(struct pico_socket *s, int mode); |
|
\end{verbatim} |
|
|
|
\subsubsection*{Parameters} |
|
\begin{itemize}[noitemsep] |
|
\item \texttt{s} - Pointer to socket of type \texttt{struct pico$\_$socket} |
|
\item \texttt{mode} - \texttt{PICO$\_$SHUT$\_$RDWR}, \texttt{PICO$\_$SHUT$\_$WR}, \texttt{PICO$\_$SHUT$\_$RD} |
|
\end{itemize} |
|
|
|
\subsubsection*{Return value} |
|
On success, this call returns 0 after a succesfull socket shutdown. |
|
On error, -1 is returned, and \texttt{pico$\_$err} is set appropriately. |
|
|
|
\subsubsection*{Errors} |
|
\begin{itemize}[noitemsep] |
|
\item \texttt{PICO$\_$ERR$\_$EINVAL} - invalid argument |
|
\end{itemize} |
|
|
|
\subsubsection*{Example} |
|
\begin{verbatim} |
|
errMsg = pico_socket_shutdown(s, PICO_SHUT_RDWR); |
|
\end{verbatim} |
|
|
|
|
|
\subsection{pico$\_$socket$\_$close} |
|
|
|
\subsubsection*{Description} |
|
Function used on application level to close a socket. Always closes read and write connection. |
|
|
|
\subsubsection*{Function prototype} |
|
\begin{verbatim} |
|
int pico_socket_close(struct pico_socket *s); |
|
\end{verbatim} |
|
|
|
\subsubsection*{Parameters} |
|
\begin{itemize}[noitemsep] |
|
\item \texttt{s} - Pointer to socket of type \texttt{struct pico$\_$socket} |
|
\end{itemize} |
|
|
|
\subsubsection*{Return value} |
|
On success, this call returns 0 after a succesfull socket shutdown. |
|
On error, -1 is returned, and \texttt{pico$\_$err} is set appropriately. |
|
|
|
\subsubsection*{Errors} |
|
\begin{itemize}[noitemsep] |
|
\item \texttt{PICO$\_$ERR$\_$EINVAL} - invalid argument |
|
\end{itemize} |
|
|
|
\subsubsection*{Example} |
|
\begin{verbatim} |
|
errMsg = pico_socket_close(sk_tcp); |
|
\end{verbatim} |
|
|
|
|
|
|
|
\subsection{pico$\_$socket$\_$setoption} |
|
\label{socket:setoption} |
|
\subsubsection*{Description} |
|
Function used to set socket options. |
|
|
|
\subsubsection*{Function prototype} |
|
\begin{verbatim} |
|
int pico_socket_setoption(struct pico_socket *s, int option, void *value); |
|
\end{verbatim} |
|
|
|
\subsubsection*{Parameters} |
|
\begin{itemize}[noitemsep] |
|
\item \texttt{s} - Pointer to socket of type \texttt{struct pico$\_$socket} |
|
\item \texttt{option} - Option to be set (see further for all options) |
|
\item \texttt{value} - Value of option (void pointer) |
|
\end{itemize} |
|
|
|
\subsubsection*{Available socket options} |
|
\begin{itemize}[noitemsep] |
|
\item \texttt{PICO$\_$TCP$\_$NODELAY} - Disables/enables the Nagle algorithm (TCP Only). |
|
\item \texttt{PICO$\_$SOCKET$\_$OPT$\_$KEEPCNT} - Set number of probes for TCP keepalive |
|
\item \texttt{PICO$\_$SOCKET$\_$OPT$\_$KEEPIDLE} - Set timeout value for TCP keepalive probes (in ms) |
|
\item \texttt{PICO$\_$SOCKET$\_$OPT$\_$KEEPINTVL} - Set interval between TCP keepalive retries in case of no reply (in ms) |
|
\item \texttt{PICO$\_$SOCKET$\_$OPT$\_$LINGER} - Set linger time for TCP TIME$\_$WAIT state (in ms) |
|
\item \texttt{PICO$\_$SOCKET$\_$OPT$\_$RCVBUF} - Set receive buffer size for the socket |
|
\item \texttt{PICO$\_$SOCKET$\_$OPT$\_$RCVBUF} - Set receive buffer size for the socket |
|
\item \texttt{PICO$\_$SOCKET$\_$OPT$\_$RCVBUF} - Set receive buffer size for the socket |
|
\item \texttt{PICO$\_$SOCKET$\_$OPT$\_$SNDBUF} - Set send buffer size for the socket |
|
\item \texttt{PICO$\_$IP$\_$MULTICAST$\_$IF} - (Not supported) Set link multicast datagrams are sent from, default is first added link |
|
\item \texttt{PICO$\_$IP$\_$MULTICAST$\_$TTL} - Set TTL (0-255) of multicast datagrams, default is 1 |
|
\item \texttt{PICO$\_$IP$\_$MULTICAST$\_$LOOP} - Specifies if a copy of an outgoing multicast datagram is looped back as long as it is a member of the multicast group, default is enabled |
|
\item \texttt{PICO$\_$IP$\_$ADD$\_$MEMBERSHIP} - Join the multicast group specified in the \textit{pico\_ip\_mreq} structure passed in the value argument |
|
\item \texttt{PICO$\_$IP$\_$DROP$\_$MEMBERSHIP} - Leave the multicast group specified in the \textit{pico\_ip\_mreq} structure passed in the value argument |
|
\item \texttt{PICO$\_$IP$\_$ADD$\_$SOURCE$\_$MEMBERSHIP} - Join the source-specific multicast group specified in the \textit{pico\_ip\_mreq\_source} structure passed in the value argument |
|
\item \texttt{PICO$\_$IP$\_$DROP$\_$SOURCE$\_$MEMBERSHIP} - Leave the source-specific multicast group specified in the \textit{pico\_ip\_mreq\_source} structure passed in the value argument |
|
\end{itemize} |
|
|
|
\subsubsection*{Return value} |
|
On success, this call returns 0 after a succesfull setting of socket option. |
|
On error, -1 is returned, and \texttt{pico$\_$err} is set appropriately. |
|
|
|
\subsubsection*{Errors} |
|
\begin{itemize}[noitemsep] |
|
\item \texttt{PICO$\_$ERR$\_$EINVAL} - invalid argument |
|
\end{itemize} |
|
|
|
\subsubsection*{Example} |
|
\begin{verbatim} |
|
ret = pico_socket_setoption(sk_tcp, PICO_TCP_NODELAY, NULL); |
|
|
|
uint8_t ttl = 2; |
|
ret = pico_socket_setoption(sk_udp, PICO_IP_MULTICAST_TTL, &ttl); |
|
|
|
uint8_t loop = 0; |
|
ret = pico_socket_setoption(sk_udp, PICO_IP_MULTICAST_LOOP, &loop); |
|
|
|
struct pico_ip4 inaddr_dst, inaddr_link; |
|
struct pico_ip_mreq mreq = {{0},{0}}; |
|
pico_string_to_ipv4("224.7.7.7", &inaddr_dst.addr); |
|
pico_string_to_ipv4("192.168.0.2", &inaddr_link.addr); |
|
mreq.mcast_group_addr = inaddr_dst; |
|
mreq.mcast_link_addr = inaddr_link; |
|
ret = pico_socket_setoption(sk_udp, PICO_IP_ADD_MEMBERSHIP, &mreq); |
|
ret = pico_socket_setoption(sk_udp, PICO_IP_DROP_MEMBERSHIP, &mreq) |
|
\end{verbatim} |
|
|
|
|
|
\subsection{pico$\_$socket$\_$getoption} |
|
|
|
\subsubsection*{Description} |
|
Function used to get socket options. |
|
|
|
\subsubsection*{Function prototype} |
|
\begin{verbatim} |
|
int pico_socket_getoption(struct pico_socket *s, int option, void *value); |
|
\end{verbatim} |
|
|
|
\subsubsection*{Parameters} |
|
\begin{itemize}[noitemsep] |
|
\item \texttt{s} - Pointer to socket of type \texttt{struct pico$\_$socket} |
|
\item \texttt{option} - Option to be set (see further for all options) |
|
\item \texttt{value} - Value of option (void pointer) |
|
\end{itemize} |
|
|
|
\subsubsection*{Available socket options} |
|
\begin{itemize}[noitemsep] |
|
\item \texttt{PICO$\_$TCP$\_$NODELAY} - Nagle algorithm, \texttt{value} casted to \texttt{(int *)} (0 = disabled, 1 = enabled) |
|
\item \texttt{PICO$\_$SOCKET$\_$OPT$\_$RCVBUF} - Read current receive buffer size for the socket |
|
\item \texttt{PICO$\_$SOCKET$\_$OPT$\_$SNDBUF} - Read current receive buffer size for the socket |
|
\item \texttt{PICO$\_$IP$\_$MULTICAST$\_$IF} - (Not supported) Link multicast datagrams are sent from |
|
\item \texttt{PICO$\_$IP$\_$MULTICAST$\_$TTL} - TTL (0-255) of multicast datagrams |
|
\item \texttt{PICO$\_$IP$\_$MULTICAST$\_$LOOP} - Loop back a copy of an outgoing multicast datagram, as long as it is a member of the multicast group, or not. |
|
\end{itemize} |
|
|
|
\subsubsection*{Return value} |
|
On success, this call returns 0 after a succesfull getting of socket option. The value of |
|
the option is written to \texttt{value}. |
|
On error, -1 is returned, and \texttt{pico$\_$err} is set appropriately. |
|
|
|
\subsubsection*{Errors} |
|
\begin{itemize}[noitemsep] |
|
\item \texttt{PICO$\_$ERR$\_$EINVAL} - invalid argument |
|
\end{itemize} |
|
|
|
\subsubsection*{Example} |
|
\begin{verbatim} |
|
ret = pico_socket_getoption(sk_tcp, PICO_TCP_NODELAY, &stat); |
|
|
|
uint8_t ttl = 0; |
|
ret = pico_socket_getoption(sk_udp, PICO_IP_MULTICAST_TTL, &ttl); |
|
|
|
uint8_t loop = 0; |
|
ret = pico_socket_getoption(sk_udp, PICO_IP_MULTICAST_LOOP, &loop); |
|
\end{verbatim}
|
|
|