2.5. Unsolicited Data Interfaces

As shown in Figure 2-1 and Figure 2-3 the LCBD routes unsolicited data based upon the LATp protocol. This implies an interface by which the user registers a handler for a particular LATp protocol.

Once the handler is invoked the user needs interfaces for navigating the unsolicited data and for freeing the circular buffer memory used by the unsolicited data.

2.5.1. Registering Call Back Handlers

The LCBD provides an interface for registering a default unsolicited data handler in addition to registering handlers based on specific LATp protocol. The declaration of a call back handler is shown below:

typedef int (*LCB_handlerFunc)(LCB_msg *msg, void *usrData);

The declaration of the registration function for the default call back handler is shown below:

int LCB_setDefaultHandler(LCB *lcb, LCB_handlerFunc func, void *usrData);

The declaration of the registration function for the LATp source address call back handler is shown below:

int LCB_setHandler(LCB *lcb, unsigned short latpProto, LCB_handlerFunc func, void *usrData);

2.5.2. Navigating Unsolicited Data

The user needs a way to navigate the unsolicited data inside of the call back handler. From the LCB_msg item the user can extract the following information about the unsolicited data:

The LCB_msg structure is defined below:


typedef struct __LCB_msg {
   unsigned short       error;
   unsigned short      length;
   unsigned short  cellHeader;
   unsigned short   reserved1;
   unsigned   int  bulkData[];
} LCB_msg;

unsigned short   err = msg->error;
unsigned short   len = msg->length;
unsigned short    ch = msg->cellHeader;
unsigned   int *data = msg->bulkData;

Alternatively the details of the above structure could remain hidden and inlined GET methods used instead:

int LCB_getError(LCB_msg *msg, unsigned short *err);

int LCB_getLength(LCB_msg *msg, unsigned short *len);

int LCB_getCellHeader(LCB_msg *msg, unsigned short *ch);

int LCB_getData(LCB_msg *msg, unsigned int **data);

2.5.3. Freeing Unsolicited Data

The unsolicited data arrives in a circular buffer managed by the LCB (write pointer) and the LCBD (read pointer). Within the handler function the user controls when the unsolicited data is freed by calling the LCB_msgFree() routine shown below.

int LCB_msgFree(LCB_msg *msg);

It is important that the user return the memory to the circular buffer as quickly as possible. If the user operation will "take a long time" the user is obligated to make a copy of the unsolicited data and return the unsolicited data memory immediately. It remains to be seen what "a long time" is.

2.5.4. Example Handlers

Below is an example of a quick handler:


int my_LCB_HandlerQuick( LCB_msg *msg, void *usrData) {

int status = OK;

  if ( msg->error) {
    status = msg->error;
  }
  else {
    // our processing is quick, so just do it
    status = processData( usrData, msg->bulkData);
  }

  // free unsolicited data
  LCB_msgFree( msg);

  return status;
}

Below is an example of a slow handler, which makes a copy of the unsolicited data.


int my_LCB_HandlerSlow( LCB_msg *msg, void *usrData) {

int status = OK;

  if ( msg->error) {
    // free unsolicited data
    status = msg->error;
    LCB_msgFree( msg);
  }
  else {
    // our processing is slow, so make a copy using memcpy.
    // copy data to previously allocated memory, pointed to
    // by the "copy_mem" pointer.
    memcpy( copy_mem, (void *)msg, msg->length);

    // free the unsolicited data
    LCB_msgFree( msg);

    // process the copy
    status = processData( usrData, copy_mem);
  }

  return status;
}