Porting PicoTCP WIP

This commit is contained in:
2025-10-29 14:29:06 +01:00
parent 6722f42e68
commit 815c2239fe
464 changed files with 235009 additions and 24 deletions

View File

@ -0,0 +1,20 @@
Downloading the manual
----------------------
With every git commit, we rebuild the documentation and make the [user_doc.pdf](http://162.13.84.104/user_doc.pdf) file (click to download) publicly available.
If for some reason, you're looking for an older version of the documentation, please check out the wanted commit in git, and compile the manual as described below.
Compiling the manual
--------------------
The picoTCP user manual is written in LaTeX, which needs to be compiled to get a readable version.
First and foremost you need the compiler and some packages:
* sudo apt-get install texlive
* sudo apt-get install texlive-latex-extra
Now, cd into docs/user_manual and do
* ./build.sh
A user_doc.pdf should be generated in the current directory

View File

@ -0,0 +1,3 @@
#!/bin/bash
pdflatex user_doc.tex && pdflatex user_doc.tex && pdflatex user_doc.tex

View File

@ -0,0 +1,42 @@
\section{Ad-hoc On-Demand Distance Vector Routing (AODV)}
AODV is a reactive routing protocol for mobile ad-hoc networks
(MANETs). Its best fit are especially ultra-low power radio networks,
or those RF topologies where sporadic traffic between a small specific set
of nodes is foreseen.
In order to create a route, one node must explicitly start the communication
towards a remote node, and the route is created ad-hoc upon the demand
for a specific network path.
AODV guarantees that the traffic generated by each node in order to create
and maintain routes is kept as low as possible.
\subsection{pico\_aodv\_add}
\subsubsection*{Description}
This function will add the target device to the AODV mechanism on the machine,
meaning that it will be possible to advertise and collect routing information
using Ad-hoc On-Demand Distance Vector Routing, as described in RFC3561, through the
target device.
In order to use multiple devices in the AODV system, this function needs to be called
multiple times, once per device.
\subsubsection*{Function prototype}
\texttt{pico\_aodv\_add(struct pico\_device *dev);}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{dev} - a pointer to a struct \texttt{pico\_device} specifying the target interface.
\end{itemize}
\subsubsection*{Return value}
0 returned if the device is successfully added.
\subsubsection*{Example}
\begin{verbatim}
ret = pico_aodv_add(dev);
\end{verbatim}

View File

@ -0,0 +1,170 @@
\section{DHCP client}
% Short description/overview of module functions
A DHCP client for obtaining a dynamic IP address. DHCP is supported on multiple interfaces.
\subsection{pico\_dhcp\_initiate\_negotiation}
\subsubsection*{Description}
Initiate a DHCP negotiation. The user passes a callback-function, which will be executed on DHCP success or failure.
\subsubsection*{Function prototype}
\begin{verbatim}
int pico_dhcp_initiate_negotiation(struct pico_device *device,
void (*callback)(void *cli, int code), uint32_t *xid);
\end{verbatim}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{device} - the device on which a negotiation should be started.
\item \texttt{callback} - the function which is executed on success or failure. This function can be called multiple times. F.e.: initially DHCP succeeded, then the DHCP server is removed long enough from the network for the lease to expire, later the server is added again to the network. The callback is called 3 times: first with code \texttt{PICO\_DHCP\_SUCCESS}, then with \texttt{PICO\_DHCP\_RESET} and finally with \texttt{PICO\_DHCP\_SUCCESS}. The callback may be called before \texttt{pico\_dhcp\_initiate\_negotiation} has returned, f.e. in case of failure to open a socket. The callback has two parameters:
\begin{itemize}[noitemsep]
\item \texttt{cli} - the identifier of the negotiation
\item \texttt{code} - the id indicating success or failure, see further
\end{itemize}
\item \texttt{xid} - transaction id of the negotiation. Is set on \texttt{PICO\_DHCP\_SUCCESS}, 0 otherwise.
\end{itemize}
\subsubsection*{Possible DHCP codes}
\begin{itemize}[noitemsep]
\item \texttt{PICO\_DHCP\_SUCCESS} - DHCP succeeded, the user can start using the assigned address, which can be obtained by calling \texttt{pico\_dhcp\_get\_address}.
\item \texttt{PICO\_DHCP\_ERROR} - an error occurred. DHCP is unable to recover from this error. \texttt{pico$\_$err} is set appropriately.
\item \texttt{PICO\_DHCP\_RESET} - DHCP was unable to renew its lease, and the lease expired. The user must immediately stop using the previously assigned IP, and wait for DHCP to obtain a new lease. DHCP will automatically start negotiations again.
\end{itemize}
\subsubsection*{Return value}
Returns 0 on success, -1 otherwise.
\subsubsection*{Errors} % ORGANIZE
All errors are reported through the callback-function described above.
\begin{itemize}[noitemsep]
\item \texttt{PICO$\_$ERR$\_$EADDRNOTAVAIL} - address not available % pico_socket_sendto
\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
\item \texttt{PICO$\_$ERR$\_$EPROTONOSUPPORT} - protocol not supported % pico_socket_open
\item \texttt{PICO$\_$ERR$\_$ENETUNREACH} - network unreachable
\item \texttt{PICO$\_$ERR$\_$EINVAL} - invalid argument % pico_socket_bind
\item \texttt{PICO$\_$ERR$\_$ENXIO} - no such device or address
\item \texttt{PICO$\_$ERR$\_$EOPNOTSUPP} - operation not supported on socket
\end{itemize}
\subsubsection*{Example}
\begin{verbatim}
pico_dhcp_initiate_negotiation(dev, &callback_dhcpclient, &xid);
\end{verbatim}
\subsection{pico\_dhcp\_client\_abort}
\subsubsection*{Description}
Cancel the ongoing negotiation. To be used if the operation of obtaining an IP address from a remote DHCP server needs to be aborted, before the callback has been triggered.
\subsubsection*{Function prototype}
\texttt{struct pico\_ip4 pico\_dhcp\_client\_abort(uint32\_t xid);}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{xid} - the transaction id returned from the call \texttt{pico\_dhcp\_initiate\_negotiation}.
\end{itemize}
\subsubsection*{Return value}
Returns 0 on success, -1 otherwise (i.e. the XID could not be found in the list of ongoing transactions).
\subsection{pico\_dhcp\_get\_identifier}
\subsubsection*{Description}
Get the identifier needed to pass to all other \texttt{pico\_dhcp} functions. This function should only be called after a callback occurred with code \texttt{PICO\_DHCP\_SUCCESS}.
\subsubsection*{Function prototype}
\texttt{void *pico\_dhcp\_get\_identifier(uint32\_t xid);}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{xid} - transaction id of the negotiation.
\end{itemize}
\subsubsection*{Return value}
\texttt{void *} - pointer to the identifier.
%\subsubsection*{Errors}
\subsubsection*{Example}
\begin{verbatim}
void *cli = pico_dhcp_get_identifier(xid);
\end{verbatim}
\subsection{pico\_dhcp\_get\_address}
\subsubsection*{Description}
Get the address that was assigned through DHCP. This function should only be called after a callback occurred with code \texttt{PICO\_DHCP\_SUCCESS}.
\subsubsection*{Function prototype}
\texttt{struct pico\_ip4 pico\_dhcp\_get\_address(void *cli);}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{cli} - the identifier that was provided by the callback on \texttt{PICO\_DHCP\_SUCCESS}.
\end{itemize}
\subsubsection*{Return value}
\texttt{struct pico\_ip4} - the address that was assigned.
%\subsubsection*{Errors}
\subsubsection*{Example}
\begin{verbatim}
struct pico_ip4 address = pico_dhcp_get_address(cli);
\end{verbatim}
\subsection{pico\_dhcp\_get\_gateway}
\subsubsection*{Description}
Get the address of the gateway that was assigned through DHCP. This function should
only be called after a callback occurred with code \texttt{PICO\_DHCP\_SUCCESS}.
\subsubsection*{Function prototype}
\texttt{struct pico\_ip4 pico\_dhcp\_get\_gateway(void *cli);}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{cli} - the identifier that was provided by the callback on \texttt{PICO\_DHCP\_SUCCESS}.
\end{itemize}
\subsubsection*{Return value}
\begin{itemize}[noitemsep]
\item \texttt{struct pico\_ip4} - the address of the gateway that should be used.
\end{itemize}
\subsection{pico\_dhcp\_get\_nameserver}
\subsubsection*{Description}
Get the address of the first or the second nameserver that was assigned through DHCP.
This function should only be called after a callback occurred with code \texttt{PICO\_DHCP\_SUCCESS}.
\subsubsection*{Function prototype}
\texttt{struct pico\_ip4 pico\_dhcp\_get\_nameserver(void *cli, int index);}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{cli} - the identifier that was provided by the callback on \texttt{PICO\_DHCP\_SUCCESS}.
\item \texttt{index} - the indes of the domain name server received. Can be either "0" or "1".
\end{itemize}
\subsubsection*{Return value}
\begin{itemize}[noitemsep]
\item \texttt{struct pico\_ip4} - the address of the nameserver that should be used. On failure, e.g. an invalid index was passed, it returns "255.255.255.255". If the IP address of the DNS has not been set, it may return INADDR\_ANY.
\end{itemize}
%\subsubsection*{Errors}
\subsubsection*{Example}
\begin{verbatim}
struct pico_ip4 gateway = pico_dhcp_get_gateway(cli);
\end{verbatim}

View File

@ -0,0 +1,71 @@
\section{DHCP server}
% Short description/overview of module functions
\subsection{pico\_dhcp\_server\_initiate}
\subsubsection*{Description}
This function starts a simple DHCP server.
\subsubsection*{Function prototype}
\texttt{int pico\_dhcp\_server\_initiate(struct pico\_dhcpd\_settings *settings);}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{settings} - a pointer to a struct \texttt{pico\_dhcpd\_settings}, in which the following members matter to the user :
\begin{itemize}[noitemsep]
\item \texttt{struct pico\_ip4 my\_ip} - the IP address of the device performing DHCP. Only IPs of this network will be served.
\item \texttt{uint32\_t pool\_start} - the lowest host number that may be assigned, defaults to 100 if not provided.
\item \texttt{uint32\_t pool\_end} - the highest host number that may be assigned, defaults to 254 if not provided.
\item \texttt{uint32\_t lease\_time} - the advertised lease time in seconds, defaults to 120 if not provided.
\end{itemize}
\end{itemize}
\subsubsection*{Return value}
On successful startup of the dhcp server, 0 is returned.
On error, -1 is returned, and \texttt{pico$\_$err} is set appropriately.
\subsubsection*{Errors}
\begin{itemize}[noitemsep]
%everything from :
%pico_socket_open
\item PICO$\_$ERR$\_$EPROTONOSUPPORT - protocol not supported
\item PICO$\_$ERR$\_$ENETUNREACH - network unreachable
%pico_socket_bind
\item PICO$\_$ERR$\_$EINVAL - invalid argument
\item PICO$\_$ERR$\_$ENXIO - no such device or address
\end{itemize}
\subsection{pico\_dhcp\_server\_destroy}
\subsubsection*{Description}
This function stops a previously started DHCP server on the given device.
\subsubsection*{Function prototype}
\texttt{int pico\_dhcp\_server\_destroy(struct pico\_device *dev);}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{dev} - a pointer to a struct \texttt{pico\_device}, to identify a previously started DHCP server that must be terminated.
\end{itemize}
\subsubsection*{Return value}
On success, 0 is returned.
On error, -1 is returned, and \texttt{pico$\_$err} is set appropriately.
\subsubsection*{Errors}
\begin{itemize}[noitemsep]
\item PICO$\_$ERR$\_$ENOENT - there was no DHCP server running on the given device.
\end{itemize}
\subsubsection*{Example}
\begin{verbatim}
struct pico_dhcpd_settings s = { };
s.my_ip.addr = long_be(0x0a280001); /* 10.40.0.1 */
pico_dhcp_server_initiate(&s);
\end{verbatim}

View File

@ -0,0 +1,115 @@
\section{DNS client}
% Short description/overview of module functions
\subsection{pico$\_$dns$\_$client$\_$nameserver}
\subsubsection*{Description}
Function to add or remove nameservers.
\subsubsection*{Function prototype}
\begin{verbatim}
int pico_dns_client_nameserver(struct pico_ip4 *ns, uint8_t flag);
\end{verbatim}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{ns} - Pointer to the address of the name server.
\item \texttt{flag} - Flag to indicate addition or removal (see further).
\end{itemize}
\subsubsection*{Flags}
\begin{itemize}[noitemsep]
\item \texttt{PICO$\_$DNS$\_$NS$\_$ADD} - to add a nameserver
\item \texttt{PICO$\_$DNS$\_$NS$\_$DEL} - to remove a nameserver
\end{itemize}
\subsubsection*{Return value}
On success, this call returns 0 if the nameserver operation has succeeded.
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$\_$EAGAIN} - resource temporarily unavailable
\end{itemize}
\subsubsection*{Example}
\begin{verbatim}
ret = pico_dns_client_nameserver(&addr_ns, PICO_DNS_NS_ADD);
ret = pico_dns_client_nameserver(&addr_ns, PICO_DNS_NS_DEL);
\end{verbatim}
\subsection{pico$\_$dns$\_$client$\_$getaddr}
\subsubsection*{Description}
Function to translate an url text string to an internet host address IP.
\subsubsection*{Function prototype}
\begin{verbatim}
int pico_dns_client_getaddr(const char *url, void (*callback)(char *ip, void *arg),
void *arg);
\end{verbatim}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{url} - Pointer to text string containing url text string (e.g. www.google.com).
\item \texttt{callback} - Callback function, returning the internet host address IP and the provided argument. The returned string has to be freed by the user.
\item \texttt{arg} - Pointer to an identifier for the request. The pointer is returned in the callback.
\end{itemize}
\subsubsection*{Return value}
On success, this call returns 0 if the request is sent.
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$\_$EAGAIN} - resource temporarily unavailable
\end{itemize}
\subsubsection*{Example}
\begin{verbatim}
int ret = pico_dns_client_getaddr("www.google.com", cb_getaddr, &identifier);
\end{verbatim}
\subsection{pico$\_$dns$\_$client$\_$getname}
\subsubsection*{Description}
Function to translate an internet host address IP to an url text string.
\subsubsection*{Function prototype}
\begin{verbatim}
int pico_dns_client_getname(const char *ip, void (*callback)(char *url, void *arg),
void *arg);
\end{verbatim}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{ip} - Pointer to text string containing an internet host address IP (e.g. 8.8.4.4)
\item \texttt{callback} - Callback function, receiving the url text string. Note: the returned string has to be freed by the user.
\item \texttt{arg} - Pointer to an identifier for the request. The pointer is returned in the callback.
\end{itemize}
\subsubsection*{Return value}
On success, this call returns 0 if the request is sent.
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$\_$EAGAIN} - resource temporarily unavailable
\end{itemize}
\subsubsection*{Example}
\begin{verbatim}
int ret = pico_dns_client_getname("8.8.4.4", cb_getname, &identifier);
\end{verbatim}

View File

