Using
the BIL Interface
This tutorial describes how to use the Buffer Interface Layer (BIL)
to read and write shared chunks form the client driver.
The BIL
is a thin layer over the LDD APIs that removes the need for the class driver
to handle buffers directly. The BIL is consistent between different class
drivers and reduces the buffer related understanding needed to use the USBSc
LDD.
Using the BIL is optional to the class driver, but very highly
recommended.
Before completing these steps you must have followed
the procedure from
the beginning of the tutorial set through to
RDevUsbcScClient::FinalizeInterface()
- Open each endpoint
object.
Use the function RDevUsbcScClient::OpenEndpoint() for
each endpoint object.
TEndpointBuffer iEpBuf;
const TUint KWriteEp = 1;
gPort.OpenEndpoint(iEpBuf, KWriteEp);
OpenEndpoint() fills the provided endpoint buffer
(iEpBuf) for use with the given endpoint number (KWriteEp).
This endpoint will be opened on the current alternate interface setting.
Reading with an OUT endpoint.
To read with an endpoint call TEndpointBuffer::GetBuffer() to
request data from the BIL.
r = iEpBuf.GetBuffer(scReadData, readSize, readZlp, aStatus);
The first parameter passed to GetBuffer() can be either
a pointer to the transfer buffer or the offset of the transfer data within
the shared chunk.
This function allows the BIL to expire any previously retrieved transfer
on this endpoint so that it can be used again for new transfers. If the transfer
or the LDD are not ready then aStatus is set to pending.
If no transfer is available then the variable passed in the first parameter
is set to NULL or 0 depending on the API. Call this function again on completion,
to wait for data again.
The function GetBuffer() returns:
KErrCompletion if data could be retrieved without
a pending request,
KErrNone if an asynchronous request was queued. This
function should be called again on completion,
KErrEof if the end of the data in the endpoint has
been reached,
KErrNotSupported if the endpoint is an IN endpoint.
If the host has changed to an alternate setting and you wish to continue
reading and writing data then you must Close() all endpoints
and go to step five Process the next alternate set of endpoints. Otherwise,
if you have finished then go to step four Close each endpoint object.
Writing with an IN endpoint.
After filling a shared chunk buffer with some data call TEndpointBuffer::WriteBuffer() to
write the data to endpoint hardware.
WriteBuffer() transmits the provided buffer on the
given endpoint asynchronously. More than one request may be outstanding at
any time. This reduces the time between buffer transfers.
r = iEpBuf.WriteBuffer(buffer, length, ETrue, aStatus);
The first parameter passed to WriteBuffer() can be
either a pointer to the transfer buffer or the offset of the transfer data
within the shared chunk.
If the host has changed to an alternate setting and you wish to continue
reading and writing data then you must Close() all endpoints
and go to step five Process the next alternate set of endpoints. Otherwise,
if you have finished then go to step four Close each endpoint object.
Close each endpoint object.
Each endpoint object opened with OpenEndpoint() must
be closed with TEndpointBuffer::Close().
iEpBuf.Close();
If the host has changed to an alternate setting and you wish to continue
reading and writing data then you must Close() all endpoints
and go to step five Process the next alternate set of endpoints. Otherwise,
if you have finished data transfer then Close
and Unload the Driver.
If you wish to continue reading and writing data but on an alternate
setting then call RDevUsbcScClient::StartNextOutAlternateSetting().
Otherwise if you have finished then Close and Unload the Driver.
Process the next alternate set of endpoints.
Use the function RDevUsbcScClient::StartNextOutAlternateSetting() to
switch to the next set of endpoints. The alternate interfaces were initialised
with SetInterface(). See Set
the Interface Descriptors.
TInt r = StartNextOutAlternateSetting(ETrue);
Pass ETrue to the function to purge the buffers of any data unread for
the previous setting.
Note: All open endpoints (except EP0) must be closed before this is
called.