Yate Community Forum
General Category => Yate users hangout place => Topic started by: ganapathi on October 22, 2018, 01:30:31 AM
-
Hi
As am using custom handling for Queue Incoming module. But unable to playback the ringtone or custom music to the customer end.
Here you can find the code : https://paste.linux.community/view/7d30f87c
Also tried to attach once channel connected as well with mentioned below code.
Message* m = new Message("chan.attach");
m->copyParam(msg, "id");
m->addParam("source", "tone/ring");
But there is no ringtone on customer end.
-
Some notes:
- Delete message after dispatch: memory leak
- Don't install a handler for each call in queue: install a module global one
- msg.getParam(YSTRING("id"))->c_str(): not a good idea if the 'id' parameter is missing this will lead to segfault
What is wrong:
You execute queue chan to tone. This will play ring in queue chan
When you attach queue chan to incoming call you the tone chan will be destroyed: not connected
To play ring you must use chan.attach to set tone source in desired call leg (in queue chan).
You may use the API (CallEndpoint::connect()) instead of call.connect message. Usual procedure of executing a call in a driver:
QueueInChannel* c = new QueueInChannel(dest,msg,false);
c->initChan();
DO_SETUP (attach tone source) ...
if (SETUP_OK) {
CallEndpoint* ch = YOBJECT(CallEndpoint,msg.userData());
if (ch && c->connect(ch,msg.getValue(YSTRING("reason")))) {
c->callConnect(msg);
msg.setParam("peerid",c->id());
msg.setParam("targetid",c->id());
c->deref();
return true;
}
}
CLEANUP ....
c->deref();
return false;
-
Thanks. Now Understand.
And here are few doubt.
- How do i call QueueInChannel destructor when Customer call hangup to emit chan.hangup and clean up the qin channel. Where am tracking chan.disconnected and dispatching the chan.hangup forcefully, eventhough qin channel not cleared.
- You are trying to say Delete the Message after dispatch of QueueInChannel or every message such as call.execute/chan.connect etc. If then how do delete the message ?. i didn't find any procedure to delete message in source and perfect time to delete message.
Instead of msg.getParam(YSTRING("id"))->c_str(), msg.getValue("id") is fine. Or i need to validate if id is exist or not to proceed further to avoid segfault.
-
- Don't install a handler for each call in queue: install a module global one
Using it only to pass the variable value where i am not sure how to pass variable and access it accordingly through-out the messages. And it would lead memory leak as well ?.
-
I don't understand.
If you are speaking about matching call leg id you may always retrieve a channel in driver list. See Driver class documentation.
There is no memory leak in message handlers: the Engine will remove them on shutdown.
You may track them (keep a pointer) and remove from Engine when necessary.
-
I meant to say am calling handler on every call only to pass some value like Queue name, partycallid etc. If i used global one then have no idea to get those value, where value is not available on every messages to utilize.
Is there any API functionalities available to push value and access it whenever required throughout the messages.
-
Please specify your intention.
What is the working case?
What parameter are you talking about and where do you want to store them?
Remember: chan.connected is automatically sent by a Channel when connected to another one.
-
As i need an billid, incoming channel ID(sig/1),queue_name and other some other value that's should necessary to validate some condition and append into another message.
For Ex :
Once call.answered message received from sip(sip/1) then need to emit chan.connect with sip/1 with sig/1. Where i can id for sip/1 but i need to get value of sig/1 through some variable. Like queue_name on chan.disconnected message need to emit new message to queue module.
And Also original billid which calls to queue module is not passing into Queue_Out Module, so need value to append to sip outleg.
Current Call.answered handler :
if (msg.getValue("id") == m_partycallid) {
msg.setParam("reason", "pickup");
return true;
}
else if (msg.getValue("targetid") == m_ourcallid)
{
msg.setParam("targetid", m_partycallid);
Message* mc = new Message("chan.connect");
mc->copyParam(msg, "id");
mc->addParam("targetid", m_partycallid);
Engine::dispatch(mc);
return true;
}
return false;
Value want to store :
- billid
- queue_name
- partycallid
- ..
Want to Store into Cache Memory/ Temp File Storage/ :
Store Like : JSON Object/Object List/Single Variable
Just for scenario ,It would be great if values are stored into ObjectList from Queue Module and access it on Queue_Outgoing Module.
-
When you are handling (parking) an incoming call you known its id.
When you are executing an outbound call you have the outgoing call id in call.execute when message returns from dispatch.
Just remember them.
You may track them as needed.
You may use chan.locate to obtain channel pointer.
You may obtain billid using API. See Channel documentation.
-
To get Billid with channel ID :
Message m("chan.locate");
m.addParam("id", m_partycallid);
if (Engine::dispatch(m)) {
Channel* c = new Channel(dest,m,true)
c->billid();
}
like this ?.
-
Please read https://docs.yate.ro/wiki/Chan.locate
Why do you think that locating a Channel implies building a new one?
You are searching for an item to check if it still exists and obtain some data from it
-
Sorry. Got it now.
Here is the right one. Also tested.
Message l("chan.locate");
l.addParam("id", msg.getValue("notify"));
if (Engine::dispatch(l)) {
Channel *dd = YOBJECT(Channel, l.userData());
Output("Billid:%s", dd->billid().c_str());
}
-
That's it!
For safety you should always check pointers (dd)
-
Sure.
In My cases dataEndpoint are linked like below :
Customer Channel <--> Queue_In Channel
Queue_Out Channel <--> Operator Channel
In this case if customer Channel hangup then how to terminate queue_out Channel forcefully , because here Queue_Out won't disconnect until operator channel disconnected.
Dispatching a chan.hangup or Call Destructor(~OueueOutChannel()) of channel is right way?.
-
For calling destructor see response on irc channel.
chan.hangup vever terminates a call leg: it's a notification sent by a call leg that protocol (external) call was terminated.
Use call.drop message to terminate a call leg.
-
Thanks a lot. Got it
-
To play ring you must use chan.attach to set tone source in desired call leg (in queue chan).
QueueInChannel* c = new QueueInChannel(dest,msg,false);
c->initChan();
DO_SETUP (attach tone source) ...
Like this ?.
Message m("chan.attach");
m->addParam("id",c->id());
m->addparam("source","tone/ring");
Engine::dispatch(m);
or
Message m("chan.masquerde");
m->addParam("message","chan.attach");
m->addParam("id",c->id());
m->addparam("source","tone/ring");
Engine::dispatch(m);
or any other way. Mentioned both looks not working for me..
-
Why would you want to masquerade a message when you already have the channel in hand?
chan.masquerade will be handled by your Driver anyway.
Don't forget to put channel in message's user data.
-
So this is fine ?
Message m("chan.attach");
m->addParam("id",c->id());
m->addparam("source","tone/ring");
Engine::dispatch(m);
How do i push channel in message's user data ?? - Setting peerid & targetid to current channel id rgt ?.
-
Please take a look at Message class API.
-
As I seen everything looks fine but now only understand qin channel not getting hang-up once customer call got hang-up.
As I hope assigned userData properly I think. but don't know where is the mistake.
here is the code :
http://dpaste.com/1N1P73G
here is the log :
http://dpaste.com/2VWKMNE
-
Message* m = new Message("chan.masquerade");
....
Engine::dispatch(m);
Engine::dispatch() don't release the object.
Dispatch is assuming you need data on return!
You must delete it after dispatch or call Engine::enqueue()
-
Thanks. Now it's hangup properly.
Where outgoing channel ringing message emitted ,Even though ringtime is not calculated properly for incoming channel. is there any missed here.
incoming channel:
param['chan'] = 'sig/1'
param['cdrid'] = '1'
param['runid'] = '1544733185'
param['operation'] = 'finalize'
param['direction'] = 'incoming'
param['duration'] = '5.434'
param['billtime'] = '0.000'
param['ringtime'] = '0.000'
Outgoing channel :
param['chan'] = 'sip/1'
param['cdrid'] = '2'
param['runid'] = '1544733185'
param['operation'] = 'finalize'
param['direction'] = 'outgoing'
param['duration'] = '5.371'
param['billtime'] = '0.000'
param['ringtime'] = '5.079'
-
Most probably call.ringing is not forwarded on incoming call leg.