HRESULT Library_spot_hardware_serial_native_System_IO_Ports_SerialPort::Read___I4__SZARRAY_U1__I4__I4( CLR_RT_StackFrame& stack ) { NATIVE_PROFILE_CLR_HARDWARE(); TINYCLR_HEADER(); CLR_RT_HeapBlock_Array* readBuffer; CLR_RT_HeapBlock* pThis; CLR_RT_HeapBlock* config; CLR_UINT8* ptr; CLR_INT32 offset; CLR_INT32 count; CLR_INT32 totLength; CLR_INT32 totRead; CLR_RT_HeapBlock* timeout; CLR_INT64* timeoutTicks; CLR_INT32 port; bool fRes; pThis = stack.This(); FAULT_ON_NULL(pThis); // check if the object was disposed if(pThis[ FIELD__m_fDisposed ].NumericByRef().s1 != 0) { TINYCLR_SET_AND_LEAVE(CLR_E_OBJECT_DISPOSED); } config = pThis[ FIELD__m_config ].Dereference(); FAULT_ON_NULL(config); readBuffer = stack.Arg1().DereferenceArray(); FAULT_ON_NULL(readBuffer); offset = stack.Arg2().NumericByRef().s4; count = stack.Arg3().NumericByRef().s4; totLength = readBuffer->m_numOfElements; timeout = &config[ Library_spot_hardware_serial_native_System_IO_Ports_SerialPort__Configuration::FIELD__ReadTimeout ]; port = config[ Library_spot_hardware_serial_native_System_IO_Ports_SerialPort__Configuration::FIELD__PortIndex ].NumericByRef().s4; // // Bound checking. // if(offset < 0 || offset > totLength) { TINYCLR_SET_AND_LEAVE(CLR_E_OUT_OF_RANGE); } if(count == -1) { count = totLength - offset; } else { if(count < 0 || (offset+count) > totLength) { TINYCLR_SET_AND_LEAVE(CLR_E_OUT_OF_RANGE); } } TINYCLR_CHECK_HRESULT(stack.SetupTimeout( *timeout, timeoutTicks )); // // Push "totRead" onto the eval stack. // if(stack.m_customState == 1) { stack.PushValueI4( 0 ); stack.m_customState = 2; } //--// totRead = stack.m_evalStack[ 1 ].NumericByRef().s4; ptr = readBuffer->GetFirstElement(); ptr += offset + totRead; count -= totRead; fRes = true; while(fRes && count > 0) { int read = ::USART_Read( port, (char*)ptr, count ); if(read == 0) { stack.m_evalStack[ 1 ].NumericByRef().s4 = totRead; TINYCLR_CHECK_HRESULT(g_CLR_RT_ExecutionEngine.WaitEvents( stack.m_owningThread, *timeoutTicks, CLR_RT_ExecutionEngine::c_Event_SerialPort, fRes )); } else if(read < 0) { TINYCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } else { ptr += read; totRead += read; count -= read; } } stack.PopValue(); // totRead stack.PopValue(); // Timeout stack.SetResult_I4( totRead ); TINYCLR_NOCLEANUP(); }
HRESULT Library_spot_net_security_native_Microsoft_SPOT_Net_Security_SslNative::ReadWriteHelper( CLR_RT_StackFrame& stack, bool isWrite ) { NATIVE_PROFILE_CLR_NETWORK(); TINYCLR_HEADER(); CLR_RT_HeapBlock* socket = stack.Arg0().Dereference(); CLR_RT_HeapBlock_Array* arrData = stack.Arg1().DereferenceArray(); CLR_INT32 offset = stack.Arg2().NumericByRef().s4; CLR_INT32 count = stack.Arg3().NumericByRef().s4; CLR_INT32 timeout_ms = stack.Arg4().NumericByRef().s4; CLR_UINT8* buffer; CLR_RT_HeapBlock hbTimeout; CLR_INT32 totReadWrite; bool fRes = true; CLR_INT64 *timeout; int result = 0; CLR_INT32 handle; if(count == 0) { stack.SetResult_I4( 0 ); TINYCLR_SET_AND_LEAVE(S_OK); } FAULT_ON_NULL(socket); handle = socket[ Library_spot_net_native_Microsoft_SPOT_Net_SocketNative::FIELD__m_Handle ].NumericByRef().s4; /* Because we could have been a rescheduled call due to a prior call that would have blocked, we need to see * if our handle has been shutdown before continuing. */ if (handle == Library_spot_net_native_Microsoft_SPOT_Net_SocketNative::DISPOSED_HANDLE) { ThrowError( stack, CLR_E_OBJECT_DISPOSED ); TINYCLR_SET_AND_LEAVE(CLR_E_PROCESS_EXCEPTION); } FAULT_ON_NULL(arrData); hbTimeout.SetInteger( timeout_ms ); TINYCLR_CHECK_HRESULT(stack.SetupTimeout( hbTimeout, timeout )); // // Push "totReadWrite" onto the eval stack. // if(stack.m_customState == 1) { stack.PushValueI4( 0 ); stack.m_customState = 2; } totReadWrite = stack.m_evalStack[ 1 ].NumericByRef().s4; buffer = arrData->GetElement( offset + totReadWrite ); count -= totReadWrite; if((offset + count + totReadWrite) > (int)arrData->m_numOfElements) TINYCLR_SET_AND_LEAVE(CLR_E_INDEX_OUT_OF_RANGE); while(count > 0) { // first make sure we have data to read or ability to write while(fRes) { if(!isWrite) { // check SSL_DataAvailable() in case SSL has already read and buffered socket data result = SSL_DataAvailable(handle); if((result > 0) || ((result < 0) && (SOCK_getlasterror() != SOCK_EWOULDBLOCK))) { break; } } result = Library_spot_net_native_Microsoft_SPOT_Net_SocketNative::Helper__SelectSocket( handle, isWrite ? 1 : 0 ); if((result > 0) || ((result < 0) && (SOCK_getlasterror() != SOCK_EWOULDBLOCK))) { break; } // non-blocking - allow other threads to run while we wait for socket activity TINYCLR_CHECK_HRESULT(g_CLR_RT_ExecutionEngine.WaitEvents( stack.m_owningThread, *timeout, CLR_RT_ExecutionEngine::c_Event_Socket, fRes )); // timeout expired if(!fRes) { result = SOCK_SOCKET_ERROR; ThrowError(stack, SOCK_ETIMEDOUT); TINYCLR_SET_AND_LEAVE( CLR_E_PROCESS_EXCEPTION ); } } // socket is in the excepted state, so let's bail out if(SOCK_SOCKET_ERROR == result) { break; } if(isWrite) { result = SSL_Write( handle, (const char*)buffer, count ); } else { result = SSL_Read( handle, (char*)buffer, count ); if(result == SSL_RESULT__WOULD_BLOCK) { continue; } } // ThrowOnError expects anything other than 0 to be a failure - so return 0 if we don't have an error if(result <= 0) { break; } buffer += result; totReadWrite += result; count -= result; // read is non-blocking if we have any data if(!isWrite && (totReadWrite > 0)) { break; } stack.m_evalStack[ 1 ].NumericByRef().s4 = totReadWrite; } stack.PopValue(); // totReadWrite stack.PopValue(); // Timeout if(result < 0) { TINYCLR_CHECK_HRESULT(ThrowOnError( stack, result )); } stack.SetResult_I4( totReadWrite ); TINYCLR_NOCLEANUP(); }
HRESULT Library_spot_native_Microsoft_SPOT_Messaging_EndPoint::Check___BOOLEAN__mscorlibSystemType__U4__I4( CLR_RT_StackFrame& stack ) { NATIVE_PROFILE_CLR_MESSAGING(); TINYCLR_HEADER(); CLR_RT_HeapBlock* pThis; CLR_RT_HeapBlock_EndPoint::Message* msg; CLR_RT_HeapBlock_EndPoint::Port port; CLR_RT_HeapBlock_EndPoint* ep; CLR_INT64* timeout; bool fRes; CLR_UINT32 seq; pThis = stack.This(); FAULT_ON_NULL(pThis); TINYCLR_CHECK_HRESULT(CLR_RT_HeapBlock_EndPoint::ExtractInstance( pThis[ FIELD__m_handle ], ep )); if(CLR_RT_ReflectionDef_Index::Convert( stack.Arg1(), port.m_type ) == false) TINYCLR_SET_AND_LEAVE(CLR_E_NULL_REFERENCE); port.m_id = stack.Arg2().NumericByRefConst().u4; TINYCLR_CHECK_HRESULT(stack.SetupTimeout( stack.Arg3(), timeout )); // // Send message. // if(stack.m_customState == 1) { CLR_Messaging_Commands::Messaging_Query rpc; rpc.m_addr.m_from = ep->m_addr; rpc.m_addr.m_seq = ep->m_seq++; rpc.m_addr.m_to = port; // // Push sequence number onto the eval stack to wait for reply. // stack.PushValueI4( rpc.m_addr.m_seq ); CLR_EE_MSG_EVENT_RPC( CLR_Messaging_Commands::c_Messaging_Query, sizeof(rpc), &rpc, WP_Flags::c_NonCritical ); stack.m_customState = 2; } // // Get seq# from stack // seq = stack.m_evalStack[ 1 ].NumericByRef().u4; fRes = true; msg = NULL; while(fRes) { msg = ep->FindMessage( CLR_Messaging_Commands::c_Messaging_Query, &seq ); if(msg) break; TINYCLR_CHECK_HRESULT(g_CLR_RT_ExecutionEngine.WaitEvents( stack.m_owningThread, *timeout, CLR_RT_ExecutionEngine::c_Event_EndPoint, fRes )); } stack.PopValue(); //seq stack.PopValue(); //Timeout fRes = false; if(msg) { fRes = (msg->m_found != 0); msg->Unlink(); CLR_RT_Memory::Release( msg ); } stack.SetResult_Boolean( fRes ); TINYCLR_NOCLEANUP(); }
HRESULT Library_spot_net_native_Microsoft_SPOT_Net_SocketNative::SendRecvHelper( CLR_RT_StackFrame& stack, bool fSend, bool fAddress ) { NATIVE_PROFILE_CLR_NETWORK(); TINYCLR_HEADER(); CLR_RT_HeapBlock* socket = stack.Arg0().Dereference(); CLR_INT32 handle; CLR_RT_HeapBlock_Array* arrData = stack.Arg1().DereferenceArray(); CLR_UINT32 offset = stack.Arg2().NumericByRef().u4; CLR_UINT32 count = stack.Arg3().NumericByRef().u4; CLR_INT32 flags = stack.Arg4().NumericByRef().s4; CLR_INT32 timeout_ms = stack.ArgN(5).NumericByRef().s4; CLR_RT_HeapBlock hbTimeout; CLR_INT64* timeout; CLR_UINT8* buf; bool fRes = true; CLR_INT32 totReadWrite; CLR_INT32 ret = 0; FAULT_ON_NULL(socket); handle = socket[ FIELD__m_Handle ].NumericByRef().s4; FAULT_ON_NULL(arrData); if(offset + count > arrData->m_numOfElements) TINYCLR_SET_AND_LEAVE(CLR_E_INDEX_OUT_OF_RANGE); /* Because we could have been a rescheduled call due to a prior call that would have blocked, we need to see * if our handle has been shutdown before continuing. */ if (handle == DISPOSED_HANDLE) { ThrowError( stack, CLR_E_OBJECT_DISPOSED ); TINYCLR_SET_AND_LEAVE (CLR_E_PROCESS_EXCEPTION); } hbTimeout.SetInteger( timeout_ms ); TINYCLR_CHECK_HRESULT(stack.SetupTimeout( hbTimeout, timeout )); // // Push "totReadWrite" onto the eval stack. // if(stack.m_customState == 1) { stack.PushValueI4( 0 ); stack.m_customState = 2; } totReadWrite = stack.m_evalStack[ 1 ].NumericByRef().s4; buf = arrData->GetElement( offset + totReadWrite ); count -= totReadWrite; while(count > 0) { CLR_INT32 bytes = 0; // first make sure we have data to read or ability to write while(fRes) { ret = Helper__SelectSocket( handle, fSend ? 1 : 0 ); if(ret != 0) break; // non-blocking - allow other threads to run while we wait for handle activity TINYCLR_CHECK_HRESULT(g_CLR_RT_ExecutionEngine.WaitEvents( stack.m_owningThread, *timeout, CLR_RT_ExecutionEngine::c_Event_Socket, fRes )); } // timeout expired if(!fRes) { ret = SOCK_SOCKET_ERROR; ThrowError( stack, SOCK_ETIMEDOUT ); TINYCLR_SET_AND_LEAVE( CLR_E_PROCESS_EXCEPTION ); } // socket is in the excepted state, so let's bail out if(SOCK_SOCKET_ERROR == ret) { break; } if(fAddress) { struct SOCK_sockaddr addr; CLR_UINT32 addrLen = sizeof(addr); CLR_RT_HeapBlock& blkAddr = stack.ArgN( 6 ); if(fSend) { TINYCLR_CHECK_HRESULT(MarshalSockAddress( &addr, addrLen, blkAddr )); bytes = SOCK_sendto( handle, (const char*)buf, count, flags, &addr, addrLen ); } else { CLR_RT_HeapBlock* pBlkAddr = blkAddr.Dereference(); TINYCLR_CHECK_HRESULT(MarshalSockAddress( &addr, addrLen, *pBlkAddr )); bytes = SOCK_recvfrom( handle, (char*)buf, count, flags, &addr, (int*)&addrLen ); if(bytes != SOCK_SOCKET_ERROR) { TINYCLR_CHECK_HRESULT(MarshalSockAddress( blkAddr, &addr, addrLen )); } } } else { if(fSend) { bytes = SOCK_send( handle, (const char*)buf, count, flags ); } else { bytes = SOCK_recv( handle, (char*)buf, count, flags ); } } // send/recv/sendto/recvfrom failed if(bytes == SOCK_SOCKET_ERROR) { CLR_INT32 err = SOCK_getlasterror(); if(err != SOCK_EWOULDBLOCK) { ret = SOCK_SOCKET_ERROR; break; } continue; } // zero recv bytes indicates the handle has been closed. else if(!fSend && (bytes == 0)) { break; } buf += bytes; totReadWrite += bytes; count -= bytes; stack.m_evalStack[ 1 ].NumericByRef().s4 = totReadWrite; // receive returns immediately after receiving bytes. if(!fSend && (totReadWrite > 0)) { break; } } stack.PopValue(); // totReadWrite stack.PopValue(); // Timeout TINYCLR_CHECK_HRESULT(ThrowOnError( stack, ret )); stack.SetResult_I4( totReadWrite ); TINYCLR_NOCLEANUP(); }
HRESULT Library_spot_native_Microsoft_SPOT_Messaging_EndPoint::SendMessageRaw___SZARRAY_U1__mscorlibSystemType__U4__I4__SZARRAY_U1( CLR_RT_StackFrame& stack ) { NATIVE_PROFILE_CLR_MESSAGING(); TINYCLR_HEADER(); CLR_RT_HeapBlock* pThis; CLR_Messaging_Commands::Messaging_Send* rpc; CLR_RT_HeapBlock_EndPoint::Message* msg; CLR_RT_HeapBlock_EndPoint::Port port; CLR_RT_HeapBlock_EndPoint* ep; CLR_INT64* timeout; CLR_RT_HeapBlock_Array* pData; CLR_UINT32 len; bool fRes; CLR_UINT32 seq; pThis = stack.This(); FAULT_ON_NULL(pThis); TINYCLR_CHECK_HRESULT(CLR_RT_HeapBlock_EndPoint::ExtractInstance( pThis[ FIELD__m_handle ], ep )); if(CLR_RT_ReflectionDef_Index::Convert( stack.Arg1(), port.m_type ) == false) TINYCLR_SET_AND_LEAVE(CLR_E_NULL_REFERENCE); port.m_id = stack.Arg2().NumericByRefConst().u4; TINYCLR_CHECK_HRESULT(stack.SetupTimeout( stack.Arg3(), timeout )); pData = stack.Arg4().DereferenceArray(); FAULT_ON_NULL(pData); //Send message rpc = NULL; if(stack.m_customState == 1) { len = sizeof(CLR_RT_HeapBlock_EndPoint::Address) + pData->m_numOfElements; rpc = (CLR_Messaging_Commands::Messaging_Send*)CLR_RT_Memory::Allocate( len ); CHECK_ALLOCATION(rpc); rpc->m_addr.m_to = port; rpc->m_addr.m_from = ep->m_addr; rpc->m_addr.m_seq = ep->m_seq++; memcpy( rpc->m_data, pData->GetFirstElement(), pData->m_numOfElements ); //Push sequence number onto the eval stack to wait for reply stack.PushValueI4( rpc->m_addr.m_seq ); CLR_EE_MSG_EVENT_RPC( CLR_Messaging_Commands::c_Messaging_Send, len, rpc, WP_Flags::c_NonCritical ); stack.m_customState = 2; } //get seq# from stack seq = stack.m_evalStack[ 1 ].NumericByRef().u4; fRes = true; msg = NULL; while(fRes) { msg = ep->FindMessage( CLR_Messaging_Commands::c_Messaging_Reply, &seq ); if(msg) break; TINYCLR_CHECK_HRESULT(g_CLR_RT_ExecutionEngine.WaitEvents( stack.m_owningThread, *timeout, CLR_RT_ExecutionEngine::c_Event_EndPoint, fRes )); } stack.PopValue(); //seq stack.PopValue(); //Timeout { CLR_RT_HeapBlock& top = stack.PushValueAndClear(); if(msg) { TINYCLR_CHECK_HRESULT(CLR_RT_HeapBlock_Array::CreateInstance( top, msg->m_length, g_CLR_RT_WellKnownTypes.m_UInt8 )); memcpy( top.DereferenceArray()->GetFirstElement(), msg->m_data, msg->m_length ); msg->Unlink(); CLR_RT_Memory::Release( msg ); } } TINYCLR_NOCLEANUP(); }