int sl_Start(const void* pIfHdl, char* pDevName, const P_INIT_CALLBACK pInitCallBack) { int pObjIdx = MAX_CONCURRENT_ACTIONS; InitComplete_t AsyncRsp; /* callback init */ _SlDrvDriverCBInit(); /* open the interface: usually SPI or UART */ if (NULL == pIfHdl) { g_pCB->FD = sl_IfOpen(pDevName, 0); } else { g_pCB->FD = (_SlFd_t)pIfHdl; } /* Use Obj to issue the command, if not available try later */ pObjIdx = _SlDrvWaitForPoolObj(START_STOP_ID, SL_MAX_SOCKETS); 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)); if( g_pCB->FD >= 0) { sl_DeviceDisable(); sl_IfRegIntHdlr((SL_P_EVENT_HANDLER)_SlDrvRxIrqHandler, NULL); sl_DeviceEnable(); if (NULL != pInitCallBack) { g_pCB->pInitCallback = pInitCallBack; } else { OSI_RET_OK_CHECK(sl_SyncObjWait(&g_pCB->ObjPool[pObjIdx].SyncObj, SL_OS_WAIT_FOREVER)); /*release Pool Object*/ _SlDrvReleasePoolObj(g_pCB->FunctionParams.AsyncExt.ActionIndex); return GetStartResponseConvert(AsyncRsp.Status); } } return (int)g_pCB->FD; }
int sl_Stop(unsigned short timeout) { int RetVal=0; _SlStopMsg_u Msg; _BasicResponse_t AsyncRsp; int pObjIdx = MAX_CONCURRENT_ACTIONS; /* if timeout is 0 the shutdown is forced immediately */ if( 0 == timeout ) { sl_IfRegIntHdlr(NULL, NULL); sl_DeviceDisable(); RetVal = sl_IfClose(g_pCB->FD); } else { /* let the device make the shutdown using the defined timeout */ Msg.Cmd.Timeout = timeout; /* Use Obj to issue the command, if not available try later */ pObjIdx = _SlDrvWaitForPoolObj(START_STOP_ID,SL_MAX_SOCKETS); 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)); VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlStopCmdCtrl, &Msg, NULL)); if(SL_OS_RET_CODE_OK == (int)Msg.Rsp.status) { OSI_RET_OK_CHECK(sl_SyncObjWait(&g_pCB->ObjPool[pObjIdx].SyncObj, SL_OS_WAIT_FOREVER)); Msg.Rsp.status = AsyncRsp.status; RetVal = Msg.Rsp.status; } _SlDrvReleasePoolObj(pObjIdx); sl_IfRegIntHdlr(NULL, NULL); sl_DeviceDisable(); sl_IfClose(g_pCB->FD); } _SlDrvDriverCBDeinit(); return RetVal; }
int sl_NetAppDnsGetHostByName(char * hostname, unsigned short usNameLen, unsigned long* out_ip_addr,unsigned char family) { _SlGetHostByNameMsg_u Msg; _SlCmdExt_t ExtCtrl; _GetHostByNameAsyncResponse_u AsyncRsp; UINT8 pObjIdx = MAX_CONCURRENT_ACTIONS; ExtCtrl.TxPayloadLen = usNameLen; ExtCtrl.RxPayloadLen = 0; ExtCtrl.pTxPayload = (UINT8 *)hostname; ExtCtrl.pRxPayload = 0; Msg.Cmd.Len = usNameLen; Msg.Cmd.family = family; /*Use Obj to issue the command, if not available try later */ pObjIdx = _SlDrvWaitForPoolObj(GETHOSYBYNAME_ID,SL_MAX_SOCKETS); 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; /*set bit to indicate IPv6 address is expected */ if (SL_AF_INET6 == family) { g_pCB->ObjPool[pObjIdx].AdditionalData |= SL_NETAPP_FAMILY_MASK; } OSI_RET_OK_CHECK(sl_LockObjUnlock(&g_pCB->ProtectionLockObj)); VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlGetHostByNameCtrl, &Msg, &ExtCtrl)); if(SL_RET_CODE_OK == Msg.Rsp.status) { OSI_RET_OK_CHECK(sl_SyncObjWait(&g_pCB->ObjPool[pObjIdx].SyncObj, SL_OS_WAIT_FOREVER)); Msg.Rsp.status = AsyncRsp.IpV4.status; if(SL_OS_RET_CODE_OK == (int)Msg.Rsp.status) { sl_Memcpy((char *)out_ip_addr, (char *)&AsyncRsp.IpV4.ip0, (SL_AF_INET == family) ? SL_IPV4_ADDRESS_SIZE : SL_IPV6_ADDRESS_SIZE); } } _SlDrvReleasePoolObj(pObjIdx); return Msg.Rsp.status; }
int sl_Select(int nfds, SlFdSet_t *readsds, SlFdSet_t *writesds, SlFdSet_t *exceptsds, struct SlTimeval_t *timeout) { _SlSelectMsg_u Msg; _SelectAsyncResponse_t AsyncRsp; UINT8 pObjIdx = MAX_CONCURRENT_ACTIONS; Msg.Cmd.nfds = nfds; Msg.Cmd.readFdsCount = 0; Msg.Cmd.writeFdsCount = 0; Msg.Cmd.readFds = 0; Msg.Cmd.writeFds = 0; if( readsds ) { Msg.Cmd.readFds = (UINT16)readsds->fd_array[0]; } if( writesds ) { Msg.Cmd.writeFds = (UINT16)writesds->fd_array[0]; } if( NULL == timeout ) { Msg.Cmd.tv_sec = 0xffff; Msg.Cmd.tv_usec = 0xffff; } else { if( 0xffff <= timeout->tv_sec ) { Msg.Cmd.tv_sec = 0xffff; } else { Msg.Cmd.tv_sec = (UINT16)timeout->tv_sec; } timeout->tv_usec = timeout->tv_usec >> 10; /* convert to milliseconds */ if( 0xffff <= timeout->tv_usec ) { Msg.Cmd.tv_usec = 0xffff; } else { Msg.Cmd.tv_usec = (UINT16)timeout->tv_usec; } } /* Use Obj to issue the command, if not available try later */ pObjIdx = _SlDrvWaitForPoolObj(SELECT_ID, SL_MAX_SOCKETS); 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 *)&_SlSelectCmdCtrl, &Msg, NULL)); if(SL_OS_RET_CODE_OK == (int)Msg.Rsp.status) { OSI_RET_OK_CHECK(sl_SyncObjWait(&g_pCB->ObjPool[pObjIdx].SyncObj, SL_OS_WAIT_FOREVER)); Msg.Rsp.status = AsyncRsp.status; if( ((int)Msg.Rsp.status) >= 0 ) { if( readsds ) { readsds->fd_array[0] = AsyncRsp.readFds; } if( writesds ) { writesds->fd_array[0] = AsyncRsp.writeFds; } } } _SlDrvReleasePoolObj(pObjIdx); return (int)Msg.Rsp.status; }
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; }
int sl_Connect(int sd, const SlSockAddr_t *addr, int addrlen) { _SlSockConnectMsg_u Msg; _SlReturnVal_t RetVal; _SlCmdCtrl_t CmdCtrl = {0, 0, sizeof(_SocketResponse_t)}; _SocketResponse_t AsyncRsp; UINT8 pObjIdx = MAX_CONCURRENT_ACTIONS; switch(addr->sa_family) { case SL_AF_INET : CmdCtrl.Opcode = SL_OPCODE_SOCKET_CONNECT; CmdCtrl.TxDescLen = sizeof(_SocketAddrIPv4Command_t); break; case SL_AF_INET6_EUI_48: CmdCtrl.Opcode = SL_OPCODE_SOCKET_CONNECT_V6; CmdCtrl.TxDescLen = sizeof(_SocketAddrIPv6EUI48Command_t); break; #ifdef SL_SUPPORT_IPV6 case AF_INET6: CmdCtrl.Opcode = SL_OPCODE_SOCKET_CONNECT_V6; CmdCtrl.TxDescLen = sizeof(_SocketAddrIPv6Command_t); break; #endif case SL_AF_RF : default: return SL_RET_CODE_INVALID_INPUT; } Msg.Cmd.IpV4.lenOrPadding = 0; Msg.Cmd.IpV4.sd = sd; _sl_BuildAddress(addr, addrlen, &Msg.Cmd); /* Use Obj to issue the command, if not available try later */ pObjIdx = _SlDrvWaitForPoolObj(CONNECT_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 *)&CmdCtrl, &Msg, NULL)); VERIFY_PROTOCOL(Msg.Rsp.sd == sd) RetVal = Msg.Rsp.statusOrLen; if(SL_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.sd == sd); RetVal = AsyncRsp.statusOrLen; } _SlDrvReleasePoolObj(pObjIdx); return RetVal; }
int sl_NetAppPingStart(SlPingStartCommand_t* pPingParams,unsigned char family,SlPingReport_t *pReport,const P_SL_DEV_PING_CALLBACK pPingCallback) { _SlCmdCtrl_t CmdCtrl = {0, sizeof(_PingStartCommand_t), sizeof(_BasicResponse_t)}; _SlPingStartMsg_u Msg; _PingReportResponse_t PingRsp; UINT8 pObjIdx = MAX_CONCURRENT_ACTIONS; if( 0 == pPingParams->Ip ) // stop any ongoing ping { return _SlDrvBasicCmd(SL_OPCODE_NETAPP_PINGSTOP); } if(SL_AF_INET == family) { CmdCtrl.Opcode = SL_OPCODE_NETAPP_PINGSTART; memcpy(&Msg.Cmd.ip0, &pPingParams->Ip, SL_IPV4_ADDRESS_SIZE); } else { CmdCtrl.Opcode = SL_OPCODE_NETAPP_PINGSTART_V6; memcpy(&Msg.Cmd.ip0, &pPingParams->Ip, SL_IPV6_ADDRESS_SIZE); } Msg.Cmd.pingIntervalTime = pPingParams->PingIntervalTime; Msg.Cmd.PingSize = pPingParams->PingSize; Msg.Cmd.pingRequestTimeout = pPingParams->PingRequestTimeout; Msg.Cmd.totalNumberOfAttempts = pPingParams->TotalNumberOfAttempts; Msg.Cmd.flags = pPingParams->Flags; if( pPingCallback ) { pPingCallBackFunc = pPingCallback; } else { /*Use Obj to issue the command, if not available try later */ pObjIdx = _SlDrvWaitForPoolObj(PING_ID,SL_MAX_SOCKETS); if (MAX_CONCURRENT_ACTIONS == pObjIdx) { return SL_POOL_IS_EMPTY; } OSI_RET_OK_CHECK(sl_LockObjLock(&g_pCB->ProtectionLockObj, SL_OS_WAIT_FOREVER)); /* async response handler for non callback mode */ g_pCB->ObjPool[pObjIdx].pRespArgs = (UINT8 *)&PingRsp; pPingCallBackFunc = NULL; OSI_RET_OK_CHECK(sl_LockObjUnlock(&g_pCB->ProtectionLockObj)); } VERIFY_RET_OK(_SlDrvCmdOp(&CmdCtrl, &Msg, NULL)); /*send the command*/ if(CMD_PING_TEST_RUNNING == (int)Msg.Rsp.status || CMD_PING_TEST_STOPPED == (int)Msg.Rsp.status ) { /* block waiting for results if no callback function is used */ if( NULL == pPingCallback ) { OSI_RET_OK_CHECK(sl_SyncObjWait(&g_pCB->ObjPool[pObjIdx].SyncObj, SL_OS_WAIT_FOREVER)); if( SL_OS_RET_CODE_OK == (int)PingRsp.status ) { CopyPingResultsToReport(&PingRsp,pReport); } _SlDrvReleasePoolObj(pObjIdx); } } else { /* ping failure, no async response */ if( NULL == pPingCallback ) { _SlDrvReleasePoolObj(pObjIdx); } } return Msg.Rsp.status; }
long sl_NetAppDnsGetHostByService(char *pServiceName, /* string containing all (or only part): name + subtype + service */ unsigned char ServiceLen, unsigned char Family, /* 4-IPv4 , 16-IPv6 */ unsigned long pAddr[], unsigned long *pPort, unsigned short *pTextLen, /* in: max len , out: actual len */ char *pText ) { _SlGetHostByServiceMsg_u Msg; _SlCmdExt_t CmdExt ; _GetHostByServiceAsyncResponse_t AsyncRsp; UINT8 pObjIdx = MAX_CONCURRENT_ACTIONS; /* Note: 1. The return's attributes are belonged to first service that is found. It can be other services with the same service name will response to the query. The results of these responses are saved in the peer cache of the NWP, and should be read by another API. 2. Text length can be 120 bytes only - not more It is because of constraints in the NWP on the buffer that is allocated for the Async event. 3.The API waits to Async event by blocking. It means that the API is finished only after an Async event is sent by the NWP. 4.No rolling option!!! - only PTR type is sent. */ /*build the attribute part of the command. It contains the constant parameters of the command */ Msg.Cmd.ServiceLen = ServiceLen; Msg.Cmd.AddrLen = Family; /*Build the payload part of the command Copy the service name and text to one buffer.*/ CmdExt.TxPayloadLen = ServiceLen; CmdExt.RxPayloadLen = 0; CmdExt.pTxPayload = (UINT8 *)pServiceName; CmdExt.pRxPayload = NULL; /*set pointers to the output parameters (the returned parameters). This pointers are belonged to local struct that is set to global Async response parameter. It is done in order not to run more than one sl_DnsGetHostByService at the same time. The API should be run only if global parameter is pointed to NULL. */ AsyncRsp.out_pText = pText; AsyncRsp.inout_TextLen = (unsigned short*)pTextLen; AsyncRsp.out_pPort = pPort; AsyncRsp.out_pAddr = (unsigned long *)pAddr; /*Use Obj to issue the command, if not available try later */ pObjIdx = _SlDrvWaitForPoolObj(GETHOSYBYSERVICE_ID,SL_MAX_SOCKETS); 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 = (void *)&AsyncRsp; OSI_RET_OK_CHECK(sl_LockObjUnlock(&g_pCB->ProtectionLockObj)); /* set bit to indicate IPv6 address is expected */ if (SL_AF_INET6 == Family) { g_pCB->ObjPool[pObjIdx].AdditionalData |= SL_NETAPP_FAMILY_MASK; } /* Send the command */ VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlGetHostByServiceCtrl, &Msg, &CmdExt)); /* If the immediate reponse is O.K. than wait for aSYNC event response. */ if(SL_RET_CODE_OK == Msg.Rsp.status) { OSI_RET_OK_CHECK(sl_SyncObjWait(&g_pCB->ObjPool[pObjIdx].SyncObj, SL_OS_WAIT_FOREVER)); /* If we are - it means that Async event was sent. The results are copied in the Async handle return functions */ Msg.Rsp.status = AsyncRsp.Status; } _SlDrvReleasePoolObj(pObjIdx); return Msg.Rsp.status; }