/** Test the driver data flow path by loopback, i.e Transmit the data and receive same data back. It runs the device @ default configuration @param aLoopback Loopback mode as internal or external aTxData Transmit Data buffer aRxSize Receive data size */ void TestExDriver::TestConcurrentTxRx(TInt aLoopback, const TDesC8& aTxData, TInt aRxSize) { TInt r; TRequestStatus stat; iTest.Printf(_L("Test Concurrent Synchronous Requests - Tx/Rx\n")); // Open channel r=iLdd.Open(KUnit1); iTest(r==KErrNone); // Create a buffer that has to be filled and returned by the driver RBuf8 rxBuf; r=rxBuf.Create(aRxSize); iTest(r==KErrNone); r=iLdd.SetIntLoopback(aLoopback); iTest(r==KErrNone); TData TData(&iLdd,&aTxData,&iSem1); // Call ldd interface ReceiveData() API to get data to rxBuf RThread TransferThread; _LIT(KThreadName, "TestThread"); TInt ret = TransferThread.Create( KThreadName, // Thread name TransferTestThread, // Function to be called KDefaultStackSize, KHeapSize, KHeapSize, (TAny *)&TData ); iTest.Printf(_L("Receive Data\n")); TransferThread.Logon(stat); TransferThread.Resume(); iSem1.Signal(); r = iLdd.ReceiveData(rxBuf); // In case of zero length request if (aRxSize==0) { // Driver should return error immediately iTest(r!=KErrNone); TransferThread.Kill(KErrNone); TransferThread.Close(); // Close the RBuf rxBuf.Close(); // Close channel iLdd.Close(); return; } // Print the receive data to display. // It automatically checks the Tx and Rx data. Fails if not matched. // TInt i; iTest.Printf(_L("Received Data of size (%d):"),rxBuf.Size()); for (i=0; i<rxBuf.Size(); i++) { iTest.Printf(_L("%c"),(rxBuf.Ptr())[i]); if ((TUint8)(rxBuf.Ptr())[i] != aTxData[i]) { iTest.Printf(_L("Transmit and Receive data do not match\n")); iTest(EFalse); } } iTest.Printf(_L("\n")); User::WaitForRequest(stat); TransferThread.Close(); // Free the receive buffer rxBuf.Close(); // Close channel iLdd.Close(); }
inline CMapNode(const TKey& oKey1, const TData &oData1=TData()) :oKey(oKey1), oData(oData1) { }
/** Tests if there is a duplication in client access and handle @pre TestLoadDriver() called */ void TestExDriver::TestHandleDuplication() { TInt r; RThread DuplicateThread; TRequestStatus stat; _LIT(KThreadName, "DuplicateThread"); // Check if the driver can verify and deny access to wrong clients iTest.Printf(_L("Check Wrong client access\n")); // Open a channel on Unit1 r=iLdd.Open(KUnit1); iTest(r==KErrNone); // Create another user side handle for the logical channel RExDriverChannel ldd2=iLdd; // RBusLogicalChannel::Duplicate() creates a valid handle to the kernel // object for which the specified thread already has a handle. Check with // ownership as process. // r=ldd2.Duplicate(RThread(),EOwnerProcess); // Above API should return KErrNone. // iTest(r==KErrNone); ldd2.Close(); //Handle duplication iTest.Printf(_L("Check handle duplication\n")); ldd2=iLdd; // Check handle duplication, with ownership as this Thread. r=ldd2.Duplicate(RThread(),EOwnerThread); iTest(r==KErrNone); ldd2.Close(); iLdd.Close(); // Open a channel on Unit1 r=iLdd.Open(KUnit1); iTest(r==KErrNone); TData TData(&iLdd,NULL,NULL); // Create the thread and pass currently opened iLdd handle to it. // This thread shall check the handle duplication. TInt ret = DuplicateThread.Create( KThreadName, // Thread name DuplicateHandleTestThread, // Function to be called KDefaultStackSize, KHeapSize, KHeapSize, (TAny *)&TData ); DuplicateThread.Logon(stat); DuplicateThread.Resume(); User::WaitForRequest(stat); DuplicateThread.Close(); iLdd.Close(); }
void Messenger::onDataReceived( ::net::IStream::TId streamId, const unsigned char* buf, size_t bufSize) { util::ScopedLock lock(&s_sync); try { // Append data to corresponding data buffer TStreamData::iterator dd = m_streamData.find(streamId); if (dd == m_streamData.end()) { dd = m_streamData.insert(std::make_pair(streamId, TData(0))).first; } TData& data = dd->second; // Required data length size_t dataSize = data.size(); size_t requiredLen = dataSize + bufSize; size_t availableLen = data.capacity(); #ifndef NDEBUG { char buf2[128]; memset(buf2, 0, sizeof(buf2)); sprintf(buf2, "%p data before: ", reinterpret_cast<void*>(streamId)); OutputDebugStringA(buf2); if (0 < data.size()) dumpBinBuffer(&data[0], data.size()); else OutputDebugStringA("<empty>\n"); } #endif // !NDEBUG // Resize data buffer if it is not large enough if (availableLen < requiredLen) { // Reserve 20% more size_t reserve = static_cast<size_t>(requiredLen * 1.2); if (reserve < KMSG_INITIAL_DATA_BUF_SIZE) reserve = KMSG_INITIAL_DATA_BUF_SIZE; data.reserve(reserve); } data.resize(requiredLen); // Copy data to buffer memcpy(&data[dataSize], buf, bufSize); // Try to extract message from data while (sizeof(MessageHeader) <= (dataSize = data.size())) { MessageHeader header; memset(&header, 0, sizeof(header)); assert(data.size() == dataSize); unsigned char* pData = &data[0]; memcpy(&header, pData, sizeof(header)); util::T_UI4 messageSize = header.payloadSize + sizeof(MessageHeader); // two bytes at the beginning are message type and payload length if (messageSize <= dataSize) { TMessagePtr message; try { if (!m_messageFactory) { assert(!"Message factory must be set before receiving messages"); throw std::logic_error("Internal error"); } chkptr(m_messageFactory); message = m_messageFactory->createMessage(header.messageType); { util::ScopedLock lock(&m_memStreamSync); util::MemoryStream memstream(pData + sizeof(MessageHeader), pData + messageSize); message->load(memstream); } // Remove message bytes from data { TData::iterator bb = data.begin(); std::advance(bb, messageSize); #ifndef NDEBUG size_t dataSizeBefore = data.size(); assert(dataSizeBefore >= messageSize); #endif // !NDEBUG data.erase(data.begin(), bb); #ifndef NDEBUG size_t dataSizeAfter = data.size(); assert(dataSizeAfter + messageSize == dataSizeBefore); assert(dd->second.size() == dataSizeAfter); { char buf2[128]; memset(buf2, 0, sizeof(buf2)); sprintf(buf2, "%p data after: ", reinterpret_cast<void*>(streamId)); OutputDebugStringA(buf2); if (0 < data.size()) dumpBinBuffer(&data[0], data.size()); else OutputDebugStringA("<empty>\n"); } #endif // !NDEBUG } TMessengerDelegates::iterator ii = m_messengerDelegates.find(streamId); if (ii == m_messengerDelegates.end()) { assert(0); throw util::Error("Stream not found"); } IMessengerDelegate* delegate_ = ii->second; chkptr(delegate_); delegate_->onMessageReceived(streamId, message); } catch (const std::exception& x) { #ifndef NDEBUG const char* szMsg = x.what(); #endif // Unknown messages and message handling errors are simple discarded ignore_unused(x); assert(!"Unknown message type or message handling error"); } catch (...) { // Unknown messages and message handling errors are simple discarded assert(!"Unknown message type or message handling error"); } } else { // Not enough data break; } } } catch (const std::exception& x) { // Some error (probably bad_alloc) occured while processing stream data. // In this case stream is assumed to be in incosistent state and thus is not used any more. net::StreamListener::instance().closeStream(streamId, x.what()); } catch (...) { // Some unknown error occured while processing stream data. // In this case stream is assumed to be in incosistent state and thus is not used any more. net::StreamListener::instance().closeStream(streamId, "Unknown error"); } }