views:

306

answers:

2

I'm trying to get the status of an Asterisk Server using a python socket but nothing happens.

Here is my code:

import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
HOST = '192.168.1.105'
PORT = 5038

s.connect((HOST, PORT))

params = """Action: login
Events: off
Username: admin
Secret: mypass

Action: status
Action: Logoff
"""

s.send(params)
data = s.recv(1024)
print data + '\n'
s.close()

I just get a message saying Asterisk Version and nothing more.

I hope somebody could help me with this.

Thanks in advance.

+1  A: 

You have malformed your code there. The Asterisk AMI requires \r\n termination between commands.

You need to send each command in a separate packet:

params = """Action: login
Events: off
Username: admin
Secret: mypass"""

s.send(params + '\r\n')
data = s.recv(1024)
print data + '\n'

params = 'Action: status'
s.send(params + '\r\n')
data = s.recv(1024)
print data + '\n'

params = 'Action: Logoff'
s.send(params + '\r\n')
data = s.recv(1024)
print data + '\n'

That should do the trick. Obviously you'll want to also make a function for it or whatever, but that will make it work.

Always separate AMI commands out!

b14ck
Thanks for your answer. I tried your solution but nothing happens when I execute:params = 'Action: status's.send(params + '\r\n')data = s.recv(1024)The Python console stays there and nothing more.
Harph
Do you have the correct permissions setup for your user account that you're running the AMI program under? Check out this page on voip-info (it contains a list of permissions required to execute that command):http://www.voip-info.org/wiki/view/Asterisk+Manager+API+Action+StatusAlso, don't test this in the python console. The delay of your typing will likely result in a time-out. Put your code into a python program and run it to get reliable results.
b14ck
+1  A: 

Handling of even such simple TCP based protocol may become tricky.

Problems in this case:

  1. Each line should be terminated with '\r\n' (not just '\n' as you send)
  2. You should receive all output or the connection may block. Please note, that output may came in multiple chunks (though, it will probably not happen in this case), which should be handled.

Try something like this:

import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
HOST = '192.168.1.105'
PORT = 5038

s.connect((HOST, PORT))

params = ["Action: login",
          "Events: off",
          "Username: admin",
          "Secret: mypass"]

s.send("\r\n".join(params) + "\r\n")

# receive login response
data = ""
while "\r\n" not in data:
    data += s.recv(1024)

s.send("Action: status\r\n\r\n")

# receive action response
data = ""
while "\r\n" not in data:
    data += s.recv(1024)
print repr(data)

s.send("Action: Logoff\r\n\r\n")
s.close()
Jacek Konieczny