Hi there,
I have a situation where subscriptions do not get notified and have tracked
it down to a problem with the polled notify processing. Can you advise if
this is a bug or correct my understanding of the code.
I am using kamailio 3.3.3 and have 1 notify process. I have extended
the support for the ua-profile event (rfc 6080). When a new subscription
arrives it is added to the active_watchers table, the 'updated' column is
assigned a number in the range 0 - N-1, where N is effectively the total
number of polled update tasks that are called in a round-robin fashion,
distributed across the notify processes. In this case updated = 7.
In subscribe.c:
int update_subscription_notifier(struct sip_msg* msg, subs_t* subs, int
to_tag_gen, int* sent_reply)
{
...
/* Set the notifier/update fields for the subscription */
subs->updated = core_hash(&subs->callid, &subs->from_tag, 0) %
(pres_waitn_time * pres_notifier_poll_rate
* pres_notifier_processes);
The notify process periodically calls pres_timer_send_notify(), which
calculates the round (the update task number) and does the notify update by
checking the active_watchers table for entries with updated = round. The
update is done twice, first for the event then for event.winfo.
In notify.c:
void pres_timer_send_notify(unsigned int ticks, void *param)
{
int process_num = *((int *) param);
int round = subset + (pres_waitn_time * pres_notifier_poll_rate
* process_num);
if (process_dialogs(round, 0) < 0)
{
LM_ERR("Handling non presence.winfo dialogs\n");
return;
}
if (process_dialogs(round, 1) < 0)
{
LM_ERR("Handling presence.winfo dialogs\n");
return;
}
}
In this instance process_num = 0, so round = subset. However subset is
incremented in process_dialogs() in notify.c:
if (++subset > (pres_waitn_time * pres_notifier_poll_rate) -1)
subset = 0;
This means that round is incremented twice between calls to
process_dialogs(round, 0), in my case round is always even, hence not
detecting the subscription with updated = 7.
It seems that the subset increment should be done in
pres_timer_send_notify() rather than in process_dialogs(). Does that make
sense?
Additionally, is there a need for the second call that only handles
presence.winfo subscriptions? The code could be simplified by only making
one call and processing all subscriptions for the round.
Cheers
Shane Harrison
--
Imagination NZ Ltd
Level 6
92 Queens Drive
P0 Box 30449
Lower Hutt 5040
+64 4 5703870 Extn 875
+64 21 608919 (mobile)