int sl_RecvFrom(int sd, void *buf, int Len, int flags, SlSockAddr_t *from, SlSocklen_t *fromlen) { _SlRecvfromMsg_u Msg; _SlCmdExt_t CmdExt; int RetVal; CmdExt.TxPayloadLen = 0; CmdExt.RxPayloadLen = Len; CmdExt.pTxPayload = NULL; CmdExt.pRxPayload = (UINT8 *)buf; Msg.Cmd.sd = sd; Msg.Cmd.StatusOrLen = Len; /* no size truncation in recv path */ CmdExt.RxPayloadLen = Msg.Cmd.StatusOrLen; if(sizeof(SlSockAddrIn_t) == *fromlen) { Msg.Cmd.FamilyAndFlags = SL_AF_INET; } else if (sizeof(SlSockAddrIn6_t) == *fromlen) { Msg.Cmd.FamilyAndFlags = SL_AF_INET6; } else { return SL_RET_CODE_INVALID_INPUT; } Msg.Cmd.FamilyAndFlags = (Msg.Cmd.FamilyAndFlags << 4) & 0xF0; Msg.Cmd.FamilyAndFlags |= flags & 0x0F; RetVal = _SlDrvDataReadOp((_SlSd_t)sd, (_SlCmdCtrl_t *)&_SlRecvfomCmdCtrl, &Msg, &CmdExt); if( RetVal != SL_OS_RET_CODE_OK ) { return RetVal; } RetVal = Msg.Rsp.IpV4.statusOrLen; if(RetVal >= 0) { VERIFY_PROTOCOL(sd == Msg.Rsp.IpV4.sd); #if 0 _sl_ParseAddress(&Msg.Rsp, from, fromlen); #else from->sa_family = Msg.Rsp.IpV4.family; if(SL_AF_INET == from->sa_family) { ((SlSockAddrIn_t *)from)->sin_port = Msg.Rsp.IpV4.port; ((SlSockAddrIn_t *)from)->sin_addr.s_addr = Msg.Rsp.IpV4.address; *fromlen = sizeof(SlSockAddrIn_t); } else if (SL_AF_INET6_EUI_48 == from->sa_family ) { ((SlSockAddrIn6_t *)from)->sin6_port = Msg.Rsp.IpV6EUI48.port; sl_Memcpy(((SlSockAddrIn6_t *)from)->sin6_addr._S6_un._S6_u8, Msg.Rsp.IpV6EUI48.address, 6); } #ifdef SL_SUPPORT_IPV6 else if(AF_INET6 == from->sa_family) { VERIFY_PROTOCOL(*fromlen >= sizeof(sockaddr_in6)); ((sockaddr_in6 *)from)->sin6_port = Msg.Rsp.IpV6.port; sl_Memcpy(((sockaddr_in6 *)from)->sin6_addr._S6_un._S6_u32, Msg.Rsp.IpV6.address, 16); *fromlen = sizeof(sockaddr_in6); } #endif #endif } return (int)RetVal; }
int sl_Accept(int sd, SlSockAddr_t *addr, SlSocklen_t *addrlen) { _SlSockAcceptMsg_u Msg; _SlReturnVal_t RetVal; _SocketAddrResponse_u AsyncRsp; UINT8 pObjIdx = MAX_CONCURRENT_ACTIONS; Msg.Cmd.sd = sd; Msg.Cmd.family = (sizeof(SlSockAddrIn_t) == *addrlen) ? SL_AF_INET : SL_AF_INET6; /* Use Obj to issue the command, if not available try later */ pObjIdx = _SlDrvWaitForPoolObj(ACCEPT_ID, sd & BSD_SOCKET_ID_MASK); if (MAX_CONCURRENT_ACTIONS == pObjIdx) { return SL_POOL_IS_EMPTY; } OSI_RET_OK_CHECK(sl_LockObjLock(&g_pCB->ProtectionLockObj, SL_OS_WAIT_FOREVER)); g_pCB->ObjPool[pObjIdx].pRespArgs = (UINT8 *)&AsyncRsp; OSI_RET_OK_CHECK(sl_LockObjUnlock(&g_pCB->ProtectionLockObj)); /* send the command */ VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlAcceptCmdCtrl, &Msg, NULL)); VERIFY_PROTOCOL(Msg.Rsp.sd == sd); RetVal = Msg.Rsp.statusOrLen; if(SL_OS_RET_CODE_OK == RetVal) { /* wait for async and get Data Read parameters */ OSI_RET_OK_CHECK(sl_SyncObjWait(&g_pCB->ObjPool[pObjIdx].SyncObj, SL_OS_WAIT_FOREVER)); VERIFY_PROTOCOL(AsyncRsp.IpV4.sd == sd); RetVal = AsyncRsp.IpV4.statusOrLen; if( (NULL != addr) && (NULL != addrlen) ) { #if 0 /* Kept for backup */ _sl_ParseAddress(&AsyncRsp, addr, addrlen); #else addr->sa_family = AsyncRsp.IpV4.family; if(SL_AF_INET == addr->sa_family) { if( *addrlen == sizeof( SlSockAddrIn_t ) ) { ((SlSockAddrIn_t *)addr)->sin_port = AsyncRsp.IpV4.port; ((SlSockAddrIn_t *)addr)->sin_addr.s_addr = AsyncRsp.IpV4.address; } else { *addrlen = 0; } } else if (SL_AF_INET6_EUI_48 == addr->sa_family ) { if( *addrlen == sizeof( SlSockAddrIn6_t ) ) { ((SlSockAddrIn6_t *)addr)->sin6_port = AsyncRsp.IpV6EUI48.port ; /* will be called from here and from _sl_BuildAddress*/ sl_Memcpy(((SlSockAddrIn6_t *)addr)->sin6_addr._S6_un._S6_u8, AsyncRsp.IpV6EUI48.address, 6); } else { *addrlen = 0; } } #ifdef SL_SUPPORT_IPV6 else { if( *addrlen == sizeof( sockaddr_in6 ) ) { ((sockaddr_in6 *)addr)->sin6_port = AsyncRsp.IpV6.port ; sl_Memcpy(((sockaddr_in6 *)addr)->sin6_addr._S6_un._S6_u32, AsyncRsp.IpV6.address, 16); } else { *addrlen = 0; } } #endif #endif } } _SlDrvReleasePoolObj(pObjIdx); return (int)RetVal; }
_i16 sl_RecvFrom(_i16 sd, void *buf, _i16 Len, _i16 flags, SlSockAddr_t *from, SlSocklen_t *fromlen) { _SlRecvfromMsg_u Msg; _SlCmdExt_t CmdExt; _i16 RetVal; /* verify no erorr handling in progress. if in progress than ignore the API execution and return immediately with an error */ VERIFY_NO_ERROR_HANDLING_IN_PROGRESS(); _SlDrvResetCmdExt(&CmdExt); CmdExt.RxPayloadLen = Len; CmdExt.pRxPayload = (_u8 *)buf; Msg.Cmd.sd = (_u8)sd; Msg.Cmd.StatusOrLen = (_u16)Len; /* no size truncation in recv path */ CmdExt.RxPayloadLen = (_i16)Msg.Cmd.StatusOrLen; Msg.Cmd.FamilyAndFlags = (_u8)(flags & 0x0F); if(sizeof(SlSockAddrIn_t) == *fromlen) { Msg.Cmd.FamilyAndFlags |= (SL_AF_INET << 4); } else if (sizeof(SlSockAddrIn6_t) == *fromlen) { Msg.Cmd.FamilyAndFlags |= (SL_AF_INET6 << 4); } else { return SL_RET_CODE_INVALID_INPUT; } RetVal = _SlDrvDataReadOp((_SlSd_t)sd, (_SlCmdCtrl_t *)&_SlRecvfomCmdCtrl, &Msg, &CmdExt); if( RetVal != SL_OS_RET_CODE_OK ) { return RetVal; } RetVal = Msg.Rsp.IpV4.statusOrLen; if(RetVal >= 0) { VERIFY_PROTOCOL(sd == (_i16)Msg.Rsp.IpV4.sd); #if 0 _sl_ParseAddress(&Msg.Rsp, from, fromlen); #else from->sa_family = Msg.Rsp.IpV4.family; if(SL_AF_INET == from->sa_family) { ((SlSockAddrIn_t *)from)->sin_port = Msg.Rsp.IpV4.port; ((SlSockAddrIn_t *)from)->sin_addr.s_addr = Msg.Rsp.IpV4.address; *fromlen = (SlSocklen_t)sizeof(SlSockAddrIn_t); } else if (SL_AF_INET6_EUI_48 == from->sa_family ) { ((SlSockAddrIn6_t *)from)->sin6_port = Msg.Rsp.IpV6EUI48.port; sl_Memcpy(((SlSockAddrIn6_t *)from)->sin6_addr._S6_un._S6_u8, Msg.Rsp.IpV6EUI48.address, 6); } #ifdef SL_SUPPORT_IPV6 else if(AF_INET6 == from->sa_family) { VERIFY_PROTOCOL(*fromlen >= sizeof(sockaddr_in6)); ((sockaddr_in6 *)from)->sin6_port = Msg.Rsp.IpV6.port; sl_Memcpy(((sockaddr_in6 *)from)->sin6_addr._S6_un._S6_u32, Msg.Rsp.IpV6.address, 16); *fromlen = sizeof(sockaddr_in6); } #endif #endif } return (_i16)RetVal; }