HRESULT Library_spot_net_security_native_Microsoft_SPOT_Net_Security_SslNative::SecureConnect___STATIC__VOID__I4__STRING__OBJECT( CLR_RT_StackFrame& stack ) { NATIVE_PROFILE_CLR_NETWORK(); TINYCLR_HEADER(); CLR_INT32 sslContext = stack.Arg0().NumericByRef().s4; CLR_RT_HeapBlock* hb = stack.Arg1().DereferenceString(); CLR_RT_HeapBlock* socket = stack.Arg2().Dereference(); CLR_INT32 timeout_ms = -1; // wait forever CLR_RT_HeapBlock hbTimeout; int result; LPCSTR szName; CLR_INT32 handle; bool fRes = true; CLR_INT64 *timeout; 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_ARG(hb); szName = hb->StringText(); hbTimeout.SetInteger( timeout_ms ); TINYCLR_CHECK_HRESULT(stack.SetupTimeout( hbTimeout, timeout )); while(true) { result = SSL_Connect( handle, szName, sslContext ); if(result == SOCK_EWOULDBLOCK || result == SOCK_TRY_AGAIN) { // 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 )); if(result < 0) break; } else { break; } } stack.PopValue(); // Timeout TINYCLR_CHECK_HRESULT(ThrowOnError( stack, result )); TINYCLR_NOCLEANUP(); }
HRESULT Library_spot_native_Microsoft_SPOT_Messaging_EndPoint::GetMessage___MicrosoftSPOTMessagingMessage__I4( CLR_RT_StackFrame& stack ) { NATIVE_PROFILE_CLR_MESSAGING(); TINYCLR_HEADER(); CLR_RT_HeapBlock* pThis; CLR_RT_HeapBlock_EndPoint* ep; CLR_RT_HeapBlock_EndPoint::Message* msg = NULL; CLR_INT64* timeout; bool fRes; pThis = stack.This(); FAULT_ON_NULL(pThis); TINYCLR_CHECK_HRESULT(CLR_RT_HeapBlock_EndPoint::ExtractInstance( pThis[ FIELD__m_handle ], ep )); TINYCLR_CHECK_HRESULT(stack.SetupTimeout( stack.Arg1(), timeout )); fRes = true; while(fRes) { msg = ep->FindMessage( CLR_Messaging_Commands::c_Messaging_Send, NULL ); if(msg) break; TINYCLR_CHECK_HRESULT(g_CLR_RT_ExecutionEngine.WaitEvents( stack.m_owningThread, *timeout, CLR_RT_ExecutionEngine::c_Event_EndPoint, fRes )); } stack.PopValue(); { CLR_RT_HeapBlock& top = stack.PushValueAndClear(); if(msg) { CLR_RT_HeapBlock* pMsg; CLR_RT_ReflectionDef_Index val; val.InitializeFromHash( msg->m_addr.m_from.m_type ); TINYCLR_CHECK_HRESULT(g_CLR_RT_ExecutionEngine.NewObjectFromIndex( top, g_CLR_RT_WellKnownTypes.m_Message )); pMsg = top.Dereference(); pMsg[ Library_spot_native_Microsoft_SPOT_Messaging_Message::FIELD__m_source ].SetObjectReference( pThis ); pMsg[ Library_spot_native_Microsoft_SPOT_Messaging_Message::FIELD__m_selector ].SetReflection ( val ); pMsg[ Library_spot_native_Microsoft_SPOT_Messaging_Message::FIELD__m_id ].SetInteger ( msg->m_addr.m_from.m_id ); pMsg[ Library_spot_native_Microsoft_SPOT_Messaging_Message::FIELD__m_seq ].SetInteger ( msg->m_addr.m_seq ); TINYCLR_CHECK_HRESULT(CLR_RT_HeapBlock_Array::CreateInstance( pMsg[ Library_spot_native_Microsoft_SPOT_Messaging_Message::FIELD__m_payload ], msg->m_length, g_CLR_RT_WellKnownTypes.m_UInt8 )); memcpy( pMsg[ Library_spot_native_Microsoft_SPOT_Messaging_Message::FIELD__m_payload ].DereferenceArray()->GetFirstElement(), msg->m_data, msg->m_length ); msg->Unlink(); CLR_RT_Memory::Release( msg ); } } TINYCLR_NOCLEANUP(); }
HRESULT Library_spot_net_native_Microsoft_SPOT_Net_SocketNative::poll___STATIC__BOOLEAN__OBJECT__I4__I4( CLR_RT_StackFrame& stack ) { NATIVE_PROFILE_CLR_NETWORK(); TINYCLR_HEADER(); CLR_RT_HeapBlock* socket = stack.Arg0().Dereference(); CLR_INT32 handle; CLR_INT32 mode = stack.Arg1().NumericByRef().s4; CLR_INT32 timeout_us = stack.Arg2().NumericByRef().s4; CLR_RT_HeapBlock hbTimeout; CLR_INT32 timeout_ms; CLR_INT32 res = 0; bool fRes = true; CLR_INT64* timeout; FAULT_ON_NULL(socket); handle = socket[ 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 == DISPOSED_HANDLE) { ThrowError( stack, CLR_E_OBJECT_DISPOSED ); TINYCLR_SET_AND_LEAVE (CLR_E_PROCESS_EXCEPTION); } if(timeout_us < 0) timeout_ms = -1; else timeout_ms = timeout_us / 1000; hbTimeout.SetInteger( timeout_ms ); TINYCLR_CHECK_HRESULT(stack.SetupTimeout( hbTimeout, timeout )); while(fRes) { res = Helper__SelectSocket( handle, mode ); if(res != 0) break; TINYCLR_CHECK_HRESULT(g_CLR_RT_ExecutionEngine.WaitEvents( stack.m_owningThread, *timeout, CLR_RT_ExecutionEngine::c_Event_Socket, fRes )); } stack.PopValue(); //timer TINYCLR_CHECK_HRESULT(ThrowOnError( stack, res )); stack.SetResult_Boolean( res == 1 ); TINYCLR_NOCLEANUP(); }
HRESULT Library_corlib_native_System_AppDomain::Unload___STATIC__VOID__SystemAppDomain( CLR_RT_StackFrame& stack ) { NATIVE_PROFILE_CLR_CORE(); TINYCLR_HEADER(); CLR_RT_AppDomain* appDomainSav; CLR_RT_AppDomain* appDomain; CLR_RT_HeapBlock hbTimeout; CLR_INT64* timeout; bool fRes; TINYCLR_CHECK_HRESULT(GetAppDomain( stack.ThisRef(), appDomain, appDomainSav, false )); hbTimeout.SetInteger( 5 * 1000 ); if(stack.m_customState == 0) { //Attempt to unload the AppDomain only once TINYCLR_CHECK_HRESULT(g_CLR_RT_ExecutionEngine.UnloadAppDomain( appDomain, stack.m_owningThread )); } TINYCLR_CHECK_HRESULT(stack.SetupTimeout( hbTimeout, timeout )); fRes = true; while(fRes) { //Check to make sure this AppDomain is the one that caused the event to fire if(appDomain->m_state == CLR_RT_AppDomain::AppDomainState_Unloaded) break; _ASSERTE(CLR_EE_IS(UnloadingAppDomain)); TINYCLR_CHECK_HRESULT(g_CLR_RT_ExecutionEngine.WaitEvents( stack.m_owningThread, *timeout, CLR_RT_ExecutionEngine::c_Event_AppDomain, fRes )); } if(!fRes) TINYCLR_SET_AND_LEAVE(CLR_E_TIMEOUT); appDomain->DestroyInstance(); stack.PopValue(); TINYCLR_CLEANUP(); g_CLR_RT_ExecutionEngine.SetCurrentAppDomain( appDomainSav ); TINYCLR_CLEANUP_END(); }
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_net_native_Microsoft_SPOT_Net_SocketNative::getaddrinfo___STATIC__VOID__STRING__BYREF_STRING__BYREF_SZARRAY_SZARRAY_U1( CLR_RT_StackFrame& stack ) { NATIVE_PROFILE_CLR_NETWORK(); TINYCLR_HEADER(); LPCSTR szName = stack.Arg0().RecoverString(); struct SOCK_addrinfo hints; struct SOCK_addrinfo* addr = NULL; struct SOCK_addrinfo* addrT; CLR_UINT32 cAddresses = 0; CLR_RT_HeapBlock* pAddress; CLR_INT32 timeout_ms = 30000; CLR_RT_HeapBlock hbTimeout; CLR_INT32 ret; bool fRes = true; CLR_INT64* timeout; hbTimeout.SetInteger( timeout_ms ); TINYCLR_CHECK_HRESULT(stack.SetupTimeout( hbTimeout, timeout )); do { memset( &hints, 0, sizeof(hints) ); ret = SOCK_getaddrinfo( szName, NULL, &hints, &addr ); if(ret == SOCK_SOCKET_ERROR) { if(SOCK_getlasterror() == SOCK_EWOULDBLOCK) { // 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 )); } else { break; } } else { break; } } while(fRes); // timeout expired if(!fRes) { ret = SOCK_SOCKET_ERROR; ThrowError( stack, SOCK_ETIMEDOUT ); TINYCLR_SET_AND_LEAVE( CLR_E_PROCESS_EXCEPTION ); } // getaddrinfo returns a winsock error code rather than SOCK_SOCKET_ERROR, so pass this on to the exception handling if(ret != 0) { ThrowError( stack, ret ); TINYCLR_SET_AND_LEAVE(CLR_E_PROCESS_EXCEPTION); } { CLR_RT_HeapBlock hbCanonicalName; CLR_RT_HeapBlock hbAddresses; hbCanonicalName.SetObjectReference( NULL ); CLR_RT_ProtectFromGC gc( hbCanonicalName ); hbAddresses.SetObjectReference( NULL ); CLR_RT_ProtectFromGC gc2( hbAddresses ); for(int pass = 0; pass < 2; pass++) { cAddresses = 0; for(addrT = addr; addrT != NULL; addrT = addrT->ai_next) { if(pass == 1) { if(addrT->ai_canonname && addrT->ai_canonname[ 0 ]) { //allocate return string TINYCLR_CHECK_HRESULT(CLR_RT_HeapBlock_String::CreateInstance( hbCanonicalName, addrT->ai_canonname )); TINYCLR_CHECK_HRESULT(hbCanonicalName.StoreToReference( stack.Arg1(), 0 )); } //allocate address and store into array pAddress = (CLR_RT_HeapBlock*)hbAddresses.DereferenceArray()->GetElement( cAddresses ); TINYCLR_CHECK_HRESULT(CLR_RT_HeapBlock_Array::CreateInstance( *pAddress, (CLR_UINT32)addrT->ai_addrlen, g_CLR_RT_WellKnownTypes.m_UInt8 )); //copy address. memcpy( pAddress->DereferenceArray()->GetFirstElement(), addrT->ai_addr, addrT->ai_addrlen ); } cAddresses++; } if(pass == 0) { //allocate array of byte arrays CLR_RT_ReflectionDef_Index idx; idx.m_kind = REFLECTION_TYPE; idx.m_levels = 2; idx.m_data.m_type.m_data = g_CLR_RT_WellKnownTypes.m_UInt8.m_data; TINYCLR_CHECK_HRESULT(CLR_RT_HeapBlock_Array::CreateInstance( hbAddresses, cAddresses, idx )); TINYCLR_CHECK_HRESULT(hbAddresses.StoreToReference( stack.Arg2(), 0 )); } } } stack.PopValue(); // Timeout TINYCLR_CLEANUP(); if( addr ) SOCK_freeaddrinfo( addr ); TINYCLR_CLEANUP_END(); }
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::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_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(); }