@ -0,0 +1,85 @@
\section{DNS SD client}
% Short description/overview of module functions
With this module DNS-SD services can be registered on the network to allow Zero Configuration Networking on the device. This is merely a small layer on top of Multicast DNS.
\subsection{pico$\_$dns$\_$sd$\_$init}
\subsubsection*{Description}
Just calls pico$\_$mdns$\_$init in its turn to initialise the mDNS-module. See 'pico$\_$mdns$\_$init' for more information.
\subsection{pico$\_$dns$\_$sd$\_$register$\_$service}
\subsubsection*{Description}
Registers the service with a certain name and type on the network via Multicast DNS.
\subsubsection*{Function prototype}
\begin{verbatim}
int pico_dns_sd_register_service( const char *name,
const char *type,
uint16_t port,
kv_vector *txt_data,
uint16_t ttl,
void (*callback)(pico_mdns_rtree *,char *,void *),
void *arg);
\end{verbatim}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{name} - Instance-name of the service. Use a descriptive name for it but not longer than 63 characters.
\item \texttt{type} - The type of the service. For all the possible service types see: \url{http://www.dns-sd.org/servicetypes.html}
\item \texttt{port} - The portnumber on which the service runs.
\item \texttt{txt$\_$data} - Pointer to vector with key-value pairs to insert into the TXT record to give additional information about the service. Use the 'PICO$\_$DNS$\_$SD$\_$KV$\_$VECTOR$\_$DECLARE'-macro to declare a vector for key-value-pairs. This vector will be destroyed when the function returns since there's no need in keeping the contents.
\item \texttt{ttl} - TTL of the service on the network before it needs to be reconfirmed. In seconds.
\item \texttt{callback} - Callback function that gets called when the service is successfully registered on the network.
\item \texttt{arg} - Argument for callback supplied by user. This can be used if you want to pass some variable into your callback function.
\end{itemize}
\subsubsection*{Return value}
Returns 0 when the module successfully started registering the service, something else on failure. \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
\end{itemize}
\subsubsection*{Example}
\begin{verbatim}
PICO_DNS_SD_KV_VECTOR_DECLARE(dictionary);
pico_dns_sd_register_service("Printer 2nd Floor", "_printer._sub._http._tcp", 80, \\
&dictionary, 240, &reg_cb, NULL);
\end{verbatim}
\subsection{pico$\_$dns$\_$sd$\_$kv$\_$vector$\_$add}
\subsubsection*{Description}
Add a key-value pair the a key-value pair vector.
\subsubsection*{Function prototype}
\begin{verbatim}
int pico_dns_sd_kv_vector_add( kv_vector *vector, char *key, char *value );
\end{verbatim}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{vector} - Pointer to vector to add the pair to. Declare a key-value vector with the 'PICO$\_$DNS$\_$SD$\_$KV$\_$VECTOR$\_$DECLARE'-macro.
\item \texttt{key} - Key of the pair. Cannot be NULL.
\item \texttt{value} - Value of the pair. can be NULL, empty ("") or filled ("value").
\end{itemize}
\subsubsection*{Return value}
Returns 0 when the pair is added successfully, something else on failure. \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
\end{itemize}
\subsubsection*{Example}
\begin{verbatim}
PICO_DNS_SD_KV_VECTOR_DECLARE(dictionary);
pico_dns_sd_kv_vector_add(&dictionary, "pass", "1234");
pico_dns_sd_kv_vector_add(&dictionary, "color", NULL);
\end{verbatim}

View File

@ -0,0 +1,42 @@
\section{IGMP}
% Short description/overview of module functions
This module allows the user to join and leave ipv4 multicast groups. The module is based on the IGMP version 3 protocol and it's backwards compatible with version 2. Version 1 is not supported.
The IGMP module is completly driven from socket calls (\ref{socket:setoption}) and non of the IGMP application interface functions should be called by the user. If however, by any reason, it's necessary for the user to do this, the following function call is provided:
\subsection{pico\_igmp\_state\_change}
\subsubsection*{Description}
Change the state of the host to Non-member, Idle member or Delaying member.
\subsubsection*{Function prototype}
\begin{verbatim}
int pico_igmp_state_change(struct pico_ip4 *mcast_link, struct pico_ip4 *mcast_group,
uint8_t filter_mode, struct pico_tree *_MCASTFilter, uint8_t state)
\end{verbatim}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{mcast\_link} - the link on which that multicast group should be joined.
\item \texttt{mcast\_group} - the address of the multicast group you want to join.
\item \texttt{filter\_mode} - the kind of source filtering, if applied.
\item \texttt{\_MCASTFilter} - list of multicast sources on which source filtering might be applied.
\item \texttt{state} - the prefered new state.
\end{itemize}
\subsubsection*{Errors}
In case of failure, -1 is returned, and the value of pico$\_$err
is set as follows:
\begin{itemize}[noitemsep]
\item \texttt{PICO$\_$ERR$\_$EINVAL} - Invalid argument provided
\item \texttt{PICO$\_$ERR$\_$ENOMEM} - Not enough space
\item \texttt{PICO$\_$ERR$\_$EPROTONOSUPPORT} - Invalid protocol (or protocol version) found on the link
\item \texttt{PICO$\_$ERR$\_$EFAULT} - Internal error
\end{itemize}
%\subsubsection*{Example}
%\subsubsection*{Errors}
%\subsubsection*{Example}

View File

@ -0,0 +1,89 @@
\section{IP Filter}
% Short description/overview of module functions
This module allows the user to add and remove filters. The user can filter packets based on interface, protocol, outgoing address, outgoing netmask, incomming address, incomming netmask, outgoing port, incomming port, priority and type of service. There are four types of filters: ACCEPT, PRIORITY, REJECT, DROP. When creating a PRIORITY filter, it is necessary to give a priority value in a range between '-10' and '10', '0' as default priority.
\subsection{pico$\_$ipv4$\_$filter$\_$add}
\subsubsection*{Description}
Function to add a filter.
\subsubsection*{Function prototype}
\begin{verbatim}
int pico_ipv4_filter_add(struct pico_device *dev, uint8_t proto,
struct pico_ip4 out_addr, struct pico_ip4 out_addr_netmask,
struct pico_ip4 in_addr, struct pico_ip4 in_addr_netmask, uint16_t out_port,
uint16_t in_port, int8_t priority, uint8_t tos, enum filter_action action);
\end{verbatim}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{dev} - interface to be filtered
\item \texttt{proto} - protocol to be filtered
\item \texttt{out$\_$addr} - outgoing address to be filtered
\item \texttt{out$\_$addr$\_$netmask} - outgoing address-netmask to be filtered
\item \texttt{in$\_$addr} - incomming address to be filtered
\item \texttt{in$\_$addr$\_$netmask} - incomming address-netmask to be filtered
\item \texttt{out$\_$port} - outgoing port to be filtered
\item \texttt{in$\_$port} - incomming port to be filtered
\item \texttt{priority} - priority to assign on the marked packet
\item \texttt{tos} - type of service to be filtered
\item \texttt{action} - type of action for the filter: ACCEPT, PRIORITY, REJECT and DROP. ACCEPT, filters all packets selected by the filter. PRIORITY is not yet implemented. REJECT drops all packets and send an ICMP message 'Packet Filtered' (Communication Administratively Prohibited). DROP will discard the packet silently.
\end{itemize}
\subsubsection*{Return value}
On success, this call returns the filter$\_$id from the generated filter. This id must be used when deleting the filter.
On error, -1 is returned and \texttt{pico$\_$err} is set appropriately.
\subsubsection*{Example}
\begin{verbatim}
/* block all incoming traffic on port 5555 */
filter_id = pico_ipv4_filter_add(NULL, 6, NULL, NULL, NULL, NULL, 0, 5555,
0, 0, FILTER_REJECT);
\end{verbatim}
\subsubsection*{Errors}
\begin{itemize}[noitemsep]
\item \texttt{PICO$\_$ERR$\_$EINVAL} - invalid argument
\end{itemize}
\subsection{pico$\_$ipv4$\_$filter$\_$del}
\subsubsection*{Description}
Function to delete a filter.
\subsubsection*{Function prototype}
\begin{verbatim}
int pico_ipv4_filter_del(int filter_id)
\end{verbatim}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{filter$\_$id} - the id of the filter you want to delete.
\end{itemize}
\subsubsection*{Return value}
On success, this call returns 0.
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$\_$EPERM} - operation not permitted
\end{itemize}
\subsubsection*{Example}
\begin{verbatim}
ret = pico_ipv4_filter_del(filter_id);
\end{verbatim}
%\subsubsection*{Parameters}
%\subsubsection*{Return value}
%\subsubsection*{Errors}
%\subsubsection*{Example}

View File

@ -0,0 +1,561 @@
\section{IPv4 functions}
% Short description/overview of module functions
\subsection{pico$\_$ipv4$\_$to$\_$string}
\subsubsection*{Description}
Convert the internet host address IP to a string in IPv4 dotted-decimal notation.
The result is stored in the char array that ipbuf points to. The given IP address argument must be in network order (i.e. 0xC0A80101 becomes 192.168.1.1).
\subsubsection*{Function prototype}
\begin{verbatim}
int pico_ipv4_to_string(char *ipbuf, const uint32_t ip);
\end{verbatim}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{ipbuf} - Char array to store the result in.
\item \texttt{ip} - Internet host address in integer notation.
\end{itemize}
\subsubsection*{Return value}
On success, this call returns 0 if the conversion was successful.
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_ipv4_to_string(buf, ip);
\end{verbatim}
\subsection{pico$\_$string$\_$to$\_$ipv4}
\subsubsection*{Description}
Convert the IPv4 dotted-decimal notation into binary form. The result is stored in the
\texttt{int} that IP points to. Little endian or big endian is not taken into account.
The address supplied in \texttt{ipstr} can have one of the following
forms: a.b.c.d, a.b.c or a.b.
\subsubsection*{Function prototype}
\begin{verbatim}
int pico_string_to_ipv4(const char *ipstr, uint32_t *ip);
\end{verbatim}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{ipstr} - Pointer to the IP string.
\item \texttt{ip} - Int pointer to store the result in.
\end{itemize}
\subsubsection*{Return value}
On success, this call returns 0 if the conversion was successful.
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_string_to_ipv4(buf, *ip);
\end{verbatim}
\subsection{pico$\_$ipv4$\_$valid$\_$netmask}
\subsubsection*{Description}
Check if the provided mask if valid.
\subsubsection*{Function prototype}
\begin{verbatim}
int pico_ipv4_valid_netmask(uint32_t mask);
\end{verbatim}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{mask} - The netmask in integer notation.
\end{itemize}
\subsubsection*{Return value}
On success, this call returns the netmask in CIDR notation is returned if the netmask is valid.
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_ipv4_valid_netmask(netmask);
\end{verbatim}
\subsection{pico$\_$ipv4$\_$is$\_$unicast}
\subsubsection*{Description}
Check if the provided address is unicast or multicast.
\subsubsection*{Function prototype}
\begin{verbatim}
int pico_ipv4_is_unicast(uint32_t address);
\end{verbatim}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{address} - Internet host address in integer notation.
\end{itemize}
\subsubsection*{Return value}
Returns 1 if unicast, 0 if multicast.
%\subsubsection*{Errors}
\subsubsection*{Example}
\begin{verbatim}
ret = pico_ipv4_is_unicast(address);
\end{verbatim}
\subsection{pico$\_$ipv4$\_$source$\_$find}
\subsubsection*{Description}
Find the source IP for the link associated to the specified destination.
This function will use the currently configured routing table to identify the link that would be used to transmit any traffic directed to the given IP address.
\subsubsection*{Function prototype}
\begin{verbatim}
struct pico_ip4 *pico_ipv4_source_find(struct pico_ip4 *dst);
\end{verbatim}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{address} - Pointer to the destination internet host address as \texttt{struct pico$\_$ip4}.
\end{itemize}
\subsubsection*{Return value}
On success, this call returns the source IP as \texttt{struct pico$\_$ip4}.
If the source can not be found, \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$\_$EHOSTUNREACH} - host is unreachable
\end{itemize}
\subsubsection*{Example}
\begin{verbatim}
src = pico_ipv4_source_find(dst);
\end{verbatim}
\subsection{pico$\_$ipv4$\_$link$\_$add }
\subsubsection*{Description}
Add a new local device dev inteface, f.e. eth0, with IP address 'address' and netmask 'netmask'. A device may have more than one link configured, i.e. to access multiple networks on the same link.
\subsubsection*{Function prototype}
\begin{verbatim}
int pico_ipv4_link_add(struct pico_device *dev, struct pico_ip4 address,
struct pico_ip4 netmask);
\end{verbatim}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{dev} - Local device.
\item \texttt{address} - Pointer to the internet host address as \texttt{struct pico$\_$ip4}.
\item \texttt{netmask} - Netmask of the address.
\end{itemize}
\subsubsection*{Return value}
On success, this call returns 0.
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$\_$ENETUNREACH} - network unreachable
\item \texttt{PICO$\_$ERR$\_$EHOSTUNREACH} - host is unreachable
\end{itemize}
\subsubsection*{Example}
\begin{verbatim}
ret = pico_ipv4_link_add(dev, address, netmask);
\end{verbatim}
\subsection{pico$\_$ipv4$\_$link$\_$del}
\subsubsection*{Description}
Remove the link associated to the local device that was previously configured, corresponding to the IP address 'address'.
\subsubsection*{Function prototype}
\begin{verbatim}
int pico_ipv4_link_del(struct pico_device *dev, struct pico_ip4 address);
\end{verbatim}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{dev} - Local device.
\item \texttt{address} - Pointer to the internet host address as \texttt{struct pico$\_$ip4}.
\end{itemize}
\subsubsection*{Return value}
On success, this call returns 0.
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_ipv4_link_del(dev, address);
\end{verbatim}
\subsection{pico$\_$ipv4$\_$link$\_$find}
\subsubsection*{Description}
Find the local device associated to the local IP address 'address'.
\subsubsection*{Function prototype}
\begin{verbatim}
struct pico_device *pico_ipv4_link_find(struct pico_ip4 *address);
\end{verbatim}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{address} - Pointer to the internet host address as \texttt{struct pico$\_$ip4}.
\end{itemize}
\subsubsection*{Return value}
On success, this call returns the local device.
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$\_$ENXIO} - no such device or address
\end{itemize}
\subsubsection*{Example}
\begin{verbatim}
dev = pico_ipv4_link_find(address);
\end{verbatim}
\subsection{pico$\_$ipv4$\_$nat$\_$enable}
\subsubsection*{Description}
This function enables NAT functionality on the passed IPv4 link.
Forwarded packets from an internal network will have the public IP address from the passed link
and a translated port number for transmission on the external network.
Usual operation requires at least one additional link for the internal network,
which is used as a gateway for the internal hosts.
\subsubsection*{Function prototype}
\begin{verbatim}
int pico_ipv4_nat_enable(struct pico_ipv4_link *link)
\end{verbatim}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{link} - Pointer to a link \texttt{pico$\_$ipv4$\_$link}.
\end{itemize}
\subsubsection*{Return value}
On success, this call returns 0.
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_ipv4_nat_enable(&external_link);
\end{verbatim}
\subsection{pico$\_$ipv4$\_$nat$\_$disable}
\subsubsection*{Description}
Disables the NAT functionality.
\subsubsection*{Function prototype}
\begin{verbatim}
int pico_ipv4_nat_disable(void);
\end{verbatim}
%\subsubsection*{Parameters}
\subsubsection*{Return value}
Always returns 0.
%\subsubsection*{Errors}
%\subsubsection*{Example}
\subsection{pico$\_$ipv4$\_$port$\_$forward}
\subsubsection*{Description}
This function adds or deletes a rule in the IP forwarding table. Internally in the stack,
a one-direction NAT entry will be made.
\subsubsection*{Function prototype}
\begin{verbatim}
int pico_ipv4_port_forward(struct pico_ip4 pub_addr, uint16_t pub_port,
struct pico_ip4 priv_addr, uint16_t priv_port, uint8_t proto,
uint8_t persistant)
\end{verbatim}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{pub$\_$addr} - Public IP address, must be identical to the address of the external link.
\item \texttt{pub$\_$port} - Public port to be translated.
\item \texttt{priv$\_$addr} - Private IP address of the host on the internal network.
\item \texttt{priv$\_$port} - Private port of the host on the internal network.
\item \texttt{proto} - Protocol identifier, see supported list below.
\item \texttt{persistant} - Option for function call: create \texttt{PICO$\_$IPV4$\_$FORWARD$\_$ADD} (= 1) \\
or delete \texttt{PICO$\_$IPV4$\_$FORWARD$\_$DEL} (= 0).
\end{itemize}
\subsubsection*{Protocol list}
\begin{itemize}[noitemsep]
\item \texttt{PICO$\_$PROTO$\_$ICMP4}
\item \texttt{PICO$\_$PROTO$\_$TCP}
\item \texttt{PICO$\_$PROTO$\_$UDP}
\end{itemize}
\subsubsection*{Return value}
On success, this call 0 after a succesfull entry of the forward rule.
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$\_$EAGAIN} - not succesfull, try again
\end{itemize}
\subsubsection*{Example}
\begin{verbatim}
ret = pico_ipv4_port_forward(ext_link_addr, ext_port, host_addr,
host_port, PICO_PROTO_UDP, 1);
\end{verbatim}
\subsection{pico$\_$ipv4$\_$route$\_$add}
\subsubsection*{Description}
Add a new route to the destination IP address from the local device link, f.e. eth0.
\subsubsection*{Function prototype}
\begin{verbatim}
int pico_ipv4_route_add(struct pico_ip4 address, struct pico_ip4 netmask,
struct pico_ip4 gateway, int metric, struct pico_ipv4_link *link);
\end{verbatim}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{address} - Pointer to the destination internet host address as \texttt{struct pico$\_$ip4}.
\item \texttt{netmask} - Netmask of the address. If zeroed, the call assumes the meaning of adding a default gateway.
\item \texttt{gateway} - Gateway of the address network. If zeroed, no gateway will be associated to this route, and the traffic towards the destination will be simply forwarded towards the given device.
\item \texttt{metric} - Metric for this route.
\item \texttt{link} - Local device interface. If a valid gateway is specified, this parameter is not mandatory, otherwise \texttt{NULL} can be used.
\end{itemize}
\subsubsection*{Return value}
On success, this call returns 0. On error, -1 is returned and \texttt{pico$\_$err} is set appropriately.
%if the route already exists or no memory could be allocated.
\subsubsection*{Errors}
\begin{itemize}[noitemsep]
\item \texttt{PICO$\_$ERR$\_$EINVAL} - invalid argument
\item \texttt{PICO$\_$ERR$\_$ENOMEM} - not enough space
\item \texttt{PICO$\_$ERR$\_$EHOSTUNREACH} - host is unreachable
\item \texttt{PICO$\_$ERR$\_$ENETUNREACH} - network unreachable
\end{itemize}
\subsubsection*{Example}
\begin{verbatim}
ret = pico_ipv4_route_add(dst, netmask, gateway, metric, link);
\end{verbatim}
\subsection{pico$\_$ipv4$\_$route$\_$del}
\subsubsection*{Description}
Remove the route to the destination IP address from the local device link, f.e. etho0.
\subsubsection*{Function prototype}
\begin{verbatim}
int pico_ipv4_route_del(struct pico_ip4 address, struct pico_ip4 netmask,
struct pico_ip4 gateway, int metric, struct pico_ipv4_link *link);
\end{verbatim}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{address} - Pointer to the destination internet host address as struct \texttt{pico$\_$ip4}.
\item \texttt{netmask} - Netmask of the address.
\item \texttt{gateway} - Gateway of the address network.
\item \texttt{metric} - Metric of the route.
\item \texttt{link} - Local device interface.
\end{itemize}
\subsubsection*{Return value}
On success, this call returns 0 if the route is found.
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_ipv4_route_del(dst, netmask, gateway, metric, link);
\end{verbatim}
\subsection{pico$\_$ipv4$\_$route$\_$get$\_$gateway}
\subsubsection*{Description}
This function gets the gateway address for the given destination IP address, if set.
\subsubsection*{Function prototype}
\begin{verbatim}
struct pico_ip4 pico_ipv4_route_get_gateway(struct pico_ip4 *addr)
\end{verbatim}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{address} - Pointer to the destination internet host address as struct \texttt{pico$\_$ip4}.
\end{itemize}
\subsubsection*{Return value}
On success the gateway address is returned.
On error a \texttt{null} address is returned (\texttt{0.0.0.0}) and \texttt{pico$\_$err} is set appropriately.
\subsubsection*{Errors}
\begin{itemize}[noitemsep]
\item \texttt{PICO$\_$ERR$\_$EINVAL} - invalid argument
\item \texttt{PICO$\_$ERR$\_$EHOSTUNREACH} - host is unreachable
\end{itemize}
\subsubsection*{Example}
\begin{verbatim}
gateway_addr = pico_ip4 pico_ipv4_route_get_gateway(&dest_addr)
\end{verbatim}
\subsection{pico$\_$icmp4$\_$ping}
\subsubsection*{Description}
This function sends out a number of ping echo requests and checks if the replies are received correctly.
The information from the replies is passed to the callback function after a succesfull reception.
If a timeout expires before a reply is received, the callback is called with the error condition.
\subsubsection*{Function prototype}
\begin{verbatim}
int pico_icmp4_ping(char *dst, int count, int interval, int timeout, int size,
void (*cb)(struct pico_icmp4_stats *));
\end{verbatim}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{dst} - Pointer to the destination internet host address as text string
\item \texttt{count} - Number of pings going to be send
\item \texttt{interval} - Time between two transmissions (in ms)
\item \texttt{timeout} - Timeout period untill reply received (in ms)
\item \texttt{size} - Size of data buffer in bytes
\item \texttt{cb} - Callback for ICMP ping
\end{itemize}
\subsubsection*{Data structure \texttt{struct pico$\_$icmp4$\_$stats}}
\begin{verbatim}
struct pico_icmp4_stats
{
struct pico_ip4 dst;
unsigned long size;
unsigned long seq;
unsigned long time;
unsigned long ttl;
int err;
};
\end{verbatim}
With \textbf{err} values:
\begin{itemize}[noitemsep]
\item \texttt{PICO$\_$PING$\_$ERR$\_$REPLIED} (value 0)
\item \texttt{PICO$\_$PING$\_$ERR$\_$TIMEOUT} (value 1)
\item \texttt{PICO$\_$PING$\_$ERR$\_$UNREACH} (value 2)
\item \texttt{PICO$\_$PING$\_$ERR$\_$PENDING} (value 0xFFFF)
\end{itemize}
\subsubsection*{Return value}
On success, this call returns a positive number, which is the ID of the ping operation just started.
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
\end{itemize}
\subsubsection*{Example}
\begin{verbatim}
id = pico_icmp4_ping(dst_addr, 30, 10, 100, 1000, callback);
\end{verbatim}
\subsection{pico$\_$icmp4$\_$ping$\_$abort}
\subsubsection*{Description}
This function aborts an ongoing ping operation that has previously started using pico$\_$icmp4$\_$ping().
\subsubsection*{Function prototype}
\begin{verbatim}
int pico_icmp4_ping_abort(int id);
\end{verbatim}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{id} - identification number for the ping operation. This has been returned by \texttt{pico$\_$icmp4$\_$ping()} and it is intended to distinguish the operation to be cancelled.
\end{itemize}
\subsubsection*{Return value}
On success, this call returns 0.
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_icmp4_ping_abort(id);
\end{verbatim}

