WIFI_API_20150524e

WIFI_Driver/nmc/socket_nmc.h

Committer:
Marcomissyou
Date:
2015-06-09
Revision:
0:a2de37bf5f3d

File content as of revision 0:a2de37bf5f3d:

/*
@file	
	socket.h

@brief	Socket Interface APIs

	The file defines APIs and types of socket layer for the NMC1500 IoT solution. 	The APIs 	are very similar 
	to the standard POSIX sockets APIs. The socket layer operates in asynchronus mode which means socket 
	functions are non-blocking functions, requiring the result of a socket operation (eg. bind) is delivered later
	in a callback function [APPSocketEventHandler](@ref APPSocketEventHandler).
*/
#ifndef __SOCKET_NMC_H__
#define __SOCKET_NMC_H__

#include "nmi_wlan_if.h"
#include "nmi_wlan.h"

#ifdef  __cplusplus
extern "C" {
#endif

/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
INCLUDES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/

//#include "common\include\nm_common.h"

#define NMI_API

/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
MACROS
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/


#define HOSTNAME_MAX_SIZE									64
/*< Maximum allowed size for a host domain name.
*/


	
#define SOCKET_BUFFER_MAX_LENGTH							1400
/*< Maximum allowed size for a socket Data buffer.
*/


#define  AF_INET											2
/*< Supported socket family. 
*/


#define  SOCK_STREAM										1
/*< This is the identifier of TCP socket type.
*/


#define  SOCK_DGRAM											2
/*< This is the identifier of UDP socket type.
*/


#define SOCKET_FLAGS_SSL									0x01
/*< This flag shall be passed to the 
	socket API for SSL session.
*/


#define TCP_SOCK_MAX										2//(7)
/*< Maximum number of simultaneous TCP sockets.
*/


#define UDP_SOCK_MAX										2//4
/*< Maximum number of simultaneous UDP sockets.
*/


#define MAX_SOCKET											(TCP_SOCK_MAX + UDP_SOCK_MAX)
/*< Maximum number of Sockets.
*/


/**************
Socket Errors
**************/

#define SOCK_ERR_NO_ERROR									0
/*< Every thing is OK.
*/


#define SOCK_ERR_INVALID_ADDRESS							-1
/*< Socket address is invalid. The socket operation cannot
	be completed without address is specified. For example,
	Bind is called without specifying a port number.
*/


#define SOCK_ERR_ADDR_ALREADY_IN_USE						-2
/*< Cannot bind on the given address. It is already bound
	by another opened socket.
*/


#define SOCK_ERR_MAX_TCP_SOCK								-3
/*< The maximum number of TCP sockets is reached. Socket
	creation failed.
*/


#define SOCK_ERR_MAX_UDP_SOCK								-4
/*< The maximum number of UDP sockets is reached. Socket
	creation failed.
*/


#define SOCK_ERR_INVALID_ARG								-6
/*< An invalid arguement is passed to a function.
*/


#define SOCK_ERR_MAX_LISTEN_SOCK							-7
/*< The maximum number of TCP passive listening sockets is
	reached. Listen function fails.
*/


#define SOCK_ERR_INVALID									-9
/*< The requested socket operation is not valid in the 
	current socket state. For Example, accept is called on a
	TCP socket before bind or listen.
*/


#define SOCK_ERR_ADDR_IS_REQUIRED							-11
/*< The socket address is required for the operation to 
	be completed. It is generated from sendto when there is
	no valid address found to send the data to.
*/


#define SOCK_ERR_CONN_ABORTED								-12
/*< The socket is closed by the peer. The local socket is 
	closed also.
*/


#define SOCK_ERR_TIMEOUT									-13
/*< The socket pending operation has been timedout. 
*/


#define SOCK_ERR_BUFFER_FULL								-14
/*< The send operation could not be performed before the 
	transmission buffer corresponding to this socket is busy.
*/

#ifndef _NM_BSP_BIG_END

#define _htonl(m)				(m)	
#define _htons(A)				(A)

#else

#define _htonl(m)		\
	(uint32)(((uint32)(m << 24)) | ((uint32)((m & 0x0000FF00) << 8)) | ((uint32)((m & 0x00FF0000) >> 8)) | ((uint32)(m >> 24)))
/*< Convert a 4-byte integer from the host representation to the Network byte order representation.
*/


#define _htons(A)   	(uint16)((((uint16) (A)) << 8) | (((uint16) (A)) >> 8))
/*< Convert a 2-byte integer (short) from the host representation to the Network byte order representation.
*/


#endif


#define _ntohl      		_htonl
/*< Convert a 4-byte integer from the Network byte order representation to the host representation .
*/


#define _ntohs      		_htons
/*< Convert a 2-byte integer from the Network byte order representation to the host representation .
*/


/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
DATA TYPES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/

/*
@typedef	\	
	SOCKET
	
@brief
	Data type definition for socket handlers.
*/
typedef sint8  SOCKET;


/*
@struct	\
	in_addr
	
@brief
	IPv4 address representation.
*/
typedef struct{
	uint32		s_addr;   
	/*< Network Byte Order representation of the IPv4 address.
	*/
}in_addr_nmc;//Tsungta


/*
@struct	\
	sockaddr
	
@brief
	Generic socket address structure.
*/
struct sockaddr{
    uint16		sa_family;
    uint8		sa_data[14];
};


/*
@struct	\
	sockaddr_in
	
@brief
	Socket address structure for IPV4 addresses.
*/
struct sockaddr_in_nmc{//Tsungta
	uint16			sin_family;            
	/*< The only supported value for this is AF_INET.
	*/
	uint16   		sin_port;              
	/*< Port number of the socket address. It must be set in the 
	Network Byte Order format (e.g. _htons(80)).
	*/
	in_addr_nmc			sin_addr;       //Tsungta
	/*< IP Address [in_addr].
	*/
	uint8			sin_zero[8];          
	/*< Dummy bytes.
	*/
};


/*******************************************
Specific Definitions for Asynchronous implementation
*******************************************/

/*
@enum	\
	tenuSocketCallbackMsgType
	
@brief
	Socket message types for socket callback notifications.
*/
typedef enum{
	SOCKET_MSG_BIND	= 1,
	SOCKET_MSG_LISTEN,
	SOCKET_MSG_DNS_RESOLVE,
	SOCKET_MSG_ACCEPT,
	SOCKET_MSG_CONNECT,
	SOCKET_MSG_RECV,
	SOCKET_MSG_SEND,
	SOCKET_MSG_SENDTO,
	SOCKET_MSG_RECVFROM,
	SOCKET_MSG_DHCP_OFFER,
	SOCKET_MSG_TCPERROR
}tenuSocketCallbackMsgType;

/*
@struct	\
	tstrSocketBindMsg
	
@brief	Socket bind status. 

	It is passed to the APPSocketEventHandler with SOCKET_MSG_BIND message type 
	in a response to a user call to bind.
*/
typedef struct{
	sint8		status;
	/*< The result of the bind operation.
	*/
}tstrSocketBindMsg;


/*
@struct	\
	tstrSocketListenMsg
	
@brief	Socket listen status. 

	It is passed to the APPSocketEventHandler with SOCKET_MSG_LISTEN message type 
	in a response to a user call to listen.
*/
typedef struct{
	sint8		status;
	/*< Result of the listen operation.
	*/
}tstrSocketListenMsg;



/*
@struct	\
	tstrSocketAcceptMsg
	
@brief	Socket accept status. 

	It is passed to the APPSocketEventHandler with SOCKET_MSG_ACCEPT message type 
	in a response to a user call to accept.
*/
typedef struct{
	SOCKET		sock;
	/*< Socket ID for the accepted connection with a remote peer. If it is a negative value, it refers to 
	an accept error (accept failed).
	*/
	struct		sockaddr_in_nmc	strAddr;//Tsungta
	/*< Socket address structure for the remote peer.
	*/
}tstrSocketAcceptMsg;


/*
@struct	\
	tstrSocketConnectMsg
	
@brief	Socket connect status. 

	It is passed to the APPSocketEventHandler with SOCKET_MSG_CONNECT message type 
	in a response	to a user call to connect.
*/
typedef struct{
	SOCKET	sock;
	/*< Socket ID referring to the socket passed to the connect function call.
	*/
	sint8		s8Error;
	/*< Connect error code. It shall be ZERO for successful connect and a negative number otherwise.
	*/
}tstrSocketConnectMsg;


/*
@struct	\
    tstrSocketTCPErrorMsg
    
@brief  Socket connect status. 
 
    It is passed to the APPSocketEventHandler with SOCKET_MSG_TCPERROR message type 
    in a response   for TCP socket error.
*/
typedef struct{
    SOCKET  sock;
    /*< Socket ID referring to the socket passed to the TCP socket control function call.
    */
    sint8       s8Error;
    /*< Connect error code. TCP socket handling errors.
    */
}tstrSocketTCPErrorMsg;
 
/*
@struct \

	tstrSocketRecvMsg
	
@brief	Socket recv status. 

	It is passed to the APPSocketEventHandler with SOCKET_MSG_RECV or SOCKET_MSG_RECVFROM message type 
	in a response to a user call to the recv or recvfrom.
	If the received data from the remote peer is larger than the USER Buffer size (given at recv call), the data is 
	delivered to the user in a number of consecutive chunks according to the USER Buffer size.
*/
typedef struct{
	uint8				*pu8Buffer;
	/*< Pointer to the USER buffer (passed to recv or recvfrom) containing a received data chunk.
	*/
	sint16				s16BufferSize;
	/*< The recevied data chunk size. It will be negative value if there is a recv error.
	*/
	uint16				u16RemainingSize;
	/*< The number of bytes remaining in the current recv operation.
	*/
	struct sockaddr_in_nmc		strRemoteAddr;//Tsungta
	/*< Socket address structure for the remote peer.
	*/
}tstrSocketRecvMsg;


/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
FUNCTION PROTOTYPES
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/

/*
@fn	\			
	NMI_API void socketInit(void);

@brief	Socket Layer Initialization

	The function performs the necessary initializations for the socket library. 
	It must be invoked before any socket operation is performed.
*/
NMI_API void socketInit(void);


/*
@fn	\			
	NMI_API SOCKET socket(uint16 u16Domain, uint8 u8Type, uint8 u8Flags);

@brief	
	Creates a socket with a given type.

@param [in]	u16Domain
				Socket family. The only allowed value is AF_INET for TCP/UDP sockets.

@param [in] u8Type
				Socket type. Allowed values are:
				- [SOCK_STREAM](@ref SOCK_STREAM)
				- [SOCK_DGRAM](@ref SOCK_DGRAM)

@param [in] u8Flags
				Used to specify the socket creation flags. It shall be set to zero for normal TCP/UDP sockets.
				If could be SOCKET_FLAGS_SSL if the socket is used for SSL session. The use of the flag
				[SOCKET_FLAGS_SSL](@ref SOCKET_FLAGS_SSL) has no meaning in case of UDP sockets.

@return		
	The function shall return a negative value for socket creation failed and a nonnegative value
	representing the socket ID otherwise.
*/
NMI_API SOCKET socket(uint16 u16Domain, uint8 u8Type, uint8 u8Flags);


/*
@fn	\			
	NMI_API sint8 bind(SOCKET sock, struct sockaddr *pstrAddr, uint8 u8AddrLen);

@brief	
	Binds a socket on a local port.

@param [in]	sock
				Socket ID.

@param [in] pstrAddr
				Socket address for the address to be bound.

@param [in] u8AddrLen
				Size of the given address in bytes.

@return		
	The function shall return ZERO for successful operation and a negative value otherwise. 
*/
NMI_API sint8 bind(SOCKET sock, struct sockaddr *pstrAddr, uint8 u8AddrLen);


/*
@fn	\			
	NMI_API sint8 listen(SOCKET sock, uint8 backlog);

@brief	
	Start listening on a passive socket for incoming connections. The socket must be bound on a local port
	or the listen fails. The listen function must be called at receiving [SOCKET_MSG_BIND](@ref SOCKET_MSG_BIND)
	in the socket callback.

@param [in]	sock
				Socket ID.

@param [in] backlog
				Number of maximum allowed connections that will be accepted on the given socket.
				It is not used by the current implementation.

@return		
	The function shall return ZERO for successful operation and a negative value otherwise. 
*/
NMI_API sint8 listen(SOCKET sock, uint8 backlog);


/*
@fn	\			
	NMI_API sint8 accept(SOCKET sock, struct sockaddr *addr, uint8 *addrlen);

@brief	
	Retrieve a successful connection .

@param [in]	sock
				Socket ID.

@param [in] addr
				It is not used in the current implementation.

@param [in] addrlen
				It is not used in the current implementation.

@return		
	The function shall return ZERO for successful operation and a negative value otherwise. 
*/
NMI_API sint8 accept(SOCKET sock, struct sockaddr *addr, uint8 *addrlen);


/*
@fn	\	
	NMI_API sint8 connect(SOCKET sock, struct sockaddr *pstrAddr, uint8 u8AddrLen);

@brief	
	Establishes a TCP connection with a remote server.

@param [in]	sock
				Socket ID.

@param [in]	pstrAddr
				Address of the remote server.

@param [in]	u8AddrLen
				Address length in  bytes.

@return		
	The function shall return ZERO for successful operation and a negative value otherwise. 
*/
NMI_API sint8 connect(SOCKET sock, struct sockaddr *pstrAddr, uint8 u8AddrLen);


/*
@fn	\		
	NMI_API sint16 recv(SOCKET sock, void *pvRecvBuf, uint16 u16BufLen, uint32 u32TimeoutSeconds);

@brief		
	Recieves data from a TCP Scoket.

@param [in]	sock
				Socket handler.

@param [in]	pvRecvBuf
				Pointer to a buffer that will hold the received data. The buffer shall be used 
				in the recv callback to deliver the received data to the caller. The buffer must
				be resident in memory (heap or global buffer). 

@param [in]	u16BufLen
				The buffer size in bytes.

@param [in]	u32Timeoutmsec
				Timeout for the recv function in milli-seconds. If the value is set to ZERO, the timeout
				will be set to infinite (the recv function waits forever). If the timeout period is
				elapsed with no data received, the socket will get a timeout error in the function
				[APPSocketEventHandler](@ref APPSocketEventHandler).

@return		
	- [SOCK_ERR_NO_ERROR](@ref SOCK_ERR_NO_ERROR)
	- [SOCK_ERR_INVALID_ARG](@ref SOCK_ERR_INVALID_ARG)
*/
NMI_API sint16 recv(SOCKET sock, void *pvRecvBuf, uint16 u16BufLen, uint32 u32Timeoutmsec);


/*
@fn	\	
	NMI_API sint16 recvfrom(SOCKET sock, void *pvRecvBuf, uint16 u16BufLen, uint32 u32TimeoutSeconds);

@brief		
	Recieves data from a UDP Scoket.

@param [in]	sock
				Socket handler.

@param [in]	pvRecvBuf
				Pointer to a buffer that will hold the received data. The buffer shall be used 
				in the recv callback to deliver the received data to the caller. The buffer must
				be resident in memory (heap or global buffer). 

@param [in]	u16BufLen
				The buffer size in bytes.

@param [in]	u32TimeoutSeconds
				Timeout for the recv function in milli-seconds. If the value is set to ZERO, the timeout
				will be set to infinite (the recv function waits forever).

@return		
	- [SOCK_ERR_NO_ERROR](@ref SOCK_ERR_NO_ERROR)		
	- [SOCK_ERR_INVALID_ARG](@ref SOCK_ERR_INVALID_ARG)
*/
NMI_API sint16 recvfrom(SOCKET sock, void *pvRecvBuf, uint16 u16BufLen, uint32 u32Timeoutmsec);


/*
@fn	\		
	NMI_API sint16 send(SOCKET sock, void *pvSendBuffer, uint16 u16SendLength, uint16 u16Flags);

@brief		
	Sends data on a TCP Scoket.

@param [in]	sock
				Socket handler.

@param [in]	pvSendBuffer
				Pointer to a buffer that holding data to be transmitted. 

@param [in]	u16SendLength
				The buffer size in bytes. It must not exceed [SOCKET_BUFFER_MAX_LENGTH](@ref SOCKET_BUFFER_MAX_LENGTH).

@param [in]	u16Flags
				It is not used in the current implementation

@return		
	The function shall return ZERO for successful operation and a negative value otherwise. 
*/
NMI_API sint16 send_nmc(SOCKET sock, void *pvSendBuffer, uint16 u16SendLength, uint16 u16Flags);


/*
@fn	\		
	NMI_API sint16 sendto(SOCKET sock, void *pvSendBuffer, uint16 u16SendLength, uint16 flags, struct sockaddr *pstrDestAddr, uint8 u8AddrLen);

@brief		
	Sends data on a UDP Scoket.

@param [in]	sock
				Socket handler.

@param [in]	pvSendBuffer
				Pointer to a buffer that holding data to be transmitted. 

@param [in]	u16SendLength
				The buffer size in bytes. It must not exceed [SOCKET_BUFFER_MAX_LENGTH](@ref SOCKET_BUFFER_MAX_LENGTH).

@param [in]	flags
				It is not used in the current implementation

@param [in]	pstrDestAddr
				The destination address.

@param [in]	u8AddrLen
				Destination address length in bytes.

@return		
	The function shall return ZERO for successful operation and a negative value otherwise. 
*/
NMI_API sint16 sendto(SOCKET sock, void *pvSendBuffer, uint16 u16SendLength, uint16 flags, struct sockaddr *pstrDestAddr, uint8 u8AddrLen);


/*
@fn	\		
	NMI_API sint8 close(SOCKET sock);

@brief		
	Closes a socket.

@param [in]	sock
				Socket handler.

@return		
	The function shall return ZERO for successful operation and a negative value otherwise. 
*/
NMI_API sint8 close_nmc(SOCKET sock);


/*
@fn	\		
	NMI_API sint8 gethostbyname(uint8 * pcHostName);

@brief		
	Use DNS to resolve a domain name into the corresponding IP Address.

@param [in]	pcHostName
				NULL terminated string containing the domain name for the remote host.
				Its size must not exceed [HOSTNAME_MAX_SIZE](@ref HOSTNAME_MAX_SIZE).

@return		
	- [SOCK_ERR_NO_ERROR](@ref SOCK_ERR_NO_ERROR)
	- [SOCK_ERR_INVALID_ARG](@ref SOCK_ERR_INVALID_ARG)
*/
NMI_API sint8 gethostbyname(uint8 * pcHostName);


/*
@fn	\		
	NMI_API uint32 nmi_inet_addr(char *pcIpAddr);

@brief		
	Convert the IPv4 from the dotted decimal notation to an integer represented in Network Byte Order.

@param [in]	pcIpAddr
				NULL terminated string containing the dotted decimal notation for an IP "a.b.c.d".

@return		
	The integer representation of the IPv4 address in network byte order.
*/
NMI_API uint32 nmi_inet_addr(char *pcIpAddr);


/*
@fn	\		
	NMI_API void APPSocketEventHandler(SOCKET sock, uint8 u8Msg, void * pvMsg);

@brief	Socket Callback Function

	A function used by the socket layer to convey a socket operation callback to the user. This function MUST be
	implemeneted by the application developer.
	
@param [in]	sock
				Socket ID.

@param [in]	u8Msg
				Socket message type [tenuSocketCallbackMsgType](@ref tenuSocketCallbackMsgType).

@param [in]	pvMsg
				Msg parameters corresponding to the message type.	

@sa			tstrSocketBindMsg
			tstrSocketListenMsg
			tstrSocketAcceptMsg
			tstrSocketConnectMsg
			tstrSocketRecvMsg
*/
NMI_API void APPSocketEventHandler(SOCKET sock, uint8 u8Msg, void * pvMsg);


/*
@fn	\		
	NMI_API void AppServerCb(uint8* pu8DomainName, uint32 u32ServerIP);

@brief		
	DNS host name resolution callback.

@param [in]	pu8DomainName
				NULL terminated string containing the Domain name of a host (eg. "www.Google.com").

@param [in]	u32ServerIP
				IP Address corresponding to the domain name. It is formatted in network byte order.
*/
NMI_API void AppServerCb(uint8* pu8DomainName, uint32 u32ServerIP);

//Ryan
typedef void (*tf_APPSocketEventHandler)(SOCKET sock, uint8 u8Msg, void * pvMsg);

NMI_API void m2m_set_app(tf_APPSocketEventHandler str);

#define M2M_HIF_HDR_OFFSET (sizeof(tstrHifHdr))

/*
*	@struct		tstrHifHdr
*	@brief		Structure to hold HIF header
*	@author		Mahfouz Sheref
*	@version	1.0
*/ 
typedef struct 
{
    uint8   u8Gid;		/*< Group ID */
    uint8   u8Opcode;	/*< OP code */
    uint16  u16Length;	/*< Payload length */
}tstrHifHdr;

#ifdef  __cplusplus
}
#endif /* __cplusplus */

#endif /* __SOCKET_H__ */