Hii I am making a call from Manager AMI and in my dialPlan the caller will be connected to AGI.I want to send a variable var from AMI to AGI through channel variables
originateAction.setChannel("SIP/1000abc");
originateAction.setContext("outgoing-call");
originateAction.setExten("100");
originateAction.setVariable("var", "Say to the user that he sucks");
I tried all possible combination of outbound call but none of them working
[outgoing-call]
exten=>100,1,AGI(agi://127.0.0.1/hello.agi?user=${var})
[outgoing-call]
exten=>100,1,AGI(agi://127.0.0.1/hello.agi?var=${var})
[outgoing-call]
exten=>100,1,AGI(agi://127.0.0.1/hello.agi,${var})
AGI
public void service(AgiRequest request, AgiChannel channel)
throws AgiException
{
answer();
System.out.println("Inside");
String a=request.getParameter("var");
// String b=request.getParameter("user");
String c=channel.getVariable("var");
// String d=channel.getVariable("user");
System.out.println(a+"\n"+b+"\n"+c+"\n"+d+"\n");
hangup();
}
Output is null all the time.
The right way to pass argument to AGI in your dial plan is:
exten=>_0.,n,AGI(CALLyourAGI,${VARIABLE})
Before calling your AGI you can display in your CLI if the variable was really setted:
[outgoing-call]
exten=>100,1,NoOP(My Variable content ${var})
exten=>100,n,AGI(agi://127.0.0.1/hello.agi,${var})
Do not forget to set verbose in the CLI
ast*CLI> core set verbose 9999
Make a call and keep your eyes on it
Related
Im using C# AsterNET to manage my Asterisk commands and events, and now I do have a new feature to work on.
This is simple (I think) but I'm stucked right now.
Scenario
I do have two queues, 8100 and 8300, and 2 extensions being 8101 and 8301. When I do have a call from PSTN it is driven to 8100 queue. When the 8101 extension become available I do add this extension to the 8100 queue, so the calling PSTN device will be redirected to this 8101 extension.
Everything is working fine till here.
Sometimes I do park the calling device and let 8301 knows it using my app, so 8301 user using the same app can send a command asking for that parked channel to be redirect to his SIP Phone. Also working fine.
Scope
Now I want to have some feature to let 8101 transfer this calling device to my other queue, the 8300. So I just tried to reuse my parked method and redirect method
internal void Park(string channel, int parkTimeout)
{
ParkAction pa = new ParkAction(channel, channel, parkTimeout.ToString());
ManagerResponse mr = manager.SendAction(pa);
}
internal void RedirectFromParking(string channel, string exten)
{
RedirectAction ra = new RedirectAction
{
Priority = 1,
Context = "default",
Channel = channel,
Exten = exten
};
ManagerResponse mr = manager.SendAction(ra);
}
Park("abc123456", 10000);
RedirectFromParking("abc123456", "8300")
Issue
I'm parking fine but when I try to redirect from parking to my queue the calling device is just disconnected and the connection is lost.
How can I transfer a parked call to my queue or transfer it directly to the queue (would be better) without needing to originate?
Just do hold instead of parking and make your own list of such calls.
To transfer to a queue I can do a blind transfer as documented on Asterisk website. Links below:
ManagerAction_BlindTransfer
ManagerEvent_BlindTransfer
To achieve this using AsterNET, I can use the same RedirectAction I was using but I do need to change the context. It can't be default for context, as default we are letting Asterisk manage it and somehow it can't handle as I expetected. So it need to be clearly specified as internar transfer. The event raised after this context transfer is the Manager_BlindTransfer.
Manager_Action_RedirectAction
So using my SIP Phone I manage to transfer a call while I was debugging that raised event method, so I could catch the context used in. Using the correct context
ManagerConnection manager = new ManagerConnection(address, port, user, password);
manager.BlindTransfer += Manager_BlindTransfer;
private void Manager_BlindTransfer(object sender, BlindTransferEvent e)
{
}
After this I created another method to transfer to directly to a queue using the correct context.
internal void TransferToQueue(string channel, string queue)
{
RedirectAction ma = new RedirectAction
{
Priority = priority,
Context = "from-internal-xfer",
Channel = channel,
Exten = queue
};
ManagerResponse mr = manager.SendAction(ma);
}
TransferToQueue("abc123456", "8300")
Summary
Was just a matter of the correct context to be used in.
from-internal-xfer
I have set up FreePbx and it is working I can make calls into the pbx and out of the pbx. I have enabled the REST API and added a user and password. I cloned the Asternet.Ari https://github.com/skrusty/AsterNET.ARI.
The program runs and I get the connected event:
// Create a new Ari Connection
ActionClient = new AriClient(
new StasisEndpoint("192.168.1.14", 8088, "userId", "password"),
"HelloWorld");
// Hook into required events
ActionClient.OnStasisStartEvent += c_OnStasisStartEvent;
ActionClient.OnChannelDtmfReceivedEvent += ActionClientOnChannelDtmfReceivedEvent;
ActionClient.OnConnectionStateChanged += ActionClientOnConnectionStateChanged;
ActionClient.OnChannelCallerIdEvent += ActionClient_OnChannelCallerIdEvent;
ActionClient.Connect();
........
private static void ActionClientOnConnectionStateChanged(object sender)
{
Console.WriteLine("Connection state is now {0}", ActionClient.Connected);
}
The ActionClient is connected.
I then call in to a extension but nothing happens. I do not get any other events. Should an event fire when any extension is called? Not sure if I have set the pbx up correctly. I do not get any calling events when I call in from soft phone or from outside Lan on a cell phone.
Long time have passed but maybe useful yet.
Just set subscribeAllEvents argument to true.
ActionClient = new AriClient(
new StasisEndpoint("voip", 8088, "root", "password"),
"HelloWorld",
true);
Well your Asterisk Ari is connecting, but to get anything in it, you have to create Extension so your call go to Stasis application.
Please edit your extensions.conf file with following information
exten => _1XX,1,NoOp()
same => n,Stasis(HelloWorld,PJSIP/${EXTEN}, 45)
same => n,Hangup()
This script first check any incoming number which starts with 1 will be forawarded to your ARI script. HelloWorld is name of app so you alread have it in your script. Now any call come it will show whole information on your socket. Now you have to handle this information to any specific task.
\
I'm trying to connect to a D-Bus signal this way:
bool result = QDBusConnection::systemBus().connect(
"foo.bar", // service
"/foo/bar", // path
"foo.bar", // interface
"SignalSomething",
this,
SLOT(SignalSomethingSlot()));
if( !result )
{
// Why!?
}
QDBusConnection::connect() returns a boolean, how do I get extended error information? If a check QDBusConnection::lastError() it returns no useful information (as QDBusError::isValid() is false).
I had the same issue and it turned out that the slot I connected to had the wrong parameter types. They must match according to Qt's documentation and it looks like connect() verifies that, despite not explicitly mentioned.
Warning: The signal will only be delivered to the slot if the parameters match.
I suggest d-feet to list signals and check their parameter types. dbus-monitor does list signals, paths and such too, but not always the exact type of parameters.
One important observation though: I fixed the issue in my particular case by using different slot parameters than the actual signal has!
I wanted to connect to a com.ubuntu.Upstart0_6 signal mentioned here to detect when the screen in Ubuntu is locked/unlocked. dbusmonitor prints the following and d-feet shows parameters (String, Array of [String])
// dbusmonitor output
signal time=1529077633.579984 sender=:1.0 -> destination=(null destination) serial=809 path=/com/ubuntu/Upstart; interface=com.ubuntu.Upstart0_6; member=EventEmitted
string "desktop-unlock"
array [
]
Hence the signal should be of type
void screenLockChangedUbuntu(QString event, QVector<QString> args) // connect() -> false
This however made connect() return false. The solution was to remove the array parameter from the slot:
void screenLockChangedUbuntu(QString event) // works
I am aware that the array parameter was always empty, but I cannot explain why it only worked when removing it.
You could try these tricks:
1) Set QDBUS_DEBUG environment variable before running your application.
export QDBUS_DEBUG=1
2) Start dbus-monitor to see what's happening on the bus. You may need to set a global policy to be able to eavesdrop system bus depending on your distro.
Update:
Are you sure connecting to the system bus succeeded? If it fails you should probably check system.conf policy and possibly create own conf in system.d. This post might be helpful.
You could first connect to the system bus with QDBusConnection::connectToBus and check if it succeeded with QDBusConnection::isConnected. Only after that you try to connect to the signal and check if that succeeded.
QDBusConnection bus = QDBusConnection::connectToBus(QDBusConnection::systemBus, myConnectionName);
if (bus.isConnected())
{
if(!bus.connect( ... ))
{
// Connecting to signal failed
}
}
else
{
// Connecting to system bus failed
}
I am invoking multiple async calls of thrift from my code. I would like to wait
for all of them to complete before going on with my next stage.
for (...) {
TNonblockingTransport transport = new TNonblockingSocket(host, port);
TAsyncClientManager clientManager = new TAsyncClientManager();
TProtocolFactory protocolFactory = new TBinaryProtocol.Factory();
AsyncClient c = new AsyncClient(protocolFactory, clientManager, transport);
c.function(params, callback);
}
// I would like to wait for all the calls to be complete here.
I can have a countdown in the callback like wait/notify and get this done. But does the thrift system allow a way for me to wait on my async function call, preferably with a timeout ?
I didnt see any in the TAsyncClientManager or in the AsyncClient. Please help.
Given that it was not possible to do this, I used the sync api client and managed the launch and wait using executors and launchAll. I am leaving this as my answer for people to have an alternative.
I am using this part of code in the hub (with interface IConnected) of signalr. The problem is when I call Group.Add in Connect method, a client really isn't in the group and I can't send him a message throw this group. When I call later some method from the client to register in a group, everything is ok. What I don't understand, in both methods(in Connect() even in registerClientToGroup()) has the same Groups.Add method.
public System.Threading.Tasks.Task Connect()
{
Groups.Add(this.Context.ConnectionId, "group");
return null;
}
Some ideas? Thanks a lot.
I'm not sure if this is the direct cause of your problem, but I'm surprised you are not getting errors because you are returning a null value for the Task from Connect. You probably are getting errors, you're just not debugging/catching them.
If you don't have any other work to do in Connect that necessitates your own Task then simply return the Task from the call to Groups.Add like so:
public Task Connect()
{
return Groups.Add(this.Context.ConnectionId, "group");
}