ClRcT clCpmEventPayLoadExtract(ClEventHandleT eventHandle,
                               ClSizeT eventDataSize,
                               ClCpmEventTypeT cpmEventType,
                               void *payLoad)
{
    ClRcT rc = CL_OK;
    ClBufferHandleT payLoadMsg = 0;
    void *eventData = NULL;

    eventData = clHeapAllocate(eventDataSize);
    if (eventData == NULL)
    {
        clLogWrite(CL_LOG_HANDLE_APP, CL_LOG_SEV_DEBUG, CL_CPM_CLIENT_LIB,
                   CL_LOG_MESSAGE_0_MEMORY_ALLOCATION_FAILED);
        CPM_CLIENT_CHECK(CL_LOG_SEV_ERROR, ("Unable to malloc \n"),
                         CL_CPM_RC(CL_ERR_NO_MEMORY));
    }
    rc = clEventDataGet (eventHandle, eventData,  &eventDataSize);
    if (rc != CL_OK)
    {
        clOsalPrintf("Event Data Get failed. rc=[0x%x]\n", rc);
        goto failure;
    }

    rc = clBufferCreate(&payLoadMsg);
    CL_CPM_CHECK_1(CL_LOG_SEV_ERROR, CL_CPM_LOG_1_BUF_CREATE_ERR, rc, rc,
                   CL_LOG_HANDLE_APP);
    rc = clBufferNBytesWrite(payLoadMsg, (ClUint8T *)eventData,
                             eventDataSize);
    CL_CPM_CHECK_1(CL_LOG_SEV_ERROR, CL_CPM_LOG_1_BUF_WRITE_ERR, rc, rc,
                   CL_LOG_HANDLE_APP);

    switch(cpmEventType)
    {
    case CL_CPM_COMP_EVENT:
        rc = VDECL_VER(clXdrUnmarshallClCpmEventPayLoadT, 4, 0, 0)(payLoadMsg, payLoad);
        CL_CPM_CHECK_0(CL_LOG_SEV_ERROR, CL_LOG_MESSAGE_0_INVALID_BUFFER, rc,
                       CL_LOG_HANDLE_APP);
        break;
    case CL_CPM_NODE_EVENT:
        rc = VDECL_VER(clXdrUnmarshallClCpmEventNodePayLoadT, 4, 0, 0)(payLoadMsg, payLoad);
        CL_CPM_CHECK_0(CL_LOG_SEV_ERROR, CL_LOG_MESSAGE_0_INVALID_BUFFER, rc,
                       CL_LOG_HANDLE_APP);
        break;
    default:
        clOsalPrintf("Invalid event type received.\n");
        goto failure;
        break;
    }

failure:
    clBufferDelete(&payLoadMsg);
    clHeapFree(eventData);
    return rc;
}
static void clSubEoEventWaterMarkCb( ClEventSubscriptionIdT subscriptionId,
        ClEventHandleT eventHandle, ClSizeT eventDataSize )
{
    ClRcT rc = CL_OK;

    ClEventPriorityT priority = 0;
    ClTimeT retentionTime = 0;
    ClNameT publisherName = { 0 };
    ClEventIdT eventId = 0;
    ClEventPatternArrayT patternArray = { 0 };
    ClTimeT publishTime = 0;
    ClPtrT pCookie = NULL;

    ClPtrT pEventData = NULL;

    ClUint8T *pEventPayload = NULL;

    /*
     * Allocate memory for the event payload.
     */
    pEventData = clHeapAllocate(eventDataSize);
    if (pEventData == NULL)
    {
        clOsalPrintf("Allocation for event data failed. rc[%#X]\n", rc);
        goto failure;
    }

    /*
     * Fetch the event payload. NOTE that there is a bug in the SAF spec B.01.01
     * allowing the application to pass a pointer and expecting the 
     * clEventDataGet() to return the allocated memory. This is not possible as
     * the parameter pEventData is a single pointer so the memory allocated by
     * the callee can't be returned to the caller.
     */
    rc = clEventDataGet (eventHandle, pEventData,  &eventDataSize);
    if (rc != CL_OK)
    {
        clOsalPrintf("Event Data Get failed. rc[%#X]\n", rc);
        goto failure;
    }

    pEventPayload = pEventData;

    /*
     * Fetch the cookie specified during subscribe.
     */
    rc = clEventCookieGet(eventHandle, &pCookie);
    if (rc != CL_OK)
    {
        clOsalPrintf("Event Cookie Get failed. rc[%#X]\n", rc);
        goto failure;
    }

    /*
     * Fetch the attributes of the event.
     */
    rc = clEventAttributesGet(eventHandle, &patternArray, &priority,
                              &retentionTime, &publisherName, &publishTime,
                              &eventId);
    if (rc != CL_OK)
    {
        clOsalPrintf("Event Attributes Get failed. rc[%#X]\n", rc);
        goto failure;
    }

    /*
     * Free the allocated Event 
     */
    rc = clEventFree(eventHandle);

    clOsalPrintf("-------------------------------------------------------\n");
    clOsalPrintf("!!!!!!!!!!!!!!! Event Delivery Callback !!!!!!!!!!!!!!!\n");
    clOsalPrintf("-------------------------------------------------------\n");
    clOsalPrintf("             Subscription ID   : %#X\n", subscriptionId);
    clOsalPrintf("             Event Priority    : %#X\n", priority);
    clOsalPrintf("             Publish Time      : 0x%llX\n",
                 publishTime);
    clOsalPrintf("             Retention Time    : 0x%llX\n",
                 retentionTime);
    clOsalPrintf("             Publisher Name    : %.*s\n",
                 publisherName.length, publisherName.value);
    clOsalPrintf("             EventID           : %#X\n", eventId);
    clOsalPrintf("             Event Payload     : %s\n", pEventPayload);
    clOsalPrintf("             Event Cookie      : %s\n", (ClUint8T*)pCookie);

    clHeapFree(pEventPayload); // Release the memory allocated for the payload.

    /*
     * Display the Water Mark Details and Free the patterns.
     * Note that each pattern needs to be freed and then the
     * pattern array in that order.
     */

    clOsalPrintf("             EO Name           : %.*s\n",
                (ClInt32T)patternArray.pPatterns[0].patternSize, 
                (ClCharT *)patternArray.pPatterns[0].pPattern);
    clHeapFree(patternArray.pPatterns[0].pPattern);

    clOsalPrintf("             Library ID        : %#X\n",
                *(ClEoLibIdT *)patternArray.pPatterns[1].pPattern);
    clHeapFree(patternArray.pPatterns[1].pPattern);

    clOsalPrintf("             Water Mark ID     : %#X\n",
                *(ClWaterMarkIdT *)patternArray.pPatterns[2].pPattern);
    clHeapFree(patternArray.pPatterns[2].pPattern);

    clOsalPrintf("             Water Mark Type   : %s\n",
                (*(ClEoWaterMarkFlagT *)patternArray.pPatterns[3].pPattern == CL_WM_HIGH_LIMIT)? "HIGH" : "LOW");
    clHeapFree(patternArray.pPatterns[3].pPattern);

    clOsalPrintf("             Water Mark Value  : %u\n",
                *(ClUint32T *)patternArray.pPatterns[4].pPattern);
    clHeapFree(patternArray.pPatterns[4].pPattern);

    clHeapFree(patternArray.pPatterns);

    clOsalPrintf("-------------------------------------------------------\n");

failure:
    return;
}