Hi,
I have a timer which is called each 5 seconds: modparam("timer", "declare_timer", "REFRESH_CALLSTATE_TIMER=REFRESH_CALLSTATE_TIMER,5000,slow");
I'm enabling setting the variable "testvar" and enabling the timer when an INVITE is received: if (is_method("INVITE|ACK|UPDATE|CANCEL|BYE")) { $var(testvar) = "blablabla"; timer_enable("REFRESH_CALLSTATE_TIMER", "1"); ...
route[REFRESH_CALLSTATE_TIMER] { xlog("L_INFO", "Testvariable: $var(test)\n"); }
However, the variable is always 0: INFO: <script>: Testvariable: 0
I've also tried printing pseudovariables like $ci, $du but nothinh seems accessible. Is there a workaround for this?
Best regards, Dries
Hi,
It is important to know that the scope of $var(...) is per-process[1], and timer functions run in a different process.
When REFRESH_CALLSTATE_TIMER runs, it is not in response to any particular SIP message or call, and it does not know the context of any particular SIP message or call.
-- Alex
[1] Which also has unexpected consequences when a different SIP message hits the same process in which a $var() was set before; they are process-persistent, as the documentation notes.
On 29 Nov 2023, at 16:02, dries--- via sr-users sr-users@lists.kamailio.org wrote:
Hi,
I have a timer which is called each 5 seconds: modparam("timer", "declare_timer", "REFRESH_CALLSTATE_TIMER=REFRESH_CALLSTATE_TIMER,5000,slow");
I'm enabling setting the variable "testvar" and enabling the timer when an INVITE is received: if (is_method("INVITE|ACK|UPDATE|CANCEL|BYE")) { $var(testvar) = "blablabla"; timer_enable("REFRESH_CALLSTATE_TIMER", "1"); ...
route[REFRESH_CALLSTATE_TIMER] { xlog("L_INFO", "Testvariable: $var(test)\n"); }
However, the variable is always 0: INFO: <script>: Testvariable: 0
I've also tried printing pseudovariables like $ci, $du but nothinh seems accessible. Is there a workaround for this?
Best regards, Dries __________________________________________________________ Kamailio - Users Mailing List - Non Commercial Discussions To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender! Edit mailing list options or unsubscribe:
Sorry, please ignore the variable name typo in the "REFRESH_CALLSTATE_TIMER" route in my initial post.
The issue still stands however.
route[REFRESH_CALLSTATE_TIMER] { xlog("L_INFO", "Testvariable: $var(testvar)\n"); }
I've also tried enabling the timer on start as well as attempting to use $avp instead. All called variables within the route are either 0 or null?
From the rtimer documentation overview:
The module executes route blocks on a timer base. It can create new timer processes and execute many route blocks on same timer. A static faked SIP message is given as parameter to called functions, so all functions available for REQUEST_ROUTE can be used.
It runs in it's own processes, and as Alex noted $var() is per process. It's not clear if the process re-spawns so setting a variable inside the timer action will be retained through multiple executions or not. As for $avp()s, along with $xavp()s and their assorted variants, these are scoped to a SIP transaction, and the timer shouldn't be handling a transaction.
Shared variables and hashtables should be available inside this route, though.
It might be good to clarify what your goal is (why you expect the variables to have values in this route).
-----Original Message----- From: dries--- via sr-users sr-users@lists.kamailio.org Sent: Wednesday, November 29, 2023 3:36 PM To: sr-users@lists.kamailio.org Cc: dries@degendt.com Subject: [SR-Users] Re: No access to variables within timer route
CAUTION: This email originated from outside the organization. Do not click links or open attachments unless you recognize the sender and know the content is safe.
Sorry, please ignore the variable name typo in the "REFRESH_CALLSTATE_TIMER" route in my initial post.
The issue still stands however.
route[REFRESH_CALLSTATE_TIMER] { xlog("L_INFO", "Testvariable: $var(testvar)\n"); }
I've also tried enabling the timer on start as well as attempting to use $avp instead. All called variables within the route are either 0 or null? __________________________________________________________ Kamailio - Users Mailing List - Non Commercial Discussions To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender! Edit mailing list options or unsubscribe:
Hi Ben,
I'll try my best to explain the use case here.
I have a direct trunk between our Asterisk and Kamailio servers. My goal is that when an agent is already in call, he doesn't get prompted with another incoming call on either of his devices. So Asterisk is supposed to perform a redis check each time a call goes through the Asterisk queue.
Since Asterisk can't determine the device state here, I've set up a redis cluster which is supposed to keep track of the agent's call state. For each INVITE in Kamilio, I'm storing a key into redis based on the agent's number, for example "callstate_242680". The value is the call-id. When a BYE/CANCEL is received, I'm retrieving the particular key and comparing the current call-id agains the call-id in the redis object. If it matches, I'm deleting the object so the extension is "available" again.
This works pretty good but sometimes the keys are stored way too long in case a BYE/CANCEL was missed (for example, restart of Kamailio process, network interruptions, ...). I was thinking of setting a redis expiration time for each key, which would be prolonged by the timer running in each call transaction. That way I could retrieve the agent's number and increase the expiration of the matching redis key. I don't think shared memory would be possible since I can't identify the call here.
As an alternative, I'm thinking of keeping track of dialogs using dlg_manage() and also store these into a local redis server (since db_redis doesn't seem to have redis cluster support). That way I can use a timer block to retrieve all the stored dialogs and compare them to the stored callstate keys. I've noticed however that the tracking of dialogs also depends of that BYE/CANCEL however so I don't think it's very usefull.
An alternative method could be to update the redis object in case of a periodic ACK but that's no guaruantee. I also don't want the agent to be wrongfully "busy" for too long.
I'm still trying to fit all the pieces together, I was just hoping if anyone could confirm this is a correct approach?
What I'm not clear on from your example is the use of the timer:
- Kamailio gets an invite, write a record to redis where the key identifies the user. - On call teardown, find the key and delete it.
What is the timer route doing? It should be able to read redis.
-----Original Message----- From: dries--- via sr-users sr-users@lists.kamailio.org Sent: Thursday, November 30, 2023 8:30 AM To: sr-users@lists.kamailio.org Cc: dries@degendt.com Subject: [SR-Users] Re: No access to variables within timer route
CAUTION: This email originated from outside the organization. Do not click links or open attachments unless you recognize the sender and know the content is safe.
Hi Ben,
I'll try my best to explain the use case here.
I have a direct trunk between our Asterisk and Kamailio servers. My goal is that when an agent is already in call, he doesn't get prompted with another incoming call on either of his devices. So Asterisk is supposed to perform a redis check each time a call goes through the Asterisk queue.
Since Asterisk can't determine the device state here, I've set up a redis cluster which is supposed to keep track of the agent's call state. For each INVITE in Kamilio, I'm storing a key into redis based on the agent's number, for example "callstate_242680". The value is the call-id. When a BYE/CANCEL is received, I'm retrieving the particular key and comparing the current call-id agains the call-id in the redis object. If it matches, I'm deleting the object so the extension is "available" again.
This works pretty good but sometimes the keys are stored way too long in case a BYE/CANCEL was missed (for example, restart of Kamailio process, network interruptions, ...). I was thinking of setting a redis expiration time for each key, which would be prolonged by the timer running in each call transaction. That way I could retrieve the agent's number and increase the expiration of the matching redis key. I don't think shared memory would be possible since I can't identify the call here.
As an alternative, I'm thinking of keeping track of dialogs using dlg_manage() and also store these into a local redis server (since db_redis doesn't seem to have redis cluster support). That way I can use a timer block to retrieve all the stored dialogs and compare them to the stored callstate keys. I've noticed however that the tracking of dialogs also depends of that BYE/CANCEL however so I don't think it's very usefull.
An alternative method could be to update the redis object in case of a periodic ACK but that's no guaruantee. I also don't want the agent to be wrongfully "busy" for too long.
I'm still trying to fit all the pieces together, I was just hoping if anyone could confirm this is a correct approach? __________________________________________________________ Kamailio - Users Mailing List - Non Commercial Discussions To unsubscribe send an email to sr-users-leave@lists.kamailio.org Important: keep the mailing list in the recipients, do not reply only to the sender! Edit mailing list options or unsubscribe:
So the initial idea was to prolonge the expiry of the redis key within the timer. The expiration would be set to a value a bit higher than the timer interval. At each timer iteration, the key would be renewed. That way, if a call teardown occurs because of an unexpected event (so no BYE/CANCEL), the redis object would expire itself because the timer would stop running (and thus renewing the key) if the call transaction had ended? However, I can't do that since I need to get the call-id/extension within the timer route to pick the right key.
So my alternative would be to store the dialogs into redis and loop over those within the timer to compare them to the existing callstate keys. If a dialog would no longer be known, I could delete the matching callstate key. However, it appears that the dialogs aren't cleaned up during unexpected events so it's of no use neither?
Regards