Пример #1
0
/**
 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;
	}
Пример #2
0
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));
        }
    }
}