\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}
