Callback Function Example

This example mainly shows the code that works with the previous example, which looks for a path message. This example also prints all the event information, using the format routines of the RSVP API where appropriate:

struct sockaddr_in sndAddr; /* remember the sender IP addr:port here */

    int _System callback(
        rapi_sid_t         sid,          /* Which sid generated event    */
        rapi_eventinfo_t   eventType,    /* Event type                   */
        rapi_styleid_t     styleID,      /* Style ID                     */
        int                errorCode,    /* Error code                   */
        int                errorValue,   /* Error value                  */
        struct sockaddr   *pNodeAddr,    /* Error node address           */
        u_char             errorFlags,   /* Error flags                  */
        int                nFilterSpecs, /* Number of filterspecs/sender*/
                                         /*      templates in list       */
        rapi_filter_t     *pFilterSpec,  /* Filterspec/sender templ list*/
        int                nFlowSpecs,   /* Number of flowspecs/Tspecs   */
        rapi_flowspec_t   *pFlowSpec,    /* Flowspec/tspec list          */
        int                nAdSpecs,     /* Number of adspecs            */
        rapi_adspec_t     *pAdSpec,      /* Adspec list                  */
        void *             pClientArg    /* Client supplied arg          */
        )
    {
    int i;
    #define FMT_BUF_SIZE 600
    char buf[FMT_BUF_SIZE];
    printf("callback() sid %d, eventType %d, styleID %d\n",
           sid, eventType, styleID);

    /* if we received the path event then tell the select loop */
    if (eventType == RAPI_PATH_EVENT)
        {
        receivedPathEvent = 1;
        /* get the sender address from pFilterSpec */
        if (nFilterSpec && (pFilterSpec->form == RAPI_FILTERFORM_BASE))
           sndAddr = pFilterSpec->filter.base.sender;
        /* else it is another address form... */
        }


In a realistic program, the adspec information would be processed to determine what services are supported by network elements that support RSVP. Information on data rate, bandwidth, packet MTU, and so on, normally would be available. A receiver would determine what reservation flowspec would be suitable for the data stream that the sender could send.

If a reservation event is being processed by a sender, the adspec information normally would provide the upper limit on packet size, and other useful information, and the sender could adjust its data flow accordingly.

To print all the event information:

    if (errorCode == RAPI_ERR_OK)
        printf("errorCode %d\n", errorCode);
    else
        printf("errorCode %d, errorValue %d, nodeAddr %s:%d, errorFlags %d\n",
               errorCode, errorValue,
               inet_ntoa(((struct sockaddr_in*)pNodeAddr->sin_addr),
               ((struct sockaddr_in*)pNodeAddr->sin_port, errorFlags);
    if (nFilterSpecs)
        for (i = 0; i < nFilterSpecs; ++i)
            {
            rapi_fmt_filtspec(pFilterSpec + i, buf, FMT_BUF_SIZE);
            printf("filterspec %d, %s\n", i, buf);
            }
    else
        printf("No filter specs\n");
    if (nFlowSpecs)
        for (i = 0; i < nFlowSpecs; ++i)
            {
            rapi_fmt_flowspec(pFlowSpec + i, buf, FMT_BUF_SIZE);
            printf("flowspec %d, %s\n", i, buf);
            }
    else
        printf("No flowspecs\n");
    if (nAdSpecs)
        for (i = 0; i < nAdSpecs; ++i)
            {
            rapi_fmt_adspec(pAdSpec + i, buf, FMT_BUF_SIZE);
            printf("adspec %d, %s\n", i, buf);
            }
    else
        printf("No adspecs\n");
    /* the function must return a value, but the API does nothing to it */
    return 0;
    } /* end callback */


[Back: Using Select() with the Alert Socket]
[Next: Making a QoS Reservation]