# &develguide;

## Available Functions

### `bind_peerstate(peerstate_api_t *api)`

Bind to the peerstate API and fill the provided structure with function pointers.

Meaning of the parameters is as follows:

- peerstate_api_t *api - pointer to API structure

The API structure:

    typedef struct peerstate_api {
        register_peerstate_cb_f register_callback;
    } peerstate_api_t;

Return value:

- 0 - success

- -1 - error

### `register_peerstate_callback(int event_types, peerstate_cb_f callback, void *param)`

Register a callback function for peer state change notifications.

Meaning of the parameters is as follows:

- int event_types - Bitmask of event types:

  - PEERSTATE_EVENT_DIALOG (1) - Dialog events

  - PEERSTATE_EVENT_REGISTRATION (2) - Registration events

- peerstate_cb_f callback - Callback function with signature:

  void callback(peerstate_cb_ctx_t *ctx, void *param);

- void *param - User parameter (can be NULL)

The callback context structure:

    typedef struct peerstate_cb_ctx {
        str peer;                      /* Peer identifier */
        ps_state_t current_state;        /* Current state */
        ps_state_t previous_state;       /* Previous state */
        int call_count;                /* Active call count */
        int is_registered;             /* Registration status */
        str uniq_id;                   /* Call-ID or RUID */
        peerstate_event_type_t event_type;  /* Event type */
    } peerstate_cb_ctx_t;

State enumeration:

    typedef enum ps_state {
        NOT_INUSE,      /* Registered and idle */
        INUSE,          /* In active call */
        RINGING,        /* Ringing */
        UNAVAILABLE,    /* Not registered */
        NA              /* Unknown */
    } ps_state_t;

Return value:

- 0 - success

- -1 - error

#### Callback registration example

    #include "../peerstate/peerstate_cb.h"

    static peerstate_api_t peerstate_api;

    /* Callback function */
    static void my_state_callback(peerstate_cb_ctx_t *ctx, void *param) {
        LM_INFO("Peer %.*s: %s -> %s (calls=%d, reg=%s)\n",
                ctx->peer.len, ctx->peer.s,
                PS_STATE_TO_STR(ctx->previous_state),
                PS_STATE_TO_STR(ctx->current_state),
                ctx->call_count,
                ctx->is_registered ? "yes" : "no");
    }

    /* Module initialization */
    static int mod_init(void) {
        bind_peerstate_f bind_peerstate;

        bind_peerstate = (bind_peerstate_f)find_export("bind_peerstate", 1, 0);
        if (!bind_peerstate || bind_peerstate(&peerstate_api) < 0) {
            LM_ERR("Cannot bind to peerstate module\n");
            return -1;
        }

        if (peerstate_api.register_callback(
                PEERSTATE_EVENT_DIALOG | PEERSTATE_EVENT_REGISTRATION,
                my_state_callback, NULL) < 0) {
            LM_ERR("Failed to register callback\n");
            return -1;
        }

        return 0;
    }