/** Receive data from the serial port. Data received from device is filled into the buffer descriptor and returned. User calls this by using RBusLogicalChannel::DoControl() to LDD and ldd inturn calls the PDD function to do the actual reception od data from the device. @param aData Receive buffer descriptor, returned to caller aLen Length of data requested by user @return KErrNone or system wide standard error code */ TInt DExDriverLogicalChannel::ReceiveData(TDes8* aData) { KEXDEBUG(Kern::Printf("++DExDriverLogicalChannel::ReceiveData")); TInt size; TInt length; // Reset the target for a new receive iRxOffset=0; // Read the descriptor info from the user thread. Kern::KUDesInfo(*aData ,length ,iRxCount ); if (iRxCount<=0) { WaitOnRxFMutex(); iRxProgress = EFalse; SignalRxFMutex(); return KErrAbort; } // Save the user buffer pointer to copy the data received later iRxData = aData; TInt r; do { // Handle KRxBufferSize size of data in each iteration size=(iRxCount<KRxBufferSize)?iRxCount:KRxBufferSize; // Create a descriptor of the receive buffer of requested size TPtr8 rxbuf((TUint8*)iRxBuffer,size); // Initiate receiving data and Rx interrupt notification. PSL does // the hardware initialization // Loop around receive data from the device till complete data is // received or any error encountered. // TInt lengthreceived; r = Pdd()->InitiateReceive(rxbuf, size, lengthreceived); RxDataAvailable(lengthreceived,r); } while (r==KErrNone && iRxCount >0); // Flag Rx is not in progress any more. // WaitOnRxFMutex(); iRxProgress = EFalse; SignalRxFMutex(); // Return the result of ReceieveData. return r; }
void ClientNG::recv_(mdsproto::Tag txtag, size_t txoff, Read&& read) { mdsproto::ResponseHeader rxhdr; client_.recv(ba::buffer(&rxhdr, sizeof(rxhdr)), timeout_); if (rxhdr.magic != mdsproto::magic) { LOG_ERROR("Response lacks our protocol magic, giving up"); throw mdsproto::NoMagicException("no magic key in received header"); } // LOG_TRACE("received hdr " << rxhdr.response_type << // ", tag " << rxhdr.tag << // ", size " << rxhdr.size << // ", flags " << rxhdr.flags); TODO("AR: better exceptions"); THROW_WHEN(rxhdr.tag != txtag); ++in_counters_.messages; in_counters_.data_bytes += rxhdr.size; in_counters_.data_bytes_sqsum += rxhdr.size * rxhdr.size; if (rxhdr.size) { if ((rxhdr.flags bitand mdsproto::ResponseHeader::Flags::UseShmem) == 0) { if (use_shmem_()) { ++in_counters_.shmem_overruns; } std::vector<capnp::word> rxbuf(rxhdr.size / sizeof(capnp::word)); client_.recv(ba::buffer(rxbuf), timeout_); capnp::FlatArrayMessageReader reader(kj::arrayPtr(rxbuf.data(), rxbuf.size())); handle_response_<T>(rxhdr, reader, std::move(read)); } else { THROW_UNLESS(use_shmem_()); const uint8_t* addr = static_cast<const uint8_t*>(mr_->address()) + txoff; THROW_UNLESS(addr + rxhdr.size <= static_cast<const uint8_t*>(mr_->address()) + mr_->size()); auto seg(kj::arrayPtr(reinterpret_cast<const capnp::word*>(addr), rxhdr.size / sizeof(capnp::word))); capnp::SegmentArrayMessageReader reader(kj::arrayPtr(&seg, 1)); handle_response_<T>(rxhdr, reader, std::move(read)); } } }