View File

@ -0,0 +1,533 @@
\section{IPv6 functions}
% Short description/overview of module functions
\subsection{pico$\_$ipv6$\_$to$\_$string}
\subsubsection*{Description}
Convert the internet host address IP to a string in IPv6 colon:hex notation.
The result is stored in the char array that ipbuf points to.
\subsubsection*{Function prototype}
\begin{verbatim}
int pico_ipv6_to_string(char *ipbuf, const uint8_t ip[PICO_SIZE_IP6]);
\end{verbatim}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{ipbuf} - Char array to store the result in.
\item \texttt{ip} - Internet host address in unsigned byte array notation of lenght 16.
\end{itemize}
\subsubsection*{Return value}
On success, this call returns 0 if the conversion was successful.
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_ipv6_to_string(buf, ip);
\end{verbatim}
\subsection{pico$\_$string$\_$to$\_$ipv6}
\subsubsection*{Description}
Convert the IPv6 colon:hex notation into binary form. The result is stored in the
\texttt{int} that IP points to.
The address supplied in \texttt{ipstr} can have one of the default forms for IPv6 address
description, including at most one abbreviation skipping zeroed fields using "::"
\subsubsection*{Function prototype}
\begin{verbatim}
int pico_string_to_ipv6(const char *ipstr, uint8_t *ip);
\end{verbatim}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{ipstr} - Pointer to the IP string.
\item \texttt{ip} - Int pointer to store the result in.
\end{itemize}
\subsubsection*{Return value}
On success, this call returns 0 if the conversion was successful.
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_string_to_ipv6("fe80::1", *ip);
\end{verbatim}
\subsection{pico$\_$ipv6$\_$is$\_$unicast}
\subsubsection*{Description}
Check if the provided address is unicast or multicast.
\subsubsection*{Function prototype}
\begin{verbatim}
int pico_ipv6_is_unicast(struct pico_ip6 *a);
\end{verbatim}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{address} - Internet host address.
\end{itemize}
\subsubsection*{Return value}
Returns 1 if unicast, 0 if multicast.
%\subsubsection*{Errors}
\subsubsection*{Example}
\begin{verbatim}
ret = pico_ipv6_is_unicast(address);
\end{verbatim}
\subsection{pico$\_$ipv6$\_$is$\_$multicast}
\subsubsection*{Description}
Check if the provided address is a valid Internet multicast address, i.e. it belongs to the range ff00::/8.
\subsubsection*{Function prototype}
\begin{verbatim}
int pico_ipv6_is_multicast(struct pico_ip6 *a);
\end{verbatim}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{address} - Internet host address.
\end{itemize}
\subsubsection*{Return value}
Returns 1 if a multicast Internet address has been provided.
%\subsubsection*{Errors}
\subsubsection*{Example}
\begin{verbatim}
ret = pico_ipv6_is_multicast(address);
\end{verbatim}
\subsection{pico$\_$ipv6$\_$is$\_$global}
\subsubsection*{Description}
Check if the provided address is a valid Internet global address, i.e. it belongs to the range 2000::/3.
\subsubsection*{Function prototype}
\begin{verbatim}
int pico_ipv6_is_global(struct pico_ip6 *a);
\end{verbatim}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{address} - Internet host address.
\end{itemize}
\subsubsection*{Return value}
Returns 1 if a global Internet address has been provided.
%\subsubsection*{Errors}
\subsubsection*{Example}
\begin{verbatim}
ret = pico_ipv6_is_global(address);
\end{verbatim}
\subsection{pico$\_$ipv6$\_$is$\_$uniquelocal}
\subsubsection*{Description}
Check if the provided address is a valid Internet uniquelocal address, i.e. it belongs to the range fc00::/7.
\subsubsection*{Function prototype}
\begin{verbatim}
int pico_ipv6_is_uniquelocal(struct pico_ip6 *a);
\end{verbatim}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{address} - Internet host address.
\end{itemize}
\subsubsection*{Return value}
Returns 1 if a uniquelocal Internet address has been provided.
%\subsubsection*{Errors}
\subsubsection*{Example}
\begin{verbatim}
ret = pico_ipv6_is_uniquelocal(address);
\end{verbatim}
\subsection{pico$\_$ipv6$\_$is$\_$sitelocal}
\subsubsection*{Description}
Check if the provided address is a valid Internet sitelocal address, i.e. it belongs to the range fec0::/10.
\subsubsection*{Function prototype}
\begin{verbatim}
int pico_ipv6_is_sitelocal(struct pico_ip6 *a);
\end{verbatim}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{address} - Internet host address.
\end{itemize}
\subsubsection*{Return value}
Returns 1 if a sitelocal Internet address has been provided.
%\subsubsection*{Errors}
\subsubsection*{Example}
\begin{verbatim}
ret = pico_ipv6_is_sitelocal(address);
\end{verbatim}
\subsection{pico$\_$ipv6$\_$is$\_$linklocal}
\subsubsection*{Description}
Check if the provided address is a valid Internet linklocal address, i.e. it belongs to the range fe80::/10.
\subsubsection*{Function prototype}
\begin{verbatim}
int pico_ipv6_is_linklocal(struct pico_ip6 *a);
\end{verbatim}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{address} - Internet host address.
\end{itemize}
\subsubsection*{Return value}
Returns 1 if a linklocal Internet address has been provided.
%\subsubsection*{Errors}
\subsubsection*{Example}
\begin{verbatim}
ret = pico_ipv6_is_linklocal(address);
\end{verbatim}
\subsection{pico$\_$ipv6$\_$is$\_$localhost}
\subsubsection*{Description}
Check if the provided address is a valid Internet localhost address, i.e. it is "::1".
\subsubsection*{Function prototype}
\begin{verbatim}
int pico_ipv6_is_localhost(struct pico_ip6 *a);
\end{verbatim}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{address} - Internet host address.
\end{itemize}
\subsubsection*{Return value}
Returns 1 if a localhost Internet address has been provided.
%\subsubsection*{Errors}
\subsubsection*{Example}
\begin{verbatim}
ret = pico_ipv6_is_localhost(address);
\end{verbatim}
\subsection{pico$\_$ipv6$\_$is$\_$undefined}
\subsubsection*{Description}
Check if the provided address is a valid Internet undefined address, i.e. it is "::0".
\subsubsection*{Function prototype}
\begin{verbatim}
int pico_ipv6_is_undefined(struct pico_ip6 *a);
\end{verbatim}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{address} - Internet host address.
\end{itemize}
\subsubsection*{Return value}
Returns 1 if the Internet address provided describes ANY host.
%\subsubsection*{Errors}
\subsubsection*{Example}
\begin{verbatim}
ret = pico_ipv6_is_undefined(address);
\end{verbatim}
\subsection{pico$\_$ipv6$\_$source$\_$find}
\subsubsection*{Description}
Find the source IP for the link associated to the specified destination.
This function will use the currently configured routing table to identify the link that would be used to transmit any traffic directed to the given IP address.
\subsubsection*{Function prototype}
\begin{verbatim}
struct pico_ip6 *pico_ipv6_source_find(struct pico_ip6 *dst);
\end{verbatim}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{address} - Pointer to the destination internet host address as \texttt{struct pico$\_$ip6}.
\end{itemize}
\subsubsection*{Return value}
On success, this call returns the source IP as \texttt{struct pico$\_$ip6}.
If the source can not be found, \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$\_$EHOSTUNREACH} - host is unreachable
\end{itemize}
\subsubsection*{Example}
\begin{verbatim}
src = pico_ipv6_source_find(dst);
\end{verbatim}
\subsection{pico$\_$ipv6$\_$link$\_$add }
\subsubsection*{Description}
Add a new local device dev inteface, f.e. eth0, with IP address 'address' and netmask 'netmask'. A device may have more than one link configured, i.e. to access multiple networks on the same link.
\subsubsection*{Function prototype}
\begin{verbatim}
int pico_ipv6_link_add(struct pico_device *dev, struct pico_ip6 address,
struct pico_ip6 netmask);
\end{verbatim}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{dev} - Local device.
\item \texttt{address} - Pointer to the internet host address as \texttt{struct pico$\_$ip6}.
\item \texttt{netmask} - Netmask of the address.
\end{itemize}
\subsubsection*{Return value}
On success, this call returns 0.
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$\_$ENETUNREACH} - network unreachable
\item \texttt{PICO$\_$ERR$\_$EHOSTUNREACH} - host is unreachable
\end{itemize}
\subsubsection*{Example}
\begin{verbatim}
ret = pico_ipv6_link_add(dev, address, netmask);
\end{verbatim}
\subsection{pico$\_$ipv6$\_$link$\_$del}
\subsubsection*{Description}
Remove the link associated to the local device that was previously configured, corresponding to the IP address 'address'.
\subsubsection*{Function prototype}
\begin{verbatim}
int pico_ipv6_link_del(struct pico_device *dev, struct pico_ip6 address);
\end{verbatim}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{dev} - Local device.
\item \texttt{address} - Pointer to the internet host address as \texttt{struct pico$\_$ip6}.
\end{itemize}
\subsubsection*{Return value}
On success, this call returns 0.
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_ipv6_link_del(dev, address);
\end{verbatim}
\subsection{pico$\_$ipv6$\_$link$\_$find}
\subsubsection*{Description}
Find the local device associated to the local IP address 'address'.
\subsubsection*{Function prototype}
\begin{verbatim}
struct pico_device *pico_ipv6_link_find(struct pico_ip6 *address);
\end{verbatim}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{address} - Pointer to the internet host address as \texttt{struct pico$\_$ip6}.
\end{itemize}
\subsubsection*{Return value}
On success, this call returns the local device.
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$\_$ENXIO} - no such device or address
\end{itemize}
\subsubsection*{Example}
\begin{verbatim}
dev = pico_ipv6_link_find(address);
\end{verbatim}
\subsection{pico$\_$ipv6$\_$route$\_$add}
\subsubsection*{Description}
Add a new route to the destination IP address from the local device link, f.e. eth0.
\subsubsection*{Function prototype}
\begin{verbatim}
int pico_ipv6_route_add(struct pico_ip6 address, struct pico_ip6 netmask,
struct pico_ip6 gateway, int metric, struct pico_ipv6_link *link);
\end{verbatim}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{address} - Pointer to the destination internet host address as \texttt{struct pico$\_$ip6}.
\item \texttt{netmask} - Netmask of the address. If zeroed, the call assumes the meaning of adding a default gateway.
\item \texttt{gateway} - Gateway of the address network. If zeroed, no gateway will be associated to this route, and the traffic towards the destination will be simply forwarded towards the given device.
\item \texttt{metric} - Metric for this route.
\item \texttt{link} - Local device interface. If a valid gateway is specified, this parameter is not mandatory, otherwise \texttt{NULL} can be used.
\end{itemize}
\subsubsection*{Return value}
On success, this call returns 0. On error, -1 is returned and \texttt{pico$\_$err} is set appropriately.
%if the route already exists or no memory could be allocated.
\subsubsection*{Errors}
\begin{itemize}[noitemsep]
\item \texttt{PICO$\_$ERR$\_$EINVAL} - invalid argument
\item \texttt{PICO$\_$ERR$\_$ENOMEM} - not enough space
\item \texttt{PICO$\_$ERR$\_$EHOSTUNREACH} - host is unreachable
\item \texttt{PICO$\_$ERR$\_$ENETUNREACH} - network unreachable
\end{itemize}
\subsubsection*{Example}
\begin{verbatim}
ret = pico_ipv6_route_add(dst, netmask, gateway, metric, link);
\end{verbatim}
\subsection{pico$\_$ipv6$\_$route$\_$del}
\subsubsection*{Description}
Remove the route to the destination IP address from the local device link, f.e. etho0.
\subsubsection*{Function prototype}
\begin{verbatim}
int pico_ipv6_route_del(struct pico_ip6 address, struct pico_ip6 netmask,
struct pico_ip6 gateway, int metric, struct pico_ipv6_link *link);
\end{verbatim}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{address} - Pointer to the destination internet host address as struct \texttt{pico$\_$ip6}.
\item \texttt{netmask} - Netmask of the address.
\item \texttt{gateway} - Gateway of the address network.
\item \texttt{metric} - Metric of the route.
\item \texttt{link} - Local device interface.
\end{itemize}
\subsubsection*{Return value}
On success, this call returns 0 if the route is found.
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_ipv6_route_del(dst, netmask, gateway, metric, link);
\end{verbatim}
\subsection{pico$\_$ipv6$\_$route$\_$get$\_$gateway}
\subsubsection*{Description}
This function gets the gateway address for the given destination IP address, if set.
\subsubsection*{Function prototype}
\begin{verbatim}
struct pico_ip6 pico_ipv6_route_get_gateway(struct pico_ip6 *addr)
\end{verbatim}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{address} - Pointer to the destination internet host address as struct \texttt{pico$\_$ip6}.
\end{itemize}
\subsubsection*{Return value}
On success the gateway address is returned.
On error a \texttt{null} address is returned (\texttt{0.0.0.0}) and \texttt{pico$\_$err} is set appropriately.
\subsubsection*{Errors}
\begin{itemize}[noitemsep]
\item \texttt{PICO$\_$ERR$\_$EINVAL} - invalid argument
\item \texttt{PICO$\_$ERR$\_$EHOSTUNREACH} - host is unreachable
\end{itemize}
\subsubsection*{Example}
\begin{verbatim}
gateway_addr = pico_ip6 pico_ipv6_route_get_gateway(&dest_addr)
\end{verbatim}
\subsection{pico$\_$ipv6$\_$dev$\_$routing$\_$enable}
\subsubsection*{Description}
Enable IPv6 Routing messages through the specified interface. On a picoTCP IPv6 machine,
when routing is enabled, all possible routes to other links are advertised to the target interfaces.
This allows the hosts connected to the target interface to use the picoTCP IPv6 machine as a router
towards public IPv6 addresses configured on other interfaces, or reachable through known gateways.
\subsubsection*{Function prototype}
\begin{verbatim}
struct pico_ip6 pico_ipv6_dev_routing_enable(struct pico_device *dev)
\end{verbatim}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{dev} - Pointer to the target device struct \texttt{pico$\_$device}.
\end{itemize}
\subsubsection*{Return value}
On success, zero is returned.
On error, -1 is returned and \texttt{pico$\_$err} is set appropriately.
\subsubsection*{Example}
\begin{verbatim}
retval = pico_ipv6_dev_routing_enable(eth1);
\end{verbatim}
\subsection{pico$\_$ipv6$\_$dev$\_$routing$\_$disable}
\subsubsection*{Description}
Enable IPv6 Routing messages through the specified interface. On a picoTCP IPv6 machine,
when routing is enabled, all possible routes to other links are advertised to the target interface.
This function will stop advertising reachable routes to public IPv6 addresses configured on other
interfaces, or reachable through known gateways.
\subsubsection*{Function prototype}
\begin{verbatim}
struct pico_ip6 pico_ipv6_dev_routing_disable(struct pico_device *dev)
\end{verbatim}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{dev} - Pointer to the target device struct \texttt{pico$\_$device}.
\end{itemize}
\subsubsection*{Return value}
On success, zero is returned.
On error, -1 is returned and \texttt{pico$\_$err} is set appropriately.
\subsubsection*{Example}
\begin{verbatim}
retval = pico_ipv6_dev_routing_disable(eth1);
\end{verbatim}

View File

@ -0,0 +1,235 @@
\section{MDNS client}
% Short description/overview of module functions
This module can register DNS resource records on the network via Multicast DNS as either \textbf{\emph{shared}} or \textbf{\emph{unique}} records. Unique records are, as the name implies, unique on the network (the record-name and -type combination is unique) and one single host has claimed the ownership of them. Shared records are records that are not unique on the network, which means multiple hosts can register records with the same record-name and -type combination. For more information on shared and unique resource record sets, see RFC6762.
Unique records are, as it should, defended when somebody else tries to claim the same unique records. When hosts detect such a defense of another host while registering their own records, the conflict will be resolved by choosing another name for the records and another attempt is made to register those new records.
This module only supplies the mechanisms of record registration and resolving on the network, it doesn't parses the contents of them, that's up to the application.
\subsection{pico$\_$mdns$\_$init}
\subsubsection*{Description}
Initialises the entire mDNS-module and sets the hostname for this machine. Sets up the global mDNS socket properly and calls callback when succeeded. Only when the module is properly initialised, records can be registered on the network.
\subsubsection*{Function prototype}
\begin{verbatim}
int pico_mdns_init( const char *hostname,
struct pico_ip4 address,
void (*callback)(pico_mdns_rtree *, char *, void *),
void *arg );
\end{verbatim}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{hostname} - Hostname to register for this machine. Should end with \'.local\'.
\item \texttt{address} - IPv4-address of this machines interface to generate a hostname record from.
\item \texttt{cb$\_$initialised} - Callback-function that is called when the initialisation process is done. This will also get called when asynchronous conflicts occur for successfully registered records during run-time. The mDNS-record tree contains the registered records, the char-buffer contains the registered hostname and the void-pointer contains the passed argument.
\item \texttt{arg} - Argument for callback supplied by user. This can be used if you want to pass some variable into your callback function.
\end{itemize}
\subsubsection*{Return value}
Returns 0 when the module is properly initialised and the host started registering the hostname. Returns something else went the host failed initialising the module or registering the hostname. \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
\end{itemize}
\subsubsection*{Example}
\begin{verbatim}
pico_mdns_init("host.local", address, &mdns_init_callback, NULL);
\end{verbatim}
\subsection{pico$\_$mdns$\_$get$\_$hostname}
\subsubsection*{Description}
Get the current hostname for this machine.
\subsubsection*{Function prototype}
\begin{verbatim}
const char * pico_mdns_get_hostname( void );
\end{verbatim}
\subsubsection*{Return value}
Returns the current hostname for this machine when the module is initialised, returns NULL when the module is not initialised.
\subsubsection*{Errors}
\begin{itemize}[noitemsep]
\item \texttt{PICO$\_$ERR$\_$EINVAL} - invalid argument
\end{itemize}
\subsubsection*{Example}
\begin{verbatim}
char *url = pico_mdns_get_hostname();
\end{verbatim}
\subsection{pico$\_$mdns$\_$set$\_$hostname}
\subsubsection*{Description}
Tries to claim a hostname for this machine. Claims automatically a unique A record with the IPv4-address of this host. The hostname won't be set directly when this functions returns, but only if the claiming of the unique record succeeded. Init-callback specified when initialising the module will be called when the hostname-record is successfully registered.
\subsubsection*{Function prototype}
\begin{verbatim}
int pico_mdns_tryclaim_hostname( const char *url, void *arg );
\end{verbatim}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{url} - URL to set the hostname to. Should end with \'.local\'.
\item \texttt{arg} - Argument for init-callback supplied by user. This can be used if you want to pass some variable into your callback function.
\end{itemize}
\subsubsection*{Return value}
Returns 0 when the host started registering the hostname-record successfully, returns something else when it didn't succeed. \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
\end{itemize}
\subsubsection*{Example}
\begin{verbatim}
int ret = pico_mdns_tryclaim_hostname("device.local", NULL);
\end{verbatim}
\subsection{pico$\_$mdns$\_$claim}
\subsubsection*{Description}
Claims all different mDNS records in a tree in a single API-call. All records in the mDNS record-tree are registered in a single new claim-session.
\subsubsection*{Function prototype}
\begin{verbatim}
int pico_mdns_claim( pico_mdns_rtree record_tree,
void (*callback)(pico_mdns_rtree *, char *, void *),
void *arg );
\end{verbatim}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{record$\_$tree} - mDNS record-tree with records to register on the network via Multicast DNS. Can contain \textbf{\emph{unique records}} as well as \textbf{\emph{shared records}}. Declare a mDNS record-tree with the macro 'PICO$\_$MDNS$\_$RTREE$\_$DECLARE(name)', which is actually just a pico$\_$tree-struct, with a comparing-function already set. Records can be added with the preprocessor macro 'PICO$\_$MDNS$\_$RTREE$\_$ADD(pico$\_$mdns$\_$rtree *, struct pico$\_$mdns$\_$record *)'. To create mDNS records see 'pico$\_$mdns$\_$record$\_$create'.
\item \texttt{callback} - Callback function that gets called when \textbf{\emph{ALL}} records in the tree are successfully registered on the network. Records in the returned tree can differ from records originally registered due to conflict-resolution and such.
\item \texttt{arg} - Argument for callback supplied by user. This can be used if you want to pass some variable into your callback function.
\end{itemize}
\subsubsection*{Return value}
Returns 0 when the host started registering the record successfully, returns something else when it didn't succeed. \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
\end{itemize}
\subsubsection*{Example}
\begin{verbatim}
...
PICO_MDNS_RTREE_DECLARE(rtree);
PICO_MDNS_RTREE_ADD(&rtree, &record);
int ret = pico_mdns_claim(rtree, &claimed_cb, NULL);
\end{verbatim}
\subsection{pico$\_$mdns$\_$getrecord}
\subsubsection*{Description}
API-call to query a record with a certain URL and type. First checks the cache for this record. If no cache-entry is found, a query will be sent on the wire for this record.
\subsubsection*{Function prototype}
\begin{verbatim}
int pico_mdns_getrecord( const char *url, uint16_t type,
void (*callback)(pico_mdns_rtree *, char *, void *),
void *arg );
\end{verbatim}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{url} - URL of the DNS name to query records for.
\item \texttt{type} - DNS type of the records to query for on the network.
\item \texttt{callback} - Callback to call when records are found or answers to the query are received. This functions can get called multiple times when multiple answers are possible (e.g. with shared records). It's up to the application to aggregate all these received answers, this is possible with a static variable of the type pico$\_$mdns$\_$rtree.
\item \texttt{arg} - Argument for callback supplied by user. This can be used if you want to pass some variable into your callback function.
\end{itemize}
\subsubsection*{Return value}
Returns 0 when the host started querying for these records successfully or the records are found in the cache. Returns something else when it didn't succeed. \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
\end{itemize}
\subsubsection*{Example}
\begin{verbatim}
int ret = pico_mdns_getrecord("_ipp._tcp.local", PICO_DNS_TYPE_PTR, &query_cb, NULL);
\end{verbatim}
\subsection{pico$\_$mdns$\_$record$\_$create}
\subsubsection*{Description}
Creates a single standalone mDNS resource record with given name, type and data to register on the network.
\subsubsection*{Function prototype}
\begin{verbatim}
struct pico_mdns_record *pico_mdns_record_create( const char *url,
void *_rdata,
uint16_t datalen,
uint16_t rtype,
uint32_t rttl,
uint8_t flags );
\end{verbatim}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{url} - DNS resource record name in URL format. Will be converted to DNS name notation format.
\item \texttt{$\_$rdata} - Memory buffer with data to insert in the resource record. If data of record should contain a DNS name, the name in the databuffer needs to be in URL-format.
\item \texttt{datalen} - The exact length in bytes of the $\_$rdata-buffer. If data of record should contain a DNS name (f.e. with PICO$\_$DNS$\_$TYPE$\_$PTR), datalen needs to be pico$\_$dns$\_$strlen($\_$rdata).
\item \texttt{rtype} - DNS type of the resource record to be.
\item \texttt{ttl} - TTL of the resource record to be when registered on the network. In seconds.
\item \texttt{flags} - With this parameter, you can specify a record as either a shared record or a unique record with respectively PICO$\_$MDNS$\_$RECORD$\_$SHARED- or PICO$\_$MDNS$\_$RECORD$\_$UNIQUE-preprocessor defines. Records are by default registered as unique.
\end{itemize}
\subsubsection*{Return value}
Returns a pointer to the newly created record on success, returns NULL on failure. \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
\end{itemize}
\subsubsection*{Example}
\begin{verbatim}
pico_ip4 ip = 0;
pico_string_to_ipv4("10.10.0.5", &(ip.addr));
struct pico_mdns_record *record = pico_mdns_record_create("foo.local",
&(ip.addr),
PICO_SIZE_IP4,
PICO_DNS_TYPE_ANY,
120,
PICO_MDNS_RECORD_UNIQUE);
\end{verbatim}
\subsection{IS$\_$HOSTNAME$\_$RECORD}
\subsubsection*{Description}
The initialisation-callback can get called multiple times during run-time due to \emph{passive conflict detection}. A passive conflict occurs for unique records when a faulty Multicast DNS-responder doesn't apply conflict resolution after an occurred conflict. A passive conflict can also occur when a peer registers a \textbf{\emph{shared}} record with the same name and type combination as a \textbf{\emph{unique}} record that the local host already successfully registered on the network. Because of that, shared records have priority over unique records, so unfortunately the local host has to apply the conflict resolution-mechanism to it's earlier uniquely verified record. To be able to notify the application of an updated unique record, the callback gets called given in the initialisation-function. But since that callback maybe parses the returned records as the hostname-records and this isn't necessarily the case when a passive conflict occurs, a mechanism is needed to differ hostname-records from other records. This preprocessor-macro allows this.
\subsubsection*{Function prototype}
\begin{verbatim}
IS_HOSTNAME_RECORD(record)
\end{verbatim}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{record} - mDNS resource record
\end{itemize}
\subsubsection*{Return value}
Returns 1 when this record is a hostname record, returns 0 when it's not or when given pointer is a NULL pointer.

View File

@ -0,0 +1,42 @@
\section{MLD}
% Short description/overview of module functions
This module allows the user to join and leave ipv6 multicast groups. The module is based on the MLD version 2 protocol and it's backwards compatible with version 1.
The MLD module is completly driven from socket calls (\ref{socket:setoption}) and non of the MLD application interface functions should be called by the user. If however, by any reason, it's necessary for the user to do this, the following function call is provided:
\subsection{pico\_mld\_state\_change}
\subsubsection*{Description}
Change the state of the host to Non-listener, Idle listener or Delaying listener.
\subsubsection*{Function prototype}
\begin{verbatim}
int pico_mld_state_change(struct pico_ip6 *mcast_link, struct pico_ip6 *mcast_group,
uint8_t filter_mode, struct pico_tree *_MCASTFilter, uint8_t state)
\end{verbatim}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{mcast\_link} - the link on which that multicast group should be joined.
\item \texttt{mcast\_group} - the address of the multicast group you want to join.
\item \texttt{filter\_mode} - the kind of source filtering, if applied.
\item \texttt{\_MCASTFilter} - list of multicast sources on which source filtering might be applied.
\item \texttt{state} - the prefered new state.
\end{itemize}
\subsubsection*{Errors}
In case of failure, -1 is returned, and the value of pico$\_$err
is set as follows:
\begin{itemize}[noitemsep]
\item \texttt{PICO$\_$ERR$\_$EINVAL} - Invalid argument provided
\item \texttt{PICO$\_$ERR$\_$ENOMEM} - Not enough space
\item \texttt{PICO$\_$ERR$\_$EPROTONOSUPPORT} - Invalid protocol (or protocol version) found on the link
\item \texttt{PICO$\_$ERR$\_$EFAULT} - Internal error
\end{itemize}
%\subsubsection*{Example}
%\subsubsection*{Errors}
%\subsubsection*{Example}

View File

@ -0,0 +1,49 @@
\section{Optimized Link State Routing (OLSR) Module}
OLSR is a proactive routing protocol for mobile ad-hoc networks
(MANETs). It is well suited to large and dense mobile
networks, as the optimization achieved using the MPRs works well in
this context. The larger and more dense a network, the more
optimization can be achieved as compared to the classic link state
algorithm. OLSR uses hop-by-hop routing, i.e., each node uses its
local information to route packets.
OLSR is well suited for networks, where the traffic is random and
sporadic between a larger set of nodes rather than being almost
exclusively between a small specific set of nodes. As a proactive
protocol, OLSR is also suitable for scenarios where the communicating
pairs change over time: no additional control traffic is generated in
this situation since routes are maintained for all known destinations
at all times. -- cfr. RFC3626
\subsection{pico\_olsr\_add}
\subsubsection*{Description}
This function will add the target device to the OLSR mechanism on the machine,
meaning that it will be possible to advertise and collect routing information
using Optimized Link State Routing protocol, as described in RFC3626, through the
target device.
In order to use multiple devices in the OLSR system, this function needs to be called
multiple times, once per device.
\subsubsection*{Function prototype}
\texttt{pico\_olsr\_add(struct pico\_device *dev);}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{dev} - a pointer to a struct \texttt{pico\_device} specifying the target interface.
\end{itemize}
\subsubsection*{Return value}
0 returned if the device is successfully added.
\subsubsection*{Example}
\begin{verbatim}
ret = pico_olsr_add(dev);
\end{verbatim}

View File

@ -0,0 +1,257 @@
\section{Point-to-Point Protocol (PPP)}
PPP consists in a family of data-link protocols, providing link control,
configuration and authentication over a point-to-point link. In a connected
embedded system, it is often used to access dial-up modems over serial lines.
This module supports GSM modem configuration by implementing part of ETSI TS 127 007.
From the picoTCP perspective, each PPP capable device may be abstracted into its own instance
that can be created using \texttt{pico\_ppp\_create}.
Any GSM/GPRS/3G/HSDPA module, exporting a non-blocking serial interface, such as SPI or UART,
can be connected to the ppp device abstraction, using \texttt{pico\_ppp\_set\_serial\_read},
\texttt{pico\_ppp\_set\_serial\_write}, \texttt{pico\_ppp\_set\_serial\_set\_speed}.
Once the physical interface is attached, the access to the remote access point gateway
can be configured using \texttt{pico\_ppp\_set\_apn}, \texttt{pico\_ppp\_set\_username} and
\texttt{pico\_ppp\_set\_password}.
When the interface is configured, the connection may be established using
\texttt{pico\_ppp\_connect}. Even if the peer disconnects, the connection will be brought up
again automatically afterwords.
To interrupt the connection and stop the automatic reconnection, \texttt{pico\_ppp\_disconnect}
can be called.
\subsection{pico\_ppp\_create}
\subsubsection*{Description}
This function will create a new device association to be used with the ppp driver. The driver
must then afterwards be associated with lower-level serial functions in order to be used.
\subsubsection*{Function prototype}
\texttt{struct pico\_device *pico\_ppp\_create(void);}
\subsubsection*{Return value}
A new pico\_device is allocated and returned if the device is successfully created.
\subsubsection*{Example}
\begin{verbatim}
ppp = pico_ppp_create();
\end{verbatim}
\subsection{pico\_ppp\_set\_serial\_read}
\subsubsection*{Description}
This function will associate the read function from an external source (e.g. a UART device API)
to the read functionality of the PPP driver. Setting up a proper read/write interface is necessary
for the PPP driver to work properly.
The function associated with the read must be non-blocking, no matter the execution model of the system.
\subsubsection*{Function prototype}
\texttt{int pico\_ppp\_set\_serial\_read(struct pico\_device *dev, int (*sread)(struct pico\_device *, void *, int))}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{dev} - a pointer to a struct \texttt{pico\_device} specifying the target interface.
\item \texttt{sread} - a pointer to a function of type \texttt{int fn(struct pico\_device *, void *, int)}
specifying the target serial read function. The function prototype will be called with the device pointer,
a buffer to be filled with serial data, and the maximum lenght of the usable buffer.
\end{itemize}
\subsubsection*{Return value}
0 returned if the serial read function is successfully associated.
\subsubsection*{Example}
\begin{verbatim}
static int my_serial_read(struct pico_device *dev, void *buf, int len)
{
return nonblock_uart_read(buf, len);
}
pico_ppp_set_serial_read(ppp, my_serial_read);
\end{verbatim}
\subsection{pico\_ppp\_set\_serial\_write}
\subsubsection*{Description}
This function will associate the write function from an external source (e.g. a UART device API)
to the write functionality of the PPP driver. Setting up a proper read/write interface is necessary
for the PPP driver to work properly.
The function associated with the write must be non-blocking, no matter the execution model of the system.
\subsubsection*{Function prototype}
\texttt{int pico\_ppp\_set\_serial\_write(struct pico\_device *dev, int (*swrite)(struct pico\_device *, const void *, int))}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{dev} - a pointer to a struct \texttt{pico\_device} specifying the target interface.
\item \texttt{swrite} - a pointer to a function of type \texttt{int fn(struct pico\_device *, const void *, int)}
specifying the target serial write function. The function prototype will be called with the device pointer,
a buffer to be filled with serial data, and the maximum lenght of the usable buffer.
\end{itemize}
\subsubsection*{Return value}
0 returned if the serial write function is successfully associated.
\subsubsection*{Example}
\begin{verbatim}
static int my_serial_write(struct pico_device *dev, const void *buf, int len)
{
return nonblock_uart_write(buf, len);
}
pico_ppp_set_serial_write(ppp, my_serial_write);
\end{verbatim}
\subsection{pico\_ppp\_set\_serial\_set\_speed}
\subsubsection*{Description}
This function will associate the set\_speed function from an external source (e.g. a UART device API)
to dynamically set the UART speed for the interface with the PPP driver.
Calling this function is not mandatory for the PPP UART interface to work.
\subsubsection*{Function prototype}
\texttt{int pico\_ppp\_set\_serial\_set\_speed(struct pico\_device *dev, int (*sset\_speed)(struct pico\_device *, uint32\_t))}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{dev} - a pointer to a struct \texttt{pico\_device} specifying the target interface.
\item \texttt{sset\_speed} - a pointer to a function of type \texttt{int fn(struct pico\_device *, uint32\_t speed)}
specifying the target serial set\_speed function. The function prototype will be called with the device pointer and
the speed at which the UART should be configured by PPP.
\end{itemize}
\subsubsection*{Return value}
0 returned if the serial set\_speed function is successfully associated.
\subsubsection*{Example}
\begin{verbatim}
static int my_serial_set_speed(struct pico_device *dev, uint32_t speed)
{
return uart_set_speed(speed);
}
pico_ppp_set_serial_set_speed(ppp, my_serial_set_speed);
\end{verbatim}
\subsection{pico\_ppp\_set\_apn}
\subsubsection*{Description}
This function allows the configuration of the APN name in order for PPP to correctly establish the connection
to the remote Access Point gateway.
\subsubsection*{Function prototype}
\texttt{int pico\_ppp\_set\_apn(struct pico\_device *dev, const char *apn);}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{dev} - a pointer to a struct \texttt{pico\_device} specifying the target interface.
\item \texttt{apn} - a string containing the Access Point Name.
\end{itemize}
\subsubsection*{Return value}
0 returned if the APN is correctly configured.
\subsubsection*{Example}
\begin{verbatim}
ret = pico_ppp_set_apn(dev, "internet.apn.name");
\end{verbatim}
\subsection{pico\_ppp\_set\_username}
\subsubsection*{Description}
This function will set an username for the PAP/CHAP authentication mechanism.
\subsubsection*{Function prototype}
\texttt{int pico\_ppp\_set\_username(struct pico\_device *dev, const char *username); }
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{dev} - a pointer to a struct \texttt{pico\_device} specifying the target interface.
\item \texttt{username} - a string specifying the desired username.
\end{itemize}
\subsubsection*{Return value}
0 returned if the username is successfully configured.
\subsubsection*{Example}
\begin{verbatim}
ret = pico_ppp_set_username(dev, "john");
\end{verbatim}
\subsection{pico\_ppp\_set\_password}
\subsubsection*{Description}
This function will set the password for the PAP/CHAP authentication mechanism.
\subsubsection*{Function prototype}
\texttt{int pico\_ppp\_set\_password(struct pico\_device *dev, const char *password); }
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{dev} - a pointer to a struct \texttt{pico\_device} specifying the target interface.
\item \texttt{username} - a string specifying the desired password.
\end{itemize}
\subsubsection*{Return value}
0 returned if the password is successfully configured.
\subsubsection*{Example}
\begin{verbatim}
ret = pico_ppp_set_password(dev, "secret");
\end{verbatim}
\subsection{pico\_ppp\_connect}
\subsubsection*{Description}
This function will enable the PPP connection, by triggering the startup of the handshakes
required at all levels. If the connection is dropped, the system will try to reconnect by restarting
the handshakes, until \texttt{pico\_ppp\_disconnect} is finally called.
\subsubsection*{Function prototype}
\texttt{int pico\_ppp\_connect(struct pico\_device *ppp)}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{dev} - a pointer to a struct \texttt{pico\_device} specifying the target interface.
\end{itemize}
\subsubsection*{Return value}
0 returned if the device is successfully connecting.
\subsubsection*{Example}
\begin{verbatim}
ret = pico_ppp_connect(dev);
\end{verbatim}
\subsection{pico\_ppp\_disconnect}
\subsubsection*{Description}
This function will disable the PPP connection, by triggering a disconnection, and by disabling the
reconnect feature, if enabled.
\subsubsection*{Function prototype}
\texttt{int pico\_ppp\_disconnect(struct pico\_device *ppp)}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{dev} - a pointer to a struct \texttt{pico\_device} specifying the target interface.
\end{itemize}
\subsubsection*{Return value}
0 returned if the device is successfully put in disconnected state.
\subsubsection*{Example}
\begin{verbatim}
ret = pico_ppp_disconnect(dev);
\end{verbatim}

View File

@ -0,0 +1,44 @@
\section{SLAACV4 Module}
% Short description/overview of module functions
\subsection{pico\_slaacv4\_claimip}
\subsubsection*{Description}
This function starts the ip claiming process for a device. It will generate first the local link ip using
as seed the mac address of the device. Then it will start the claim procedure described in RFC3927.
In case of success the IP is registered to the IP layer and returned using the callback function.
In case of error, code SLAACV4\_ERROR is returned. Errors occur when the maximum number of conflicts is reached.
Use the IP returned only if the return code is SLAACV4\_SUCCESS.
\subsubsection*{Function prototype}
\texttt{pico\_slaacv4\_claimip(struct pico\_device *dev, void (*cb)(struct pico\_ip4 *ip, uint8\_t code));}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{dev} - a pointer to a struct \texttt{pico\_device}
\item \texttt{*cb} - a callback function returning the ip claimed and a return code (SLAACV4\_ERROR | SLAACV4\_SUCCESS)
\end{itemize}
\subsubsection*{Return value}
0 returned if the claiming has started successfully
\subsubsection*{Example}
\begin{verbatim}
dev = pico_get_device(sdev);
ret = pico_slaacv4_claimip(dev, slaacv4_cb);
\end{verbatim}
\subsection{pico\_slaacv4\_unregisterip}
\subsubsection*{Description}
This function allows to unregister the local link ip in usage. The function will remove from the route table
the local link ip and will reset the internal state of the SLAACV4 module
\subsubsection*{Function prototype}
\texttt{void pico\_slaacv4\_unregisterip(void);}

View File

@ -0,0 +1,96 @@
\section{SNTP client}
% Short description/overview of module functions
This module allows you to sync your device to to a specified (s)ntp server.
You can then retreive the time with the pico$\_$sntp$\_$gettimeofday function.
\subsection{pico$\_$sntp$\_$sync}
\subsubsection*{Description}
Function to sync the local time to a given sntp server in string notation. DNS resolution will be done automatically.
\subsubsection*{Function prototype}
\begin{verbatim}
int pico_sntp_sync(char *sntp_server, void (*cb_synced)(pico_err_t status));
\end{verbatim}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{sntp$\_$server} - String with the sntp server to get the time from
\item \texttt{cb$\_$synced} - Callback function that is called when the synchronisation process is done. The status variable indicates wheter the synchronisation was successful or not.
\end{itemize}
\subsubsection*{Return value}
On success, this call returns 0 if the synchronisation operation has successfully started. When both IPv4 and IPv6 are enabled, success on one is sufficient.
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$\_$EPROTONOSUPPORT} - compiled without DNS support
\end{itemize}
\subsubsection*{Example}
\begin{verbatim}
int ret = pico_sntp_sync("ntp.nasa.gov", &callback);
\end{verbatim}
\subsection{pico$\_$sntp$\_$sync$\_$ip}
\subsubsection*{Description}
Function to sync the local time to a given sntp server in IP address notation.
\subsubsection*{Function prototype}
\begin{verbatim}
int pico_sntp_sync_ip(union pico_address *sntp_addr, void (*cb_synced)(pico_err_t status));
\end{verbatim}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{sntp$\_$addr} - IP address of the sntp server to get the time from
\item \texttt{cb$\_$synced} - Callback function that is called when the synchronisation process is done. The status variable indicates wheter the synchronisation was successful or not.
\end{itemize}
\subsubsection*{Return value}
On success, this call returns 0 if the synchronisation operation has successfully started. When both IPv4 and IPv6 are enabled, success on one is sufficient.
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
\end{itemize}
\subsubsection*{Example}
\begin{verbatim}
int ret = pico_sntp_sync_ip(&sntp_addr, &callback);
\end{verbatim}
\subsection{pico$\_$sntp$\_$gettimeofday}
\subsubsection*{Description}
Function to get the current time. Be sure to call the pico$\_$sntp$\_$sync function to synchronise BEFORE calling this function.
\subsubsection*{Function prototype}
\begin{verbatim}
int pico_sntp_gettimeofday(struct pico_timeval *tv);
\end{verbatim}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{tv} - Pointer to a time$\_$val struct in which the current time will be set.
\end{itemize}
\subsubsection*{Return value}
On success, this call returns 0 if the time is set.
On error, -1 is returned and \texttt{pico$\_$err} is set appropriately.
\subsubsection*{Example}
\begin{verbatim}
int ret = pico_sntp_gettimeofday(tv);
\end{verbatim}

View File

@ -0,0 +1,804 @@
\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.
Note that the port needs to be passed in network byte order (big-endian), as with all socket calls.
\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.
Note that the port needs to be passed in network byte order (big-endian), as with all socket calls.
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.
Note that the port needs to be passed in network byte order (big-endian), as with all socket calls.
\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.
Note that the port needs to be passed in network byte order (big-endian), as with all socket calls.
\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}

View File

@ -0,0 +1,911 @@
\section{TFTP}
% Short description/overview of module functions
This module provides support for Trivial File Transfer Protocol (TFTP).
The support includes client and server implementation, both of them can be active at the same time.
Flows must be split up into TFTP blocks on the sender side, and reassembled from block len
on the receiving side. Please note that a block whose size is less than the block size indicates
the end of the transfer.
To indicate the end of a transfer where the content is aligned with the block size, an additional
transmission of zero bytes must follow the flow.
Function pico$\_$tftp$\_$listen must be used to start the server with a proper callback that should be provided by the user. To reject a request received by the server the server callback must call pico$\_$tftp$\_$reject$\_$request.
In order to start transmission or reception of files a session handler must be obtained with a call to pico$\_$tftp$\_$session$\_$setup. The created session may take advantage of the Extenxed Options of the TFTP protocol invoking pico$\_$tftp$\_$set$\_$option before starting using it.
Real file transaction is started using the functions pico$\_$tftp$\_$start$\_$tx and pico$\_$tftp$\_$start$\_$rx; both require a callback that must be provided by the user to handle single chunks of the transmission. The transmitter callback must use pico$\_$tftp$\_$send function to send each block of data.
In case of problem the session can be aborted (and an error message is sent to the remote side) using pico$\_$tftp$\_$abort.
When a transfer is complete the session became invalid and must not be used any more.
\subsection*{Application driven interface}
In some use case is preferable to have an application driven behaviour. The API provide 5 specific functions to use TFTP in this scenario.
The way to obtain a session handler suited for this purpose is an invocation to the function pico$\_$tftp$\_$app$\_$setup. The synchro variable passed to this function will play a key role during the management of the transfer.
As usual the section can be instructed to use Extended Options using pico$\_$tftp$\_$set$\_$option before starting the file transfer.
Once the session is created, the application can start receiving a file with a call to the function pico$\_$tftp$\_$app$\_$start$\_$rx or, if needs to transmit, invoking pico$\_$tftp$\_$app$\_$start$\_$tx.
After the file transfer is started the user is allowed to perform data handling only when the synchro variable associated with the session is not 0. It is set to 0 after calling pico$\_$tftp$\_$app$\_$setup. A value that differ to 0 means that a single chunk is ready to be handled.
Single chunk of data are received using pico$\_$tftp$\_$get and transmitted with the use of the function pico$\_$tftp$\_$put.
Once the file transfer ends, both for completion or in case of error, the session is no more valid.
\subsection{pico\_tftp\_listen}
\subsubsection*{Description}
Start up a TFTP server listening for GET/PUT requests on the given port.
The function pointer passed as callback in the \texttt{cb} argument will be invoked upon a new
transfer request received from the network, and the call will pass the information about:
\begin{itemize}[noitemsep]
\item The address of the remote peer asking for a transfer
\item The remote port of the peer
\item The type of transfer requested, via the \texttt{opcode} parameter being either \texttt{PICO$\_$TFTP$\_$RRQ} or \texttt{PICO$\_$TFTP$\_$WRQ}, for get or put requests respectively.
\end{itemize}
\subsubsection*{Function prototype}
\begin{verbatim}
int pico_tftp_listen(uint16_t family, void (*cb)(union pico_address *addr,
uint16_t port, uint16_t opcode, char *filename, int32_t len));
\end{verbatim}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{family} - The chosen socket family. Accepted values are \texttt{PICO$\_$PROTO$\_$IPV4} for IPv4 and \texttt{PICO$\_$PROTO$\_$IPV6} for IPv6.
\item \texttt{cb} - a pointer to the callback function, defined by the user, that will be called upon a new transfer request.
\end{itemize}
\subsubsection*{Return value}
This function returns 0 if succeeds or -1 in case of errors (pico$\_$err is set accordingly).
\subsubsection*{Example}
\begin{verbatim}
/* Example of a TFTP listening service callback */
void tftp_listen_cb(union pico_address *addr, uint16_t port,
uint16_t opcode, char *filename, int32_t len)
{
struct note_t *note;
struct pico_tftp_session *session;
printf("TFTP listen callback (BASIC) from remote port %" PRIu16 ".\n",
short_be(port));
if (opcode == PICO_TFTP_RRQ) {
printf("Received TFTP get request for %s\n", filename);
note = transfer_prepare(&session, 't', filename, addr, family);
start_tx(session, filename, port, cb_tftp_tx, note);
} else if (opcode == PICO_TFTP_WRQ) {
printf("Received TFTP put request for %s\n", filename);
note = transfer_prepare(&session, 'r', filename, addr, family);
start_rx(session, filename, port, cb_tftp_rx, note);
}
}
// Code fragment to demostrate the use of pico_tftp_listen:
if (!is_server_enabled) {
pico_tftp_listen(PICO_PROTO_IPV4, (commands->operation == 'S') ?
tftp_listen_cb_opt : tftp_listen_cb);
is_server_enabled = 1;
}
\end{verbatim}
\subsection{pico\_tftp\_reject\_request}
\subsection*{Description}
This message is used in listen callback to reject a request with an error message.
\subsection*{Function prototype}
\begin{verbatim}
int pico_tftp_reject_request(union pico_address *addr, uint16_t port,
uint16_t error_code, const char *error_message);
\end{verbatim}
\subsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{addr} - The address of the remote peer; it must match the address where the request came from.
\item \texttt{port} - The port on the remote peer; it must match the address where the request came from.
\item \texttt{error$\_$code} - Error reason, possible values are:
\begin{tabular}{ll}
TFTP$\_$ERR$\_$UNDEF & Not defined, see error message (if any) \\
TFTP$\_$ERR$\_$ENOENT & File not found \\
TFTP$\_$ERR$\_$EACC & Access violation \\
TFTP$\_$ERR$\_$EXCEEDED & Disk full or allocation exceeded \\
TFTP$\_$ERR$\_$EILL & Illegal TFTP operation \\
TFTP$\_$ERR$\_$ETID & Unknown transfer ID \\
TFTP$\_$ERR$\_$EEXIST & File already exists \\
TFTP$\_$ERR$\_$EUSR & No such user \\
TFTP$\_$ERR$\_$EOPT & Option negotiation \\
\end{tabular}
\item \texttt{message} - Text message to attach.
\end{itemize}
\subsubsection*{Return value}
This function returns 0 if succeeds or -1 in case of errors (pico$\_$err is set accordingly).
\subsection*{Example}
\begin{verbatim}
void tftp_listen_cb_opt(union pico_address *addr, uint16_t port,
uint16_t opcode, char *filename, int32_t len)
{
struct note_t *note;
struct pico_tftp_session *session;
int options;
uint8_t timeout;
int32_t filesize;
int ret;
printf("TFTP listen callback (OPTIONS) from remote port %" PRIu16 ".\n",
short_be(port));
/* declare the options we want to support */
ret = pico_tftp_parse_request_args(filename, len, &options,
&timeout, &filesize);
if (ret)
pico_tftp_reject_request(addr, port, TFTP_ERR_EOPT,
"Malformed request");
if (opcode == PICO_TFTP_RRQ) {
printf("Received TFTP get request for %s\n", filename);
note = transfer_prepare(&session, 'T', filename, addr, family);
if (options & PICO_TFTP_OPTION_TIME)
pico_tftp_set_option(session, PICO_TFTP_OPTION_TIME, timeout);
if (options & PICO_TFTP_OPTION_FILE) {
ret = get_filesize(filename);
if (ret < 0) {
pico_tftp_reject_request(addr, port, TFTP_ERR_ENOENT,
"File not found");
return;
}
pico_tftp_set_option(session, PICO_TFTP_OPTION_FILE, ret);
}
start_tx(session, filename, port, cb_tftp_tx_opt, note);
} else { /* opcode == PICO_TFTP_WRQ */
printf("Received TFTP put request for %s\n", filename);
note = transfer_prepare(&session, 'R', filename, addr, family);
if (options & PICO_TFTP_OPTION_TIME)
pico_tftp_set_option(session, PICO_TFTP_OPTION_TIME, timeout);
if (options & PICO_TFTP_OPTION_FILE)
pico_tftp_set_option(session, PICO_TFTP_OPTION_FILE, filesize);
start_rx(session, filename, port, cb_tftp_rx_opt, note);
}
}
\end{verbatim}
\subsection{pico\_tftp\_session\_setup}
\subsubsection*{Description}
Obtain a session handler to use for the next file transfer with a remote location.
\subsubsection*{Function prototype}
\begin{verbatim}
struct pico_tftp_session * pico_tftp_session_setup(union pico_address *a,
uint16_t family);
\end{verbatim}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{a} - The address of the peer to be contacted. In case of a solicited transfer, it must match the address where the request came from.
\item \texttt{family} - The chosen socket family. Accepted values are \texttt{PICO$\_$PROTO$\_$IPV4} for IPv4 and \texttt{PICO$\_$PROTO$\_$IPV6} for IPv6.
\end{itemize}
\subsubsection*{Return value}
In case of success a session handler is returned. In case of failure, NULL is returned and pico$\_$err is set accordingly.
\subsubsection*{Example}
\begin{verbatim}
struct pico_tftp_session * make_session_or_die(union pico_address *addr,
uint16_t family)
{
struct pico_tftp_session * session;
session = pico_tftp_session_setup(addr, family);
if (!session) {
fprintf(stderr, "TFTP: Error in session setup\n");
exit(3);
}
return session;
}
\end{verbatim}
\subsection{pico\_tftp\_set\_option}
\subsection*{Description}
This function is used to require the use of Extended Options for TFTP transfer associate to a session according to RFC 2347 and RFC 2349. It should be used before the invocation of pico$\_$tftp$\_$start$\_$rx or pico$\_$tftp$\_$start$\_$tx unless the setting is related to the timeout.
In order to require Transfer size Option PICO$\_$TFTP$\_$OPTION$\_$FILE must be used and its value set to the file size in case of a Write Request or to 0 in case of a Read Request.
To require to adopt a specific fixed value for the timeout PICO$\_$TFTP$\_$OPTION$\_$TIME must be used with a value ranging between 1 and 255. If this option is set to a value of 0 (or not used at all) an adaptive timeout algorithm will take care of the retransmissions.
\subsection*{Function prototype}
\begin{verbatim}
int pico_tftp_set_option(struct pico_tftp_session *session,
uint8_t type, int32_t value);
\end{verbatim}
\subsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{session} - Section handler to use for the file transfer.
\item \texttt{type} - Option to set; accepted values are PICO$\_$TFTP$\_$OPTION$\_$FILE for Transfer size Option or PICO$\_$TFTP$\_$OPTION$\_$TIME for Timeout interval Option.
\item \texttt{value} - Option value to send.
\end{itemize}
\subsubsection*{Return value}
This function returns 0 if succeeds or -1 in case of errors (pico$\_$err is set accordingly).
\subsection*{Example}
\begin{verbatim}
filesize = get_filesize(commands->filename);
if (filesize < 0) {
fprintf(stderr, "TFTP: unable to read size of file %s\n",
commands->filename);
exit(3);
}
pico_tftp_set_option(session, PICO_TFTP_OPTION_FILE, filesize);
start_tx(session, commands->filename, short_be(PICO_TFTP_PORT),
cb_tftp_tx_opt, note);
\end{verbatim}
\subsection{pico\_tftp\_get\_option}
\subsection*{Description}
This function is used to retrieve the values of Extended Options that has been set to a session according to RFC 2347 and RFC 2349.
In order to ask Transfer size Option value PICO$\_$TFTP$\_$OPTION$\_$FILE must be used; it may be used for example for example in receiver callback for calculation of remaining bytes to be received to complete the current transfer.
To query the timeout PICO$\_$TFTP$\_$OPTION$\_$TIME must be used; a value ranging between 1 and 255 will be returned in the value parameter if the fixed interval is in place. If the call return -1 and pico$\_$err is set to PICO$\_$ERR$\_$ENOENT the adaptive timeout algorithm is running.
\subsection*{Function prototype}
\begin{verbatim}
int pico_tftp_set_option(struct pico_tftp_session *session,
uint8_t type, int32_t *value);
\end{verbatim}
\subsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{session} - Section handler to use for the file transfer.
\item \texttt{type} - Option to query; accepted values are PICO$\_$TFTP$\_$OPTION$\_$FILE for Transfer size Option or PICO$\_$TFTP$\_$OPTION$\_$TIME for Timeout interval Option.
\item \texttt{value} - Pointer to an integer variable where to store the value.
\end{itemize}
\subsubsection*{Return value}
This function returns 0 if succeeds or -1 in case of errors (pico$\_$err is set accordingly).
\subsection*{Example}
\begin{verbatim}
int cb_tftp_tx_opt(struct pico_tftp_session *session, uint16_t event,
uint8_t *block, int32_t len, void *arg)
{
int ret;
int32_t filesize;
if (event == PICO_TFTP_EV_OPT) {
ret = pico_tftp_get_option(session, PICO_TFTP_OPTION_FILE, &filesize);
if (ret)
printf("TFTP: Option filesize is not used\n");
else
printf("TFTP: We expect to transmit %" PRId32 " bytes\n",
filesize);
event = PICO_TFTP_EV_OK;
}
return cb_tftp_tx(session, event, block, len, arg);
}
\end{verbatim}
\subsection{pico\_tftp\_parse\_request\_args}
\subsection*{Description}
This function is used to extract Extension Options eventually present in Read or Write request (in the listen callback) or in Option ACKnowledge messages (in transmitter or receiver callback when event is equal to PICO$\_$TFTP$\_$EV$\_$OPT).
Note that timeout and filesize are modified only if the corresponding option is found in the received message.
\subsection*{Function prototype}
\begin{verbatim}
int pico_tftp_parse_request_args(char *args, int32_t len, int *options,
uint8_t *timeout, int32_t *filesize);
\end{verbatim}
\subsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{args} - Pointer to the buffer containing the arguments: filename for listen callback and block for rx or tx callback.
\item \texttt{len} - Length of the buffer containing the arguments; same value of the len parameter in callbacks.
\item \texttt{options} - Pointer to the variable that will contain the set of options found. Presence of single options can be then verified anding it with PICO$\_$TFTP$\_$OPTION$\_$FILE or PICO$\_$TFTP$\_$OPTION$\_$TIME.
\item \texttt{timeout} - Pointer to the variable that will contain the timeout value (if present in the options).
\item \texttt{filesize} - Pointer to the variable that will contain the filesize value (if present in the options)..
\end{itemize}
\subsubsection*{Return value}
This function returns 0 if succeeds or -1 in case of errors (pico$\_$err is set accordingly).
\subsection*{Example}
\begin{verbatim}
void tftp_listen_cb_opt(union pico_address *addr, uint16_t port,
uint16_t opcode, char *filename, int32_t len)
{
struct note_t *note;
struct pico_tftp_session *session;
int options;
uint8_t timeout;
int32_t filesize;
int ret;
printf("TFTP listen callback (OPTIONS) from remote port %" PRIu16 ".\n",
short_be(port));
/* declare the options we want to support */
ret = pico_tftp_parse_request_args(filename, len, &options,
&timeout, &filesize);
if (ret)
pico_tftp_reject_request(addr, port, TFTP_ERR_EOPT,
"Malformed request");
if (opcode == PICO_TFTP_RRQ) {
printf("Received TFTP get request for %s\n", filename);
note = transfer_prepare(&session, 'T', filename, addr, family);
if (options & PICO_TFTP_OPTION_TIME)
pico_tftp_set_option(session, PICO_TFTP_OPTION_TIME, timeout);
if (options & PICO_TFTP_OPTION_FILE) {
ret = get_filesize(filename);
if (ret < 0) {
pico_tftp_reject_request(addr, port, TFTP_ERR_ENOENT,
"File not found");
return;
}
pico_tftp_set_option(session, PICO_TFTP_OPTION_FILE, ret);
}
start_tx(session, filename, port, cb_tftp_tx_opt, note);
} else { /* opcode == PICO_TFTP_WRQ */
printf("Received TFTP put request for %s\n", filename);
note = transfer_prepare(&session, 'R', filename, addr, family);
if (options & PICO_TFTP_OPTION_TIME)
pico_tftp_set_option(session, PICO_TFTP_OPTION_TIME, timeout);
if (options & PICO_TFTP_OPTION_FILE)
pico_tftp_set_option(session, PICO_TFTP_OPTION_FILE, filesize);
start_rx(session, filename, port, cb_tftp_rx_opt, note);
}
}
\end{verbatim}
\subsection{pico\_tftp\_start\_tx}
\subsubsection*{Description}
Start a TFTP transfer. The action can be unsolicited (client PUT operation) or solicited (server responding to a GET request).
In either case, the transfer will happen one block at a time, and the callback provided by the user will be called to notify the acknowledgement for the successful of each transfer, transfer of the last block, reception of an option acknowledge message (client mode) or whenever an error occurs. Any error during the TFTP transfer will cancel the transfer itself.
The possible values for the \texttt{event} variable in callback are:
\begin{itemize}[noitemsep]
\item \texttt{PICO$\_$TFTP$\_$EV$\_$OK} Time to send another chunk of data.
\item \texttt{PICO$\_$TFTP$\_$EV$\_$OPT} Option acknowledge has been received.
\item \texttt{PICO$\_$TFTP$\_$EV$\_$ERR$\_$PEER} An error has occurred remotely.
\item \texttt{PICO$\_$TFTP$\_$EV$\_$ERR$\_$LOCAL} An internal error has occurred.
\end{itemize}
\subsubsection*{Function prototype}
\begin{verbatim}
int pico_tftp_start_tx(struct pico_tftp_session *session, uint16_t port,
const char *filename,
int (*user_cb)(struct pico_tftp_session *session, uint16_t event,
uint8_t *block, int32_t len, void *arg),
void *arg);
\end{verbatim}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{session} - Session handler to use for the file transfer.
\item \texttt{port} - The port on the remote peer.
\item \texttt{filename} - The name of the file to be transferred. In case of solicited transfer, it must match the filename provided during the request.
\item \texttt{user$\_$cb} - The callback provided by the user to be called upon each block transfer, option acknowledge or in case of error.
\item \texttt{arg} - The pointer is sent as argument to the callback.
\end{itemize}
\subsubsection*{Return value}
This function returns 0 if succeeds or -1 in case of errors (pico$\_$err is set accordingly).
\subsubsection*{Example}
\begin{verbatim}
void start_tx(struct pico_tftp_session *session,
const char *filename, uint16_t port,
int (*tx_callback)(struct pico_tftp_session *session, uint16_t err,
uint8_t *block, int32_t len, void *arg),
struct note_t *note)
{
if (pico_tftp_start_tx(session, port, filename, tx_callback, note)) {
fprintf(stderr, "TFTP: Error in initialization\n");
exit(1);
}
}
\end{verbatim}
\subsection{pico\_tftp\_send}
\subsubsection*{Description}
Send the next block during an active TFTP transfer. This is ideally called every time the user callback is triggered by the protocol, indicating that the transfer of the last block has been acknowledged. The user should not call this function unless it's solicited by the protocol during an active transmit session.
\subsubsection*{Function prototype}
\begin{verbatim}
int32_t pico_tftp_send(struct pico_tftp_session *session,
const uint8_t *data, int32_t len);
\end{verbatim}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{session} - the session handler to use for the file transfer.
\item \texttt{data} - the content of the block to be transferred.
\item \texttt{len} - the size of the buffer being transmitted. If $<$ \texttt{BLOCKSIZE}, the transfer is concluded. In order to terminate a transfer where the content is aligned to \texttt{BLOCKSIZE}, a zero-sized \texttt{pico$\_$tftp$\_$send} must be called at the end of the transfer.
\end{itemize}
\subsubsection*{Return value}
In case of success, the number of bytes transmitted is returned. In case of failure, -1 is returned and pico$\_$err is set accordingly.
\subsubsection*{Example}
\begin{verbatim}
int cb_tftp_tx(struct pico_tftp_session *session, uint16_t event,
uint8_t *block, int32_t len, void *arg)
{
struct note_t *note = (struct note_t *) arg;
if (event != PICO_TFTP_EV_OK) {
fprintf(stderr, "TFTP: Error %" PRIu16 ": %s\n", event, block);
exit(1);
}
len = read(note->fd, tftp_txbuf, PICO_TFTP_PAYLOAD_SIZE);
if (len >= 0) {
note->filesize += len;
pico_tftp_send(session, tftp_txbuf, len);
if (len < PICO_TFTP_PAYLOAD_SIZE) {
printf("TFTP: file %s (%" PRId32
" bytes) TX transfer complete!\n",
note->filename, note->filesize);
close(note->fd);
del_note(note);
}
} else {
perror("read");
fprintf(stderr,
"Filesystem error reading file %s,"
" cancelling current transfer\n", note->filename);
pico_tftp_abort(session, TFTP_ERR_EACC, "Error on read");
del_note(note);
}
if (!clipboard)
pico_timer_add(3000, deferred_exit, NULL);
return len;
}
\end{verbatim}
\subsection{pico\_tftp\_start\_rx}
\subsubsection*{Description}
Start a TFTP transfer. The action can be unsolicited (client GET operation) or solicited (server responding to a PUT request).
In either case, the transfer will happen one block at a time, and the callback provided by the user will be called upon successful transfer of a block, whose content can be directly accessed via the \texttt{block} field, reception of an option acknowledge messagge (client mode) or whenever an error occurs.
The possible values for the \texttt{event} variable in callback are:
\begin{itemize}[noitemsep]
\item \texttt{PICO$\_$TFTP$\_$EV$\_$OK} Previously sent block has been acknowledge.
\item \texttt{PICO$\_$TFTP$\_$EV$\_$OPT} Option acknowledge has been received.
\item \texttt{PICO$\_$TFTP$\_$EV$\_$ERR$\_$PEER} An error has occurrend remotely.
\item \texttt{PICO$\_$TFTP$\_$EV$\_$ERR$\_$LOCAL} An internal error has occurred.
\end{itemize}
\subsubsection*{Function prototype}
\begin{verbatim}
int pico_tftp_start_rx(struct pico_tftp_session *session, uint16_t port,
const char *filename,
int (*user_cb)(struct pico_tftp_session *session, uint16_t event,
uint8_t *block, int32_t len, void *arg),
void *arg);
\end{verbatim}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{session} - the session handler to use for the file transfer.
\item \texttt{port} - The port on the remote peer.
\item \texttt{filename} - The name of the file to be transfered. In case of solicited transfer, it must match the filename provided during the request.
\item \texttt{user$\_$cb} - The callback provided by the user to be called upon each block transfer, option acknowledge or in case of error. This is the callback where the incoming data is processed. When len is less than the block size, the transfer is over.
\item \texttt{arg} - The pointer sent as argument to the callback.
\end{itemize}
\subsubsection*{Return value}
This function returns 0 if succeeds or -1 in case of errors (pico$\_$err is set accordingly).
\subsubsection*{Example}
\begin{verbatim}
void start_rx(struct pico_tftp_session *session,
const char *filename, uint16_t port,
int (*rx_callback)(struct pico_tftp_session *session, uint16_t err,
uint8_t *block, int32_t len, void *arg),
struct note_t *note)
{
if (pico_tftp_start_rx(session, port, filename, rx_callback, note)) {
fprintf(stderr, "TFTP: Error in initialization\n");
exit(1);
}
}
\end{verbatim}
\subsection{pico\_tftp\_get\_file\_size}
\subsection*{Description}
This function is used to retrieve the file size (if transmitted by the remote or set as session option). It is equivalent to a call to pico$\_$tftp$\_$get$\_$option(session, PICO$\_$TFTP$\_$OPTION$\_$FILE, $\&$file$\_$size);
\subsection*{Function prototype}
\begin{verbatim}
int pico_tftp_get_file_size(struct pico_tftp_session *session,
int32_t *file_size);
\end{verbatim}
\subsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{session} - Section handler to use for the file transfer.
\item \texttt{file$\_$size} - Pointer to an integer variable where to store the value.
\end{itemize}
\subsubsection*{Return value}
This function returns 0 if succeeds or -1 in case of errors (pico$\_$err is set accordingly).
\subsection*{Example}
\begin{verbatim}
ret = pico_tftp_get_file_size(session, &file_size);
if (ret)
printf("Information about file size has not been received"\n);
\end{verbatim}
\subsection{pico\_tftp\_abort}
\subsubsection*{Description}
When called this function aborts associated ongoing transmission and notifying the other endpoint with a proper error message. After a call to this function the session is closed automatically.
\subsubsection*{Function prototype}
\begin{verbatim}
int pico_tftp_abort(struct pico_tftp_session *session,
uint16_t error, const char *reason);
\end{verbatim}
\subsubsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{session} - the session handler related to the session to abort.
\item \texttt{error} - Error reason code, possible values are:
\begin{tabular}{ll}
TFTP$\_$ERR$\_$UNDEF & Not defined, see error message (if any) \\
TFTP$\_$ERR$\_$ENOENT & File not found \\
TFTP$\_$ERR$\_$EACC & Access violation \\
TFTP$\_$ERR$\_$EXCEEDED & Disk full or allocation exceeded \\
TFTP$\_$ERR$\_$EILL & Illegal TFTP operation \\
TFTP$\_$ERR$\_$ETID & Unknown transfer ID \\
TFTP$\_$ERR$\_$EEXIST & File already exists \\
TFTP$\_$ERR$\_$EUSR & No such user \\
TFTP$\_$ERR$\_$EOPT & Option negotiation \\
\end{tabular}
\item \texttt{reason} - Text message to attach.
\end{itemize}
\subsubsection*{Return value}
This function returns 0 if succeeds or -1 in case of errors (pico$\_$err is set accordingly).
\subsection*{Example}
\begin{verbatim}
int cb_tftp_rx(struct pico_tftp_session *session, uint16_t event,
uint8_t *block, int32_t len, void *arg)
{
struct note_t *note = (struct note_t *) arg;
int ret;
if (event != PICO_TFTP_EV_OK) {
fprintf(stderr, "TFTP: Error %" PRIu16 ": %s\n", event, block);
exit(1);
}
note->filesize += len;
if (write(note->fd, block, len) < 0) {
perror("write");
fprintf(stderr, "Filesystem error writing file %s,"
" cancelling current transfer\n", note->filename);
pico_tftp_abort(session, TFTP_ERR_EACC, "Error on write");
del_note(note);
} else {
if (len != PICO_TFTP_PAYLOAD_SIZE) {
printf("TFTP: file %s (%" PRId32
" bytes) RX transfer complete!\n",
note->filename, note->filesize);
close(note->fd);
del_note(note);
}
}
if (!clipboard)
pico_timer_add(3000, deferred_exit, NULL);
return len;
}
\end{verbatim}
\subsection{pico\_tftp\_close\_server}
\subsection*{Description}
This function is used to shutdown the TFTP server.
\subsection*{Function prototype}
\begin{verbatim}
int pico_tftp_close_server(void);
\end{verbatim}
\subsubsection*{Return value}
This function returns 0 if succeeds or -1 in case of errors (pico$\_$err is set accordingly).
\subsection*{Example}
\begin{verbatim}
ret = pico_tftp_close_server();
if (ret)
printf(stderr, "Failure shutting down the server\n");
\end{verbatim}
\subsection{pico\_tftp\_app\_setup}
\subsection*{Description}
Obtain a session handler to use for the next file transfer with a remote location in application driven mode.
\subsection*{Function prototype}
\begin{verbatim}
struct pico_tftp_session * pico_tftp_app_setup(union pico_address *a,
uint16_t port, uint16_t family, int *synchro);
\end{verbatim}
\subsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{a} - The address of the peer to be contacted. In case of a solicited transfer, it must match the address where the request came from.
\item \texttt{port} - The port on the remote peer.
\item \texttt{family} - The chosen socket family. Accepted values are \texttt{PICO$\_$PROTO$\_$IPV4} for IPv4 and \texttt{PICO$\_$PROTO$\_$IPV6} for IPv6.
\item \texttt{synchro} - Variable to handle the synchronization.
\end{itemize}
\subsubsection*{Return value}
In case of success a session handler is returned. In case of failure, NULL is returned and pico$\_$err is set accordingly.
\subsection*{Example}
\begin{verbatim}
session = pico_tftp_app_setup(&server_address, short_be(PICO_TFTP_PORT),
PICO_PROTO_IPV4, &synchro);
if (!session) {
fprintf(stderr, "Error in pico_tftp_app_setup\n");
exit(1);
}
\end{verbatim}
\subsection{pico\_tftp\_app\_start\_rx}
\subsection*{Description}
Application driven function used to request to read a remote file. The transfer will happen one block at a time using pico$\_$tftp$\_$app$\_$get.
\subsection*{Function prototype}
\begin{verbatim}
int pico_tftp_app_start_rx(struct pico_tftp_session *session,
const char *filename);
\end{verbatim}
\subsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{session} - Session handler to use for the file transfer.
\item \texttt{filename} - The name of the file to be received.
\end{itemize}
\subsubsection*{Return value}
This function returns 0 if succeeds or -1 in case of errors (pico$\_$err is set accordingly).
\subsection*{Example}
\begin{verbatim}
printf("Start receiving file %s with options set to %d\n", filename, options);
if (options) {
ret = pico_tftp_set_option(session, PICO_TFTP_OPTION_FILE, 0);
if (ret) {
fprintf(stderr, "Error in pico_tftp_set_option\n");
exit(1);
}
}
ret = pico_tftp_app_start_rx(session, filename);
if (ret) {
fprintf(stderr, "Error in pico_tftp_app_start_rx\n");
exit(1);
}
\end{verbatim}
\subsection{pico\_tftp\_app\_start\_tx}
\subsection*{Description}
Application driven function used to request to write a remote file. The transfer will happen one block at a time using pico$\_$tftp$\_$app$\_$put.
\subsection*{Function prototype}
\begin{verbatim}
int pico_tftp_app_start_tx(struct pico_tftp_session *session,
const char *filename);
\end{verbatim}
\subsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{session} - Session handler to use for the file transfer.
\item \texttt{filename} - The name of the file to be sent.
\end{itemize}
\subsubsection*{Return value}
This function returns 0 if succeeds or -1 in case of errors (pico$\_$err is set accordingly).
\subsection*{Example}
\begin{verbatim}
printf("Start sending file %s with options set to %d\n", filename, options);
if (options) {
ret = get_filesize(filename);
if (ret < 0) {
fprintf(stderr, "Error in get_filesize\n");
exit(1);
}
ret = pico_tftp_set_option(session, PICO_TFTP_OPTION_FILE, ret);
if (ret) {
fprintf(stderr, "Error in pico_tftp_set_option\n");
exit(1);
}
}
ret = pico_tftp_app_start_tx(session, filename);
if (ret) {
fprintf(stderr, "Error in pico_tftp_app_start_rx\n");
exit(1);
}
\end{verbatim}
\subsection{pico\_tftp\_get}
\subsection*{Description}
Read the next block during an active TFTP transfer. The len field must always be equal to PICO$\_$TFTP$\_$PAYLOAD$\_$SIZE. Once the file has been sent or after an error the session is no more valid.
\subsection*{Function prototype}
\begin{verbatim}
int32_t pico_tftp_get(struct pico_tftp_session *session,
uint8_t *data, int32_t len);
\end{verbatim}
\subsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{session} - Session handler to use for the file transfer.
\item \texttt{data} - Buffer where to store the acquired payload.
\item \texttt{len} - Length of the buffer size to receive; it is equal to the fixed chunk size.
\end{itemize}
\subsubsection*{Return value}
This function returns the number of received bytes of payload (0 included) if succeeds. In case of error a negative number is returned.
\subsubsection*{Errors}
\begin{itemize}[noitemsep]
\item \texttt{-1} At least one of the passed arguments are invalid.
\item \texttt{-PICO$\_$TFTP$\_$EV$\_$ERR$\_$PEER} Remote failure.
\item \texttt{-PICO$\_$TFTP$\_$EV$\_$ERR$\_$LOCAL} Local failure.
\end{itemize}
\subsection*{Example}
\begin{verbatim}
for(;left; left -= countdown) {
usleep(2000); //PICO_IDLE();
pico_stack_tick();
if (countdown)
continue;
if (*synchro) {
len = pico_tftp_get(session, buf, PICO_TFTP_PAYLOAD_SIZE);
if (len < 0) {
fprintf(stderr, "Failure in pico_tftp_get\n");
close(fd);
countdown = 1;
continue;
}
ret = write(fd, buf, len);
if (ret < 0) {
fprintf(stderr, "Error in write\n");
pico_tftp_abort(session, TFTP_ERR_EXCEEDED, "File write error");
close(fd);
countdown = 1;
continue;
}
printf("Written %" PRId32 " bytes to file (synchro=%d)\n",
len, *synchro);
if (len != PICO_TFTP_PAYLOAD_SIZE) {
close(fd);
printf("Transfer complete!\n");
countdown = 1;
}
}
}
\end{verbatim}
\subsection{pico\_tftp\_put}
\subsection*{Description}
Send the next block during an active TFTP transfer. The len field, with the exception of last invocation must always be equal to PICO$\_$TFTP$\_$PAYLOAD$\_$SIZE. Once the file has been sent or after an error the session is no more valid.
\subsection*{Function prototype}
\begin{verbatim}
int32_t pico_tftp_put(struct pico_tftp_session *session,
uint8_t *data, int32_t len);
\end{verbatim}
\subsection*{Parameters}
\begin{itemize}[noitemsep]
\item \texttt{session} - Session handler to use for the file transfer.
\item \texttt{data} - Pointer to the data to be transmitted.
\item \texttt{len} - Length of the buffer size to transmit; last chunk must be $<$ of the maximum buffer size (0 if file size was a multiple of maximum buffer size).
\end{itemize}
\subsubsection*{Return value}
This function returns the number of transmitted payload data (len) if succeeds. In case of error a negative number is returned.
\subsubsection*{Errors}
\begin{itemize}[noitemsep]
\item \texttt{-1} At least one of the passed arguments are invalid.
\item \texttt{-PICO$\_$TFTP$\_$EV$\_$ERR$\_$PEER} Remote failure.
\item \texttt{-PICO$\_$TFTP$\_$EV$\_$ERR$\_$LOCAL} Local failure.
\end{itemize}
\subsection*{Example}
\begin{verbatim}
for(;left; left -= countdown) {
usleep(2000); //PICO_IDLE();
pico_stack_tick();
if (countdown)
continue;
if (*synchro) {
ret = read(fd, buf, PICO_TFTP_PAYLOAD_SIZE);
if (ret < 0) {
fprintf(stderr, "Error in read\n");
pico_tftp_abort(session, TFTP_ERR_EACC, "File read error");
close(fd);
countdown = 1;
continue;
}
printf("Read %" PRId32 " bytes from file (synchro=%d)\n",
len, *synchro);
len = pico_tftp_put(session, buf, ret);
if (len < 0) {
fprintf(stderr, "Failure in pico_tftp_put\n");
close(fd);
countdown = 1;
continue;
}
if (len != PICO_TFTP_PAYLOAD_SIZE) {
close(fd);
printf("Transfer complete!\n");
countdown = 1;
}
}
}
\end{verbatim}

View File

@ -0,0 +1,11 @@
Unless you have received a written document by PicoTCP copyright holders stating otherwise,
the software described in this document is distributed under the terms of the GNU General
Public License version 2 only.
The terms of the license are reported below.
\begin{center}
{\bf\large GNU General Public license}
{\bf Version 2, June 1991}
\end{center}
\input {gpl-2.0}

View File

@ -0,0 +1,68 @@
PicoTCP is a complete TCP/IP stack, intended for embedded devices and
designed to run on different architectures and networking
hardware. The architecture of the stack allows easy selection of the features
needed for any particular use, taking into account the sizing and
the performance of the platform on which the code is to run.
Even if it is designed
to allow for size and performance constraints, the chosen approach is to
comply with the latest standards in the telecommunications research, including
the latest proposals, in order to achieve the highest standards for
today's inter-networking communications. PicoTCP is distributed as
a library to be integrated with application and form a combination for
any hardware-specific firmware.
The main characteristics of the library are the following:
\begin{itemize}
\item \textbf{Modularity} Each component of the stack is deployed in a
separate module, allowing the selection at compile time of the components needed to
be included for any specific platform, depending on the particular use case.
We know that saving memory and resources is often mission-critical for a
project, and therefore PicoTCP is fully focussed on saving
up to the last byte of memory.
\item \textbf{Code Quality} Every component added to the
stack must pass a complete set of validation tests. Before new code can be
introduced it is scanned and proof-checked by three separate levels of
quality enforcement. The process related to the validation of the code is
one of the major tasks of the engineering team. In the top-down approach of the design, a
new module has to pass the review of our senior architects, to have it comply
with the general guidelines. The development of the smaller
components is done in a test-driven way, providing a specific unit test for each function call.
Finally, functional non-regression tests are performed
after the feature development is complete, and all the tests are automatically
scheduled to run several times per day to check for functional regressions.
\item \textbf{Adherence to the standards} The protocols
included in the stack are done following stepare designed by following meticulously the guidelines
provided by the International Engineering Task Force (IETF) with regards to
inter-networking communication. A strong adherence to the standards guarantees a
smooth integration with all the existing TCP/IP stacks, when communicating
with both other embedded devices and with the PC/server world.
\item \textbf{Features} A fully-featured protocol implementation including all those non-mandatory
features means better data-transfer performances, coverage of rare/unique
network scenarios and topologies and a better integration with all types of
networking hardware devices.
\item \textbf{Transparency} The availability of the source code to the Free
Software community is an important added value of PicoTCP.
%Our programmers
%are proud of the aestethic of their code, and they show it with no
%hesitation to the attention of the rest of the world.
The constant peer reviews and constructive comments on the
design and the development choices that PicoTCP receives from the academic world
and from several hundreds of hobbyists and professionals who read the code,
are an essential element in the quality build-up of the product.
%PicoTCP constantly receives peer-reviews and constructive comments on the
%design and the development choices from the academic world and from several
%hundreds of hobbists and professionals who read the code.
%We strongly
%believe that software is not about keeping things secret: whenever one is
%convinced by the quality of their work, there is absolutely nothing to hide.
\item \textbf{Simplicity} The APIs provided to access the library
facilities, both from the applications as well as from the device drivers, are
small and well documented. This concurs with the goal of the library to facilitate
the integration with the surroundings and minimize the time used to combine
the stack with existing code. The support required to port to a new
architecture is so small it is reduced to a set of macros defined in a
header file specific for the platform.
\end{itemize}

View File

@ -0,0 +1,187 @@
\begin{longtable}{ | l | p{15cm} | }
\hline
{\bf RFC} &
{\bf Description} \\ \hline
RFC 768 &
User Datagram Protocol (UDP) \\ \hline
RFC 791 &
Internet Protocol (IP) \\ \hline
RFC 792 &
Internet Control Message Protocol (ICMP) \\ \hline
RFC 793 &
Transmission Control Protocol (TCP) \\ \hline
RFC 816 &
Fault Isolation and Recovery \\ \hline
RFC 826 &
Address Resolution Protocol (ARP) \\ \hline
RFC 879 &
The TCP Maximum Segment Size and Related Topics \\ \hline
RFC 894 &
IP over Ethernet \\ \hline
RFC 896 &
Congestion Control in IP/TCP Internetworks \\ \hline
RFC 919 &
Broadcasting Internet Datagrams \\ \hline
RFC 922 &
Broadcasting Internet Datagrams in the Presence of Subnets \\ \hline
RFC 950 &
Internet Standard Subnetting Procedure \\ \hline
RFC 1009 &
Requirements for Internet Gateways \\ \hline
RFC 1034 &
Domain NamesConcepts and Facilities \\ \hline
RFC 1035 &
Domain NamesImplementation and Specification \\ \hline
RFC 1071 &
Computing the Internet Checksum \\ \hline
RFC 1112 &
Internet Group Management Protocol (IGMP) \\ \hline
RFC 1122 &
Requirements for Internet HostsCommunication Layers \\ \hline
RFC 1123 &
Requirements for Internet Hosts - Application and Support (\textsuperscript{1}) \\ \hline
RFC 1191 &
Path MTU Discovery (\textsuperscript{1})\\ \hline
RFC 1323 &
TCP Extensions for High Performance \\ \hline
RFC 1332 &
The PPP Internet Protocol Control Protocol (IPCP) \\ \hline
RFC 1334 &
PPP Authentication Protocols \\ \hline
RFC 1337 &
TIME-WAIT Assassination Hazards in TCP \\ \hline
RFC 1350 &
The TFTP Protocol (Revision 2) \\ \hline
RFC 1534 &
Interoperation Between DHCP and BOOTP \\ \hline
RFC 1542 &
Clarifications and Extensions for the Bootstrap Protocol \\ \hline
RFC 1661 &
The Point-to-Point Protocol (PPP) \\ \hline
RFC 1662 &
PPP in HDLC-like Framing \\ \hline
RFC 1812 &
Requirements for IP Version 4 Routers \\ \hline
RFC 1878 &
Variable Length Subnet Table For IPv4 \\ \hline
RFC 1886 &
DNS Extensions to Support IP Version 6 (\textsuperscript{1}) \\ \hline
RFC 1994 &
PPP Challenge Handshake Authentication Protocol (CHAP) \\ \hline
RFC 2018 &
TCP Selective Acknowledgment Options \\ \hline
RFC 2131 &
Dynamic Host Configuration Protocol (DHCP) \\ \hline
RFC 2132 &
DHCP Options and BOOTP Vendor Extensions \\ \hline
RFC 2236 &
Internet Group Management Protocol, Version 2 \\ \hline
RFC2347 &
TFTP Option Extension \\ \hline
RFC 2349 &
TFTP Timeout Interval and Transfer Size Options \\ \hline
RFC 2460 &
Internet Protocol, Version 6 (IPv6) Specification \\ \hline
RFC 2581 &
TCP Congestion Control \\ \hline
RFC 2663 &
IP Network Address Translator (NAT) Terminology and Considerations \\ \hline
RFC 2710 &
Multicast Listener Discovery (MLD) for IPv6 \\ \hline
RFC 3042 &
Enhancing TCP's Loss Recovery Using Limited Transmit \\ \hline
RFC 3315 &
Dynamic Host Configuration Protocol for IPv6 (DHCPv6) (\textsuperscript{1}) \\ \hline
RFC 3376 &
Internet Group Management Protocol, Version 3 \\ \hline
RFC 3517 &
A Conservative Selective Acknowledgment (SACK)-based Loss Recovery Algorithm for TCP \\ \hline
RFC 3561 &
Ad-hoc On-Demand Distance Vector (AODV) Routing \\ \hline
RFC 3626 &
Optimized Link State Routing Protocol (OLSR) \\ \hline
RFC 3782 &
The NewReno Modification to TCP's Fast Recovery Algorithm \\ \hline
RFC 3810 &
Multicast Listener Discovery Version 2 (MLDv2) for IPv6 \\ \hline
RFC 3927 &
Dynamic Configuration of IPv4 Link-Local Addresses \\ \hline
RFC 4291 &
IP Version 6 Addressing Architecture \\ \hline
RFC 4443 &
Internet Control Message Protocol (ICMPv6) for the Internet Protocol Version 6 (IPv6) Specification \\ \hline
RFC 4861 &
Neighbor Discovery for IP version 6 (IPv6) \\ \hline
RFC 4862 &
IPv6 Stateless Address Autoconfiguration \\ \hline
RFC 6691 &
TCP Options and Maximum Segment Size (MSS) \\ \hline
RFC 6762 &
Multicast DNS \\ \hline
RFC 6763 &
DNS-based Service Discovery \\ \hline
\end{longtable}
(\textsuperscript{1}) Work in progress
(\textsuperscript{2}) Experimental

View File

@ -0,0 +1,71 @@
%Thesistemplate LaTeX De Nayer 2008-2009
%Stefan Bouwens, Dave Geeradyn & Toon Goedem\'e
%PACKAGES
%\usepackage{times}
%\usepackage[dvips]{graphicx}
\usepackage{url}
\usepackage[english,dutch]{babel}
\usepackage[T1]{fontenc}
\usepackage[all]{xy}
\usepackage{amssymb}
%\usepackage[breaklinks=true, bookmarksopen=true]{hyperref}
\usepackage[small,bf,hang]{caption}
\renewcommand{\captionfont}{\small\itshape}
\usepackage{natbib}
\bibpunct{(}{)}{;}{a}{,}{,}
\usepackage{listings}
\lstloadlanguages{[visual]c++}
\lstset{ basicstyle=\small,
basicstyle=\ttfamily,
numbers=left, numberstyle=\tiny, stepnumber=1, numbersep=5pt,
tabsize=3,
keywordstyle=\color{black}\bfseries,
commentstyle=\color{gray}\itshape,
frame=single,
breaklines=true
}
%LAYOUT
%\bibliographystyle{agsm}
\setcounter{secnumdepth}{3}
\setcounter{tocdepth}{3}
\setlength{\textheight}{237mm}
\setlength{\textwidth}{160mm}
%\setlength{\columnsep}{0.3125in}
\setlength{\topmargin}{-0.54cm}
\setlength{\headheight}{15pt}
%\setlength{\headsep}{0in}
%\setlength{\parindent}{1pc}
\setlength{\oddsidemargin}{0.46cm} % Centers text.
\setlength{\evensidemargin}{-.54cm}
%
%Linkermarge 30 mm, rechtermarge 20 mm, bovenmarge 20 mm, ondermarge 20 mm.
%2,54
\usepackage{fancyhdr}
\pagestyle{fancy}
% with this we ensure that the chapter and section
% headings are in lowercase.
\renewcommand{\chaptermark}[1]{%
\markboth{#1}{}}
\renewcommand{\sectionmark}[1]{%
\markright{\thesection\ #1}}
\fancyhf{} % delete current header and footer
\fancyhead[LE,RO]{\bfseries\thepage}
\fancyhead[LO]{\bfseries\rightmark}
\fancyhead[RE]{\bfseries\leftmark}
\renewcommand{\headrulewidth}{0.5pt}
\renewcommand{\footrulewidth}{0pt}
\addtolength{\headheight}{0.5pt} % space for the rule
\fancypagestyle{plain}{%
\fancyhead{} % get rid of headers on plain pages
\renewcommand{\headrulewidth}{0pt} % and the line
}
\parskip 6pt % sets spacing between paragraphs
\parindent 0pt % sets leading space for paragraphs

View File

@ -0,0 +1,27 @@
% Altran Intelligent Systems
%
% LAYOUT TEXT
% ===========
%\documentclass[11pt, a4paper, openright,oneside]{book}
\documentclass[11pt, a4paper,oneside]{report}
\usepackage[english]{babel}
\usepackage[latin1]{inputenc}
%\usepackage[T1]{fontenc}
\usepackage{graphicx}
\usepackage{natbib}
%\usepackage{hyperref}
\usepackage[hang,flushmargin]{footmisc}
\usepackage{fullpage}
\parskip 4pt % sets spacing between paragraphs
\parindent 0pt % sets leading space for paragraphs
\makeatletter
\renewcommand{\@makechapterhead}[1]{%
%\vspace*{50 pt}%
{\setlength{\parindent}{0pt} \raggedright \normalfont
\bfseries\Huge\thechapter.\ #1
\par\nobreak\vspace{40 pt}}}
\makeatother

View File

@ -0,0 +1,38 @@
\section{MODULE}
% Short description/overview of module functions
\subsection{FUNCTION}
\subsubsection*{Description}
\subsubsection*{Function prototype}
\subsubsection*{Parameters}
\subsubsection*{Return value}
\subsubsection*{Errors}
\subsubsection*{Example}
\subsection{FUNCTION}
\subsubsection*{Description}
\subsubsection*{Function prototype}
\subsubsection*{Parameters}
\subsubsection*{Return value}
\subsubsection*{Errors}
\subsubsection*{Example}
\subsection{FUNCTION}
% ...

View File

@ -0,0 +1,113 @@
% Altran NV
%
% PicoTCP User Documentation main file
% ====================================
%\documentclass[11pt, a4paper, openright]{paper}
\input{layout1}
% TEMPS
%\usepackage{tikz}
%\usepackage[latin1]{inputenc}
%\usepackage{graphicx}
%\usepackage[hang,flushmargin]{footmisc}
%\usepackage{pdfpages}
%\usepackage{tabularx}
%\usepackage{lscape}
%\usepackage{longtable}
%\usepackage{verbatim}
%\usepackage{moreverb}
%\usepackage{listings}
%\usepackage{draftcopy}
%\usepackage{hyperref}
\usepackage{longtable}
%% to print watermark
% \usepackage{draftwatermark}
% \SetWatermarkText{Altran ISY Confidential}
% \SetWatermarkScale{3}
% \SetWatermarkLightness{0.9}
% to adjust the space between titles and text
\usepackage[compact]{titlesec}
\titlespacing{\section}{0pt}{*5}{*2}
\titlespacing{\subsection}{0pt}{*4}{*1}
\titlespacing{\subsubsection}{0pt}{*1}{*0}
% to minimize space between list items
\usepackage{enumitem}
% To use hyperlinks
\usepackage{hyperref}
% limit toc depth until sections
\setcounter{tocdepth}{1}
\begin{document}
\title{picoTCP User Documentation}
\author{Copyright \copyright 2017 Altran Belgium NV. All right reserved.}
\maketitle
\date{\today}
\maketitle
\thispagestyle{empty}
Disclaimer
This document is distributed under the terms of Creative Commons CC BY-ND 3.0.
You are free to share unmodified copies of this document, as long as the copyright
statement is kept. Click \href{http://creativecommons.org/licenses/by-nd/3.0/} {here} to view the full license text.
\pagenumbering{arabic}
\selectlanguage{english}
\tableofcontents
%\chapter{Introduction}
%\label{chap:intro}
%\input{chap_intro}
\chapter{Overview}
\label{chap:overview}
\input{chap_overview}
\chapter{API Documentation}
\label{chap:api_doc}
The following sections will describe the API for picoTCP.
\input{chap_api_ipv4}
\input{chap_api_ipv6}
\input{chap_api_sock}
\input{chap_api_dhcp_c}
\input{chap_api_dhcp_d}
\input{chap_api_dns_c}
\input{chap_api_mdns}
\input{chap_api_dns_sd}
\input{chap_api_sntp_c}
\input{chap_api_igmp}
\input{chap_api_mld}
\input{chap_api_ipfilter}
\input{chap_api_slaacv4}
\input{chap_api_tftp}
\input{chap_api_ppp}
\input{chap_api_olsr}
\input{chap_api_aodv}
\appendix
% Do not include license
%\chapter{License}
%\label{chap:license}
%\input{chap_license}
\chapter{Supported RFCs}
\label{chap:rfcs}
\input{chap_rfcs}
\end{document}