/********************************************************************* Function setsockopt Description Return None. Author Abdelrahman Diab Version 1.0 Date 9 September 2014 *********************************************************************/ sint8 sslSetSockOpt(SOCKET sock, uint8 u8Opt, const void *pvOptVal, uint16 u16OptLen) { sint8 s8Ret = SOCK_ERR_INVALID_ARG; if(sock < TCP_SOCK_MAX) { if(gastrSockets[sock].u8SSLFlags & SSL_FLAGS_ACTIVE) { if(u8Opt == SO_SSL_BYPASS_X509_VERIF) { int optVal = *((int*)pvOptVal); if(optVal) { gastrSockets[sock].u8SSLFlags |= SSL_FLAGS_BYPASS_X509; } else { gastrSockets[sock].u8SSLFlags &= ~SSL_FLAGS_BYPASS_X509; } s8Ret = SOCK_ERR_NO_ERROR; } else if(u8Opt == SO_SSL_SNI) { if(u16OptLen < HOSTNAME_MAX_SIZE) { uint8 *pu8SNI = (uint8*)pvOptVal; tstrSSLSetSockOptCmd strCmd; strCmd.sock = sock; strCmd.u16SessionID = gastrSockets[sock].u16SessionID; strCmd.u8Option = u8Opt; strCmd.u32OptLen = u16OptLen; m2m_memcpy(strCmd.au8OptVal, pu8SNI, HOSTNAME_MAX_SIZE); if(SOCKET_REQUEST(SOCKET_CMD_SSL_SET_SOCK_OPT, (uint8*)&strCmd, sizeof(tstrSSLSetSockOptCmd), 0, 0, 0) == M2M_ERR_MEM_ALLOC) { s8Ret = SOCKET_REQUEST(SOCKET_CMD_SSL_SET_SOCK_OPT | M2M_REQ_DATA_PKT, (uint8*)&strCmd, sizeof(tstrSSLSetSockOptCmd), 0, 0, 0); } s8Ret = SOCK_ERR_NO_ERROR; } else { M2M_ERR("SNI Exceeds Max Length\n"); } } else { M2M_ERR("Unknown SSL Socket Option %d\n",u8Opt); } } else { M2M_ERR("Not SSL Socket\n"); } } return s8Ret; }
/********************************************************************* Function connectSocket Description Connect to a remote TCP Server. Return Author Ahmed Ezzat Version 1.0 Date 5 June 2012 *********************************************************************/ sint8 connectSocket(SOCKET sock, struct sockaddr *pstrAddr, uint8 u8AddrLen) { sint8 s8Ret = SOCK_ERR_INVALID_ARG; if((sock >= 0) && (pstrAddr != NULL) && (gastrSockets[sock].bIsUsed == 1) && (u8AddrLen != 0)) { tstrConnectCmd strConnect; uint8 u8Cmd = SOCKET_CMD_CONNECT; if((gastrSockets[sock].u8SSLFlags) & SSL_FLAGS_ACTIVE) { u8Cmd = SOCKET_CMD_SSL_CONNECT; strConnect.u8SslFlags = gastrSockets[sock].u8SSLFlags; } strConnect.sock = sock; m2m_memcpy((uint8 *)&strConnect.strAddr, (uint8 *)pstrAddr, sizeof(tstrSockAddr)); strConnect.strAddr.u16Family = strConnect.strAddr.u16Family; strConnect.strAddr.u16Port = strConnect.strAddr.u16Port; strConnect.strAddr.u32IPAddr = strConnect.strAddr.u32IPAddr; strConnect.u16SessionID = gastrSockets[sock].u16SessionID; s8Ret = SOCKET_REQUEST(u8Cmd, (uint8*)&strConnect,sizeof(tstrConnectCmd), NULL, 0, 0); if(s8Ret != SOCK_ERR_NO_ERROR) { s8Ret = SOCK_ERR_INVALID; } } return s8Ret; }
/********************************************************************* Function bind Description Request to bind a socket on a local address. Return Author Ahmed Ezzat Version 1.0 Date 5 June 2012 *********************************************************************/ sint8 bind(SOCKET sock, struct sockaddr *pstrAddr, uint8 u8AddrLen) { sint8 s8Ret = SOCK_ERR_INVALID_ARG; if((pstrAddr != NULL) && (sock >= 0) && (gastrSockets[sock].bIsUsed == 1) && (u8AddrLen != 0)) { tstrBindCmd strBind; /* Build the bind request. */ strBind.sock = sock; m2m_memcpy((uint8 *)&strBind.strAddr, (uint8 *)pstrAddr, sizeof(tstrSockAddr)); //strBind.strAddr = *((tstrSockAddr*)pstrAddr); strBind.strAddr.u16Family = strBind.strAddr.u16Family; strBind.strAddr.u16Port = strBind.strAddr.u16Port; strBind.strAddr.u32IPAddr = strBind.strAddr.u32IPAddr; strBind.u16SessionID = gastrSockets[sock].u16SessionID; /* Send the request. */ s8Ret = SOCKET_REQUEST(SOCKET_CMD_BIND, (uint8*)&strBind,sizeof(tstrBindCmd) , NULL , 0, 0); if(s8Ret != SOCK_ERR_NO_ERROR) { s8Ret = SOCK_ERR_INVALID; } } return s8Ret; }
/********************************************************************* Function setsockopt Description Return None. Author Abdelrahman Diab Version 1.0 Date 9 September 2014 *********************************************************************/ sint8 setsockopt(SOCKET sock, uint8 u8Level, uint8 option_name, const void *option_value, uint16 u16OptionLen) { sint8 s8Ret = SOCK_ERR_INVALID_ARG; if((sock >= 0) && (option_value != NULL) && (gastrSockets[sock].bIsUsed == 1)) { if(u8Level == SOL_SSL_SOCKET) { s8Ret = sslSetSockOpt(sock, option_name, option_value, u16OptionLen); } else { uint8 u8Cmd = SOCKET_CMD_SET_SOCKET_OPTION; tstrSetSocketOptCmd strSetSockOpt; strSetSockOpt.u8Option=option_name; strSetSockOpt.sock = sock; strSetSockOpt.u32OptionValue = *(uint32*)option_value; strSetSockOpt.u16SessionID = gastrSockets[sock].u16SessionID; s8Ret = SOCKET_REQUEST(u8Cmd, (uint8*)&strSetSockOpt, sizeof(tstrSetSocketOptCmd), NULL,0, 0); if(s8Ret != SOCK_ERR_NO_ERROR) { s8Ret = SOCK_ERR_INVALID; } } } return s8Ret; }
/********************************************************************* Function sendto Description Return Author Ahmed Ezzat Version 1.0 Date 4 June 2012 *********************************************************************/ sint16 sendto(SOCKET sock, void *pvSendBuffer, uint16 u16SendLength, uint16 flags, struct sockaddr *pstrDestAddr, uint8 u8AddrLen) { sint16 s16Ret = SOCK_ERR_INVALID_ARG; if((sock >= 0) && (pvSendBuffer != NULL) && (u16SendLength <= SOCKET_BUFFER_MAX_LENGTH)) { if(gastrSockets[sock].bIsUsed) { tstrSendCmd strSendTo; m2m_memset((uint8*)&strSendTo, 0, sizeof(tstrSendCmd)); strSendTo.sock = sock; strSendTo.u16DataSize = NM_BSP_B_L_16(u16SendLength); if(pstrDestAddr != NULL) { struct sockaddr_in *pstrAddr; pstrAddr = (void*)pstrDestAddr; strSendTo.strAddr.u16Family = pstrAddr->sin_family; strSendTo.strAddr.u16Port = pstrAddr->sin_port; strSendTo.strAddr.u32IPAddr = pstrAddr->sin_addr.s_addr; } s16Ret = SOCKET_REQUEST(SOCKET_CMD_SENDTO|M2M_REQ_DATA_PKT, (uint8*)&strSendTo, sizeof(tstrSendCmd), pvSendBuffer, u16SendLength, UDP_TX_PACKET_OFFSET); if(s16Ret != SOCK_ERR_NO_ERROR) { s16Ret = SOCK_ERR_BUFFER_FULL; } } } return s16Ret; }
/********************************************************************* Function connect Description Connect to a remote TCP Server. Return Author Ahmed Ezzat Version 1.0 Date 5 June 2012 *********************************************************************/ sint8 connect(SOCKET sock, struct sockaddr *pstrAddr, uint8 u8AddrLen) { sint8 s8Ret = SOCK_ERR_INVALID_ARG; if((sock >= 0) && (pstrAddr != NULL)) { tstrConnectCmd strConnect; uint8 u8Cmd = SOCKET_CMD_CONNECT; if(gastrSockets[sock].bIsSSLSock) { u8Cmd = SOCKET_CMD_SSL_CONNECT; } strConnect.sock = sock; m2m_memcpy((uint8 *)&strConnect.strAddr, (uint8 *)pstrAddr, sizeof(tstrSockAddr)); //strConnect.strAddr = *((tstrSockAddr*)pstrAddr); strConnect.strAddr.u16Family = strConnect.strAddr.u16Family; strConnect.strAddr.u16Port = strConnect.strAddr.u16Port; strConnect.strAddr.u32IPAddr = strConnect.strAddr.u32IPAddr; s8Ret = SOCKET_REQUEST(u8Cmd, (uint8*)&strConnect,sizeof(tstrConnectCmd), NULL, 0, 0); if(s8Ret != SOCK_ERR_NO_ERROR) { s8Ret = SOCK_ERR_INVALID; } } return s8Ret; }
/********************************************************************* Function close Description Return None. Author Ahmed Ezzat Version 1.0 Date 4 June 2012 *********************************************************************/ sint8 close(SOCKET sock) { sint8 s8Ret = SOCK_ERR_INVALID_ARG; if(sock >= 0 && (gastrSockets[sock].bIsUsed == 1)) { uint8 u8Cmd = SOCKET_CMD_CLOSE; tstrCloseCmd strclose; strclose.sock = sock; strclose.u16SessionID = gastrSockets[sock].u16SessionID; gastrSockets[sock].bIsUsed = 0; gastrSockets[sock].u16SessionID =0; if(gastrSockets[sock].u8SSLFlags & SSL_FLAGS_ACTIVE) { u8Cmd = SOCKET_CMD_SSL_CLOSE; } s8Ret = SOCKET_REQUEST(u8Cmd, (uint8*)&strclose, sizeof(tstrCloseCmd), NULL,0, 0); if(s8Ret != SOCK_ERR_NO_ERROR) { s8Ret = SOCK_ERR_INVALID; } m2m_memset((uint8*)&gastrSockets[sock], 0, sizeof(tstrSocket)); } return s8Ret; }
/********************************************************************* Function send Description Return Author Ahmed Ezzat Version 1.0 Date 5 June 2012 *********************************************************************/ sint16 send(SOCKET sock, void *pvSendBuffer, uint16 u16SendLength, uint16 flags) { sint16 s16Ret = SOCK_ERR_INVALID_ARG; if((sock >= 0) && (pvSendBuffer != NULL) && (u16SendLength <= SOCKET_BUFFER_MAX_LENGTH) && (gastrSockets[sock].bIsUsed == 1)) { uint16 u16DataOffset; tstrSendCmd strSend; uint8 u8Cmd; u8Cmd = SOCKET_CMD_SEND; u16DataOffset = TCP_TX_PACKET_OFFSET; strSend.sock = sock; strSend.u16DataSize = NM_BSP_B_L_16(u16SendLength); strSend.u16SessionID = gastrSockets[sock].u16SessionID; if(sock >= TCP_SOCK_MAX) { u16DataOffset = UDP_TX_PACKET_OFFSET; } if(gastrSockets[sock].u8SSLFlags & SSL_FLAGS_ACTIVE) { u8Cmd = SOCKET_CMD_SSL_SEND; u16DataOffset = SSL_TX_PACKET_OFFSET; } s16Ret = SOCKET_REQUEST(u8Cmd|M2M_REQ_DATA_PKT, (uint8*)&strSend, sizeof(tstrSendCmd), pvSendBuffer, u16SendLength, u16DataOffset); if(s16Ret != SOCK_ERR_NO_ERROR) { s16Ret = SOCK_ERR_BUFFER_FULL; } } return s16Ret; }
/********************************************************************* Function socket Description Creates a socket. Return - Negative value for error. - ZERO or positive value as a socket ID if successful. Author Ahmed Ezzat Version 1.0 Date 4 June 2012 *********************************************************************/ SOCKET socket(uint16 u16Domain, uint8 u8Type, uint8 u8Flags) { SOCKET sock = -1; uint8 u8Count,u8SocketCount = MAX_SOCKET; volatile tstrSocket *pstrSock; /* The only supported family is the AF_INET for UDP and TCP transport layer protocols. */ if(u16Domain == AF_INET) { if(u8Type == SOCK_STREAM) { u8SocketCount = TCP_SOCK_MAX; u8Count = 0; } else if(u8Type == SOCK_DGRAM) { /*--- UDP SOCKET ---*/ u8SocketCount = MAX_SOCKET; u8Count = TCP_SOCK_MAX; } else return sock; for(;u8Count < u8SocketCount; u8Count ++) { pstrSock = &gastrSockets[u8Count]; if(pstrSock->bIsUsed == 0) { m2m_memset((uint8*)pstrSock, 0, sizeof(tstrSocket)); pstrSock->bIsUsed = 1; /* The session ID is used to distinguish different socket connections by comparing the assigned session ID to the one reported by the firmware*/ ++gu16SessionID; if(gu16SessionID == 0) ++gu16SessionID; pstrSock->u16SessionID = gu16SessionID; M2M_DBG("1 Socket %d session ID = %d\r\n",u8Count, gu16SessionID ); sock = (SOCKET)u8Count; if(u8Flags & SOCKET_FLAGS_SSL) { tstrSSLSocketCreateCmd strSSLCreate; strSSLCreate.sslSock = sock; pstrSock->u8SSLFlags = SSL_FLAGS_ACTIVE | SSL_FLAGS_NO_TX_COPY; SOCKET_REQUEST(SOCKET_CMD_SSL_CREATE, (uint8*)&strSSLCreate, sizeof(tstrSSLSocketCreateCmd), 0, 0, 0); } break; } } } return sock; }
/********************************************************************* Function sslSetActiveCipherSuites Description Send Ping request. Return Author Ahmed Ezzat Version 1.0 Date 4 June 2015 *********************************************************************/ sint8 sslSetActiveCipherSuites(uint32 u32SslCsBMP) { sint8 s8Ret = SOCK_ERR_INVALID_ARG; if(u32SslCsBMP != 0) { tstrSslSetActiveCsList strCsList; strCsList.u32CsBMP = u32SslCsBMP; s8Ret = SOCKET_REQUEST(SOCKET_CMD_SSL_SET_CS_LIST, (uint8*)&strCsList, sizeof(tstrSslSetActiveCsList), NULL, 0, 0); } return s8Ret; }
/********************************************************************* Function gethostbyname Description Return None. Author Ahmed Ezzat Version 1.0 Date 4 June 2012 *********************************************************************/ sint8 gethostbyname(uint8 * pcHostName) { sint8 s8Err = SOCK_ERR_INVALID_ARG; uint8 u8HostNameSize = (uint8)m2m_strlen(pcHostName); if(u8HostNameSize <= HOSTNAME_MAX_SIZE) { s8Err = SOCKET_REQUEST(SOCKET_CMD_DNS_RESOLVE|M2M_REQ_DATA_PKT, (uint8*)pcHostName, u8HostNameSize + 1, NULL,0, 0); if(s8Err != SOCK_ERR_NO_ERROR) { s8Err = SOCK_ERR_INVALID; } } return s8Err; }
/********************************************************************* Function listen Description Return Author Ahmed Ezzat Version 1.0 Date 5 June 2012 *********************************************************************/ sint8 listen(SOCKET sock, uint8 backlog) { sint8 s8Ret = SOCK_ERR_INVALID_ARG; if(sock >= 0) { tstrListenCmd strListen; strListen.sock = sock; strListen.u8BackLog = backlog; s8Ret = SOCKET_REQUEST(SOCKET_CMD_LISTEN, (uint8*)&strListen, sizeof(tstrListenCmd), NULL, 0, 0); if(s8Ret != SOCK_ERR_NO_ERROR) { s8Ret = SOCK_ERR_INVALID; } } return s8Ret; }
/********************************************************************* Function m2m_ping_req Description Send Ping request. Return Author Ahmed Ezzat Version 1.0 Date 4 June 2015 *********************************************************************/ sint8 m2m_ping_req(uint32 u32DstIP, uint8 u8TTL, tpfPingCb fpPingCb) { sint8 s8Ret = M2M_ERR_INVALID_ARG; if((u32DstIP != 0) && (fpPingCb != NULL)) { tstrPingCmd strPingCmd; strPingCmd.u16PingCount = 1; strPingCmd.u32DestIPAddr = u32DstIP; strPingCmd.u32CmdPrivate = (uint32)fpPingCb; strPingCmd.u8TTL = u8TTL; s8Ret = SOCKET_REQUEST(SOCKET_CMD_PING, (uint8*)&strPingCmd, sizeof(tstrPingCmd), NULL, 0, 0); } return s8Ret; }
/********************************************************************* Function listen Description Return Author Ahmed Ezzat Version 1.0 Date 5 June 2012 *********************************************************************/ sint8 listen(SOCKET sock, uint8 backlog) { sint8 s8Ret = SOCK_ERR_INVALID_ARG; if(sock >= 0 && (gastrSockets[sock].bIsUsed == 1)) { tstrListenCmd strListen; strListen.sock = sock; strListen.u8BackLog = backlog; strListen.u16SessionID = gastrSockets[sock].u16SessionID; s8Ret = SOCKET_REQUEST(SOCKET_CMD_LISTEN, (uint8*)&strListen, sizeof(tstrListenCmd), NULL, 0, 0); if(s8Ret != SOCK_ERR_NO_ERROR) { s8Ret = SOCK_ERR_INVALID; } } return s8Ret; }
/********************************************************************* Function close Description Return None. Author Ahmed Ezzat Version 1.0 Date 4 June 2012 *********************************************************************/ sint8 close(SOCKET sock) { sint8 s8Ret = SOCK_ERR_INVALID_ARG; if(sock >= 0) { uint8 u8Cmd = SOCKET_CMD_CLOSE; tstrCloseCmd strclose; strclose.sock = sock; gastrSockets[sock].bIsUsed = 0; if(gastrSockets[sock].bIsSSLSock) { u8Cmd = SOCKET_CMD_SSL_CLOSE; } s8Ret = SOCKET_REQUEST(u8Cmd, (uint8*)&strclose, sizeof(tstrCloseCmd), NULL,0, 0); if(s8Ret != SOCK_ERR_NO_ERROR) { s8Ret = SOCK_ERR_INVALID; } m2m_memset((uint8*)&gastrSockets[sock], 0, sizeof(tstrSocket)); } return s8Ret; }
/********************************************************************* Function recvfrom Description Return Author Ahmed Ezzat Version 1.0 2.0 9 April 2013 --> Add timeout for recv operation. Date 5 June 2012 *********************************************************************/ sint16 recvfrom(SOCKET sock, void *pvRecvBuf, uint16 u16BufLen, uint32 u32Timeoutmsec) { sint16 s16Ret = SOCK_ERR_NO_ERROR; if((sock >= 0) && (pvRecvBuf != NULL) && (u16BufLen != 0) && (gastrSockets[sock].bIsUsed == 1)) { if(gastrSockets[sock].bIsUsed) { s16Ret = SOCK_ERR_NO_ERROR; gastrSockets[sock].pu8UserBuffer = (uint8*)pvRecvBuf; gastrSockets[sock].u16UserBufferSize = u16BufLen; if(!gastrSockets[sock].bIsRecvPending) { tstrRecvCmd strRecv; gastrSockets[sock].bIsRecvPending = 1; /* Check the timeout value. */ if(u32Timeoutmsec == 0) strRecv.u32Timeoutmsec = 0xFFFFFFFF; else strRecv.u32Timeoutmsec = NM_BSP_B_L_32(u32Timeoutmsec); strRecv.sock = sock; strRecv.u16SessionID = gastrSockets[sock].u16SessionID; s16Ret = SOCKET_REQUEST(SOCKET_CMD_RECVFROM, (uint8*)&strRecv, sizeof(tstrRecvCmd), NULL , 0, 0); if(s16Ret != SOCK_ERR_NO_ERROR) { s16Ret = SOCK_ERR_BUFFER_FULL; } } } } else { s16Ret = SOCK_ERR_INVALID_ARG; } return s16Ret; }
/********************************************************************* Function setsockopt Description Return None. Author Abdelrahman Diab Version 1.0 Date 9 September 2014 *********************************************************************/ sint8 setsockopt(SOCKET sock, uint8 u8Level, uint8 option_name, const void *option_value, uint16 u16OptionLen) { sint8 s8Ret = SOCK_ERR_INVALID_ARG; if((sock >= 0) && (option_value != NULL) ) { uint8 u8Cmd = SOCKET_CMD_SET_SOCKET_OPTION; tstrSetSocketOptCmd strSetSockOpt; strSetSockOpt.u8Option=option_name; strSetSockOpt.sock = sock; strSetSockOpt.u32OptionValue = *(uint32*)option_value; s8Ret = SOCKET_REQUEST(u8Cmd, (uint8*)&strSetSockOpt, sizeof(tstrSetSocketOptCmd), NULL,0, 0); if(s8Ret != SOCK_ERR_NO_ERROR) { s8Ret = SOCK_ERR_INVALID; } } return s8Ret; }