void DZeroCopyLoopbackDevice::ReceiveDataCallback() { // Copy buffer from send queue (it's like our receive hardware) to receive queue DCommsBuf* srcBuf = iSendQueue.HeadBuffer(); if(!iReceiveQueue.IsFull() && !iSendQueue.IsEmpty()) { // Alloc a new buffer in to which we will copy the received (sent) buffer (mimicking DMA in the non zerocopy case) DCommsBuf newBuf; TInt result = iLdd->Pond().Alloc(newBuf); if(result == KErrNone) { // Copy our buffer and set the new buffer's properties TInt srcPayloadLength = srcBuf->Length(); newBuf.SetOffset(0); newBuf.SetLength(srcPayloadLength); // Do the copy TUint8* srcPayloadPtr = srcBuf->Ptr(); TUint8* destPayloadPtr = newBuf.Ptr(); memcpy(destPayloadPtr, srcPayloadPtr, srcPayloadLength); // Put the new buffer in the receive queue DCommsBuf* destBuf = iReceiveQueue.TailBuffer(); *destBuf = newBuf; iReceiveQueue.Push(); // Drop the incoming buffer srcBuf->Free(); // Step the queue iSendQueue.Pop(); } // We can now complete any outstanding request for received data - if indeed we managed to alloc a receive buffer if(iPendingRead && !iReceiveQueue.IsEmpty()) { iPendingRead = FALSE; // Tell LDD we're done iLdd->ReceiveDataComplete(KErrNone); } } }
void DZeroCopyLoopbackDevice::AdvanceReceiveQueue() { iReceiveQueue.Pop(); }