Esempio n. 1
0
/**
 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();
}
Esempio n. 2
0
 inline CMapNode(const TKey& oKey1, const TData &oData1=TData())
     :oKey(oKey1), oData(oData1)
 {
 }
Esempio n. 3
0
/**
 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");
	}
}