Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incorrect pack deccoding on EventList. #26

Open
soloma83 opened this issue Nov 17, 2018 · 7 comments
Open

Incorrect pack deccoding on EventList. #26

soloma83 opened this issue Nov 17, 2018 · 7 comments

Comments

@soloma83
Copy link

Hello.
Unfortunately, AMIClient dispatches responses and events incorrectly.

There are a few types of responses which is marked as EventList. These responses contain a several elements divided by '\r\n\r\n'. As soon, AMIClient wait for this separator to finish pack it cannot catch these types of response.

For example, Action: Status. This action might respond with list of active channels.

Action: Status

Response: Success
EventList: start
Message: Channel status will follow

Event: Status
Privilege: Call
Channel: SIP/3030-00000002
ChannelState: 6
ChannelStateDesc: Up
CallerIDNum: 3030
CallerIDName: 3030
ConnectedLineNum:
ConnectedLineName:
Accountcode:
Context: exten-voicemail-sub
Exten: s
Priority: 5
Uniqueid: 1542489290.45
Type: SIP
DNID: 2020
EffectiveConnectedLineNum:
EffectiveConnectedLineName:
TimeToHangup: 0
BridgeID:
Linkedid: 1542489290.45
Application: VoiceMail
Data: 3030@default,b
Nativeformats: (ulaw)
Readformat: ulaw
Readtrans:
Writeformat: ulaw
Writetrans:
Callgroup: 0
Pickupgroup: 0
Seconds: 285

Event: StatusComplete
EventList: Complete
ListItems: 1
Items: 1

But AMIClient passes only first element.

def fire_recv_pack(self, pack):
print("Received pack: \n{}\n\n".format(pack))
if Response.match(pack):
response = Response.read(pack)
self.fire_recv_reponse(response)
return
if Event.match(pack):
event = Event.read(pack)
self.fire_recv_event(event)
return
self._fire_on_unknown(pack=pack)

Output is

Received pack:
Response: Success
ActionID: 1
EventList: start
Message: Channel status will follow

Received pack:
Event: StatusComplete
ActionID: 1
EventList: Complete
ListItems: 0
Items: 0

@romkazor
Copy link
Contributor

romkazor commented Nov 19, 2018

You should use callback method:

...
from asterisk.ami.action import SimpleAction


def callback_response(response):
    print(response)

action = SimpleAction('Status')
client.send_action(action,callback=callback_response)

Please, read the documentation and examples on the main page.

@soloma83
Copy link
Author

Hello.
I read documentation which said that I can use both syncronous and asyncronous requests.
And even if I use call back, it still returns incomplete response.

Code

def test_action(action_name):
    cl = AMIClient(**connection)
    cl.login(**login)
    act = SimpleAction(action_name)
    fut = cl.send_action(act, callback=print_response)
    cl.logoff()

def print_response(response):
    print(response)
    print(response.keys)
    print(response.follows)

Output.

>>> from ami_t import *
>>> test_action('status')
Response: Success
ActionID: 1
EventList: start
Message: Channel status will follow

{'ActionID': '1', 'EventList': 'start', 'Message': 'Channel status will follow'}
[]

My fix of client.py which works for me.

54a55,62
>     asterisk_start_list_regex = re.compile(
>         b'^Response: Success\r\nActionID: \d+\r\nEventList: start',
>         re.IGNORECASE | re.MULTILINE
>     )
>     asterisk_end_list_regex = re.compile(
>         b'EventList: Complete\r\n.+\r\n.+\r\n\r\n',
>         re.IGNORECASE | re.MULTILINE
>     )
163c171,177
<             while self.asterisk_pack_regex.search(data):
---
>             is_list = self.asterisk_start_list_regex.match(data)
>             list_ends = self.asterisk_end_list_regex.search(data)
>             if is_list and list_ends:
>                 ending = list_ends.group()
>                 (pack, data) = self.asterisk_end_list_regex.split(data, 1)
>                 yield self._decode_pack(pack + ending)
>             elif not is_list and self.asterisk_pack_regex.search(data):
165a180
> 

@ettoreleandrotognoli
Copy link
Owner

I think you need add a event listener, because the events is not part os the response even though they had been generated by the action and announced by the response

@ettoreleandrotognoli
Copy link
Owner

I want make a "helper" to get the events that follows a response with EventList: start but I'm without time these days

@soloma83
Copy link
Author

soloma83 commented Nov 21, 2018 via email

@soloma83
Copy link
Author

soloma83 commented Nov 21, 2018 via email

@ldo
Copy link

ldo commented Dec 3, 2022

You have to distinguish between events which are responses to actions, and ones which are unsolicited. The EventList header identifiers sequences of the former, which should all be treated as part of the response to the action.

You know how, on the Login action, there is an Events header? That’s where you specify whether you want to see unsolicited events or not.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants