Table of Contents
cache_hash_size (integer)
cache_expire (integer)
cache_cleanup_interval (integer)
use_avps (integer)
caller_avp (string)
callee_avp (string)
reg_avp (string)
enable_notify_on_trying (integer)
disable_caller_notify_flag (integer)
disable_callee_notify_flag (integer)
disable_reg_notify (integer)
disable_dlg_notify (integer)
List of Examples
cache_hash_size parametercache_expire parametercache_cleanup_interval parameteruse_avps parametercaller_avp parametercallee_avp parameterreg_avp parameterenable_notify_on_trying parameterdisable_caller_notify_flag parameterdisable_callee_notify_flag parameterdisable_reg_notify parameterdisable_dlg_notify parameterevent_route[peerstate:state_changed] usageTable of Contents
cache_hash_size (integer)
cache_expire (integer)
cache_cleanup_interval (integer)
use_avps (integer)
caller_avp (string)
callee_avp (string)
reg_avp (string)
enable_notify_on_trying (integer)
disable_caller_notify_flag (integer)
disable_callee_notify_flag (integer)
disable_reg_notify (integer)
disable_dlg_notify (integer)
The peerstate module provides peer state tracking for the Kamailio SIP proxy. It monitors both dialog events (call states) and registration events (usrloc) to maintain an accurate view of each peer's current status.
For example, a common need in call center applications is to track agent availability in real-time. In order to monitor agent states, it is necessary for the proxy to be aware of both call activity and registration status. This is just one common application; there are many others such as presence services, load balancing, and concurrent call limiting.
The module exports RPC commands for monitoring and management, provides an event route mechanism for custom logic execution, and offers a callback API for other Kamailio modules.
The peerstate module registers callbacks with the dialog and usrloc modules. When dialog state changes (EARLY, CONFIRMED, TERMINATED) or registration events (REGISTER/UNREGISTER) occur, the module updates its internal cache and determines if a peer's state has changed.
Peer state is maintained in a shared memory hash table. Each peer entry contains current state, active call count, registration flag, and timestamp.
State transitions:
EARLY events increment call count and set peer to RINGING (or keep INUSE if already in call)
CONFIRMED events set peer to INUSE
TERMINATED events decrement call count; peer returns to NOT_INUSE (if registered) or UNAVAILABLE (if not registered) when call count reaches zero
REGISTER events set registration flag and may transition from UNAVAILABLE to NOT_INUSE
UNREGISTER events clear registration flag and may transition from NOT_INUSE to UNAVAILABLE (if no active calls)
When a peer's state changes, the module triggers notifications via event routes and callback functions.
Peer states tracked by the module:
0 : NOT_INUSE - Peer is registered and idle (no active calls)
1 : INUSE - Peer is in an active call (dialog confirmed)
2 : RINGING - Peer has incoming or outgoing call ringing (early dialog)
3 : UNAVAILABLE - Peer is not registered
4 : NA - Not applicable or unknown state
State transitions are designed to accurately reflect the peer's availability:
A peer transitions to RINGING when receiving or making a call
A peer transitions to INUSE when the call is answered
A peer returns to NOT_INUSE when all calls end and the peer is still registered
A peer transitions to UNAVAILABLE when unregistering with no active calls
Active calls are preserved during registration changes
The following modules must be loaded before this module:
Dialog - Dialog tracking module
Usrloc - User location module
The size of the hash table internally used to keep the peer state information. A larger table is much faster but consumes more memory. The hash size must be a power of two.
Default value is “4096”.
The time in seconds after which inactive peer entries are removed from the cache. Set to 0 to disable automatic expiration. This helps conserve memory by removing stale peer information. Minimum allowed value is 60 seconds (when enabled).
Default value is “3600” (1 hour).
The interval in seconds between automatic cache cleanup runs. Must be less than or equal to cache_expire. Set to 0 to disable automatic cleanup. During cleanup, expired entries are removed from the cache. Minimum allowed value is 10 seconds (when enabled).
Default value is “300” (5 minutes).
Example 1.3. Set cache_cleanup_interval parameter
...
modparam("peerstate", "cache_cleanup_interval", 600)
...
Enable or disable the use of AVPs for peer identification instead of extracting peer information from SIP headers. When enabled, the module will use the AVPs specified by caller_avp, callee_avp, and reg_avp parameters to identify peers.
If set to 0, the module extracts peer information from From/To headers. If set to 1, AVPs must be set by the routing script.
Default value is “0” (disabled).
The specification of an AVP that contains the caller's peer identifier. Only used when use_avps is set to 1. The AVP should contain the peer identifier in the format "peer@domain".
Default value is “NULL”.
Example 1.5. Set caller_avp parameter
...
modparam("peerstate", "caller_avp", "$avp(caller_peer)")
...
The specification of an AVP that contains the callee's peer identifier. Only used when use_avps is set to 1. The AVP should contain the peer identifier in the format "peer@domain".
Default value is “NULL”.
Example 1.6. Set callee_avp parameter
...
modparam("peerstate", "callee_avp", "$avp(callee_peer)")
...
The specification of an AVP that contains the registered peer identifier for usrloc events. Only used when use_avps is set to 1.
Default value is “NULL”.
Enable state change notifications for dialog TRYING state. By default, only EARLY, CONFIRMED, and TERMINATED states trigger notifications. When enabled, TRYING state will also trigger notifications.
Default value is “0” (disabled).
Example 1.8. Set enable_notify_on_trying parameter
...
modparam("peerstate", "enable_notify_on_trying", 1)
...
Message flag to disable caller state change notifications for specific calls. When this flag is set on a message, state changes for the caller will not trigger notifications. Set to -1 to disable this feature.
Default value is “-1” (feature disabled).
Example 1.9. Set disable_caller_notify_flag parameter
...
modparam("peerstate", "disable_caller_notify_flag", 10)
...
# In routing script:
if ($rU == "1234567890") {
setflag(10); # Don't notify about emergency call callers
}
...
Message flag to disable callee state change notifications for specific calls. When this flag is set on a message, state changes for the callee will not trigger notifications. Set to -1 to disable this feature.
Default value is “-1” (feature disabled).
Example 1.10. Set disable_callee_notify_flag parameter
...
modparam("peerstate", "disable_callee_notify_flag", 11)
...
Globally disable registration event processing. When set to 1, the module will not register callbacks with the usrloc module and will not process registration events.
Default value is “0” (process registration events).
Example 1.11. Set disable_reg_notify parameter
...
modparam("peerstate", "disable_reg_notify", 1)
...
Globally disable dialog event processing. When set to 1, the module will not register callbacks with the dialog module and will not process dialog events.
Default value is “0” (process dialog events).
Example 1.12. Set disable_dlg_notify parameter
...
modparam("peerstate", "disable_dlg_notify", 1)
...
Get detailed state information for a specific peer. Returns the peer's current state, active call count, and registration status.
Name: peerstate.get_peer
Parameters:
peer - peer identifier in the format "peer@domain"
RPC Command Format:
... kamctl rpc peerstate.get_peer 1000@192.168.1.100 ...
The command returns a structure containing:
peer - peer identifier
state - current state (NOT_INUSE, INUSE, RINGING, UNAVAILABLE)
call_count - number of active calls
registered - registration status ("yes" or "no")
Get global cache statistics including total number of peers, number of peers in active calls, and number of registered peers.
Name: peerstate.stats
Parameters: none
RPC Command Format:
... kamctl rpc peerstate.stats ...
The command returns a structure containing:
total_peers - total number of peers in cache
incall_peers - number of peers in INUSE or RINGING state
registered_peers - number of registered peers
List all peers in a specific state. This command is useful for monitoring which peers are currently in a particular state.
Name: peerstate.list
Parameters:
state - state filter (NOT_INUSE, INUSE, RINGING, or UNAVAILABLE)
RPC Command Format:
... kamctl rpc peerstate.list INUSE ...
The command returns a structure containing:
count - number of peers in the specified state
state - the state filter used
Peer - array of peer objects with name, state, call_count, and registered status
Dump all peers from the cache regardless of state. This command provides a complete view of all tracked peers.
Name: peerstate.dump
Parameters: none
RPC Command Format:
... kamctl rpc peerstate.dump ...
The command returns a structure containing:
count - total number of peers
Peer - array of peer objects with name, state, call_count, and registered status
Executed when a peer's state changes. Provides access to state change information through AVP pseudo-variables.
Available pseudo-variables:
$avp(ps_peer) - Peer identifier
$avp(ps_state) - Current state (NOT_INUSE, INUSE, RINGING, UNAVAILABLE)
$avp(ps_prev_state) - Previous state
$avp(ps_uniq_id) - Call-ID or RUID
Example 1.13. event_route[peerstate:state_changed] usage
...
event_route[peerstate:state_changed] {
xlog("L_INFO", "Peer $avp(ps_peer): $avp(ps_prev_state) -> $avp(ps_state)");
# HTTP notification
if ($avp(ps_state) == "INUSE") {
http_async_query("http://api.local/state", "peer=$avp(ps_peer)&state=busy", "HTTP_REPLY");
}
}
...
Table of Contents
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 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
Example 2.1. 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;
}