#84 ✓resolved
dimas

Unable to process UserEvent

Reported by dimas | September 15th, 2009 @ 08:02 AM | in 1.0.0

When asterisk dialplan executes

UserEvent(qqq)

everything works and I'm able to read these events with Adhearsion with loop like:

require 'adhearsion/events_support' Adhearsion::Events.framework_theatre.start! Adhearsion::Events.register_callback %w[asterisk manager_interface] do |event|

puts event.inspect

end

i get

"#<Adhearsion::VoIP::Asterisk::Manager::ManagerInterfaceEvent:0xb7b646c8 @name="UserEvent", @headers={"Privilege"=>"user,all", "UserEvent"=>"qqq"}>"

However if i also specify event body:

UserEvent(qqq,aaa=bbb)

the loop above does not display anything.
I believe this is because Adhearsion can not properly read user events - do not know how the event text is terminated etc.

Comments and changes to this ticket

  • dimas

    dimas November 11th, 2009 @ 01:32 PM

    Issue still present in 0.8.3. As soon as UserEvent invoked with two parameters (eventname and body) AMI connection dies.

  • dimas

    dimas November 14th, 2009 @ 05:45 AM

    It seems there is no issue levels here at lighthouse so I would like to emphasize the fact that this issue is major. This is IMHO of course. But the fact is that any UserEvent with two parameters (event name + event body) executed by Asterisk dialplan immediately kills all Adhearsion applications listening for events. Adhearsion hangs reading that UserEvent and never able to read any following events.

  • Jay Phillips

    Jay Phillips November 14th, 2009 @ 01:36 PM

    • State changed from “new” to “open”

    The best way for my to debug issues like this with the AMI parser is to see a telnet exchange reproducing the exact text which the parser fails to parse.

    Could you telnet into your Asterisk server, login with events on, and show me the exact text that you receive for that UserEvent? So I can see how the frame is terminated, include the event after the UserEvent too please.

  • dimas

    dimas November 14th, 2009 @ 05:58 PM

    The dialplan is like

    UserEvent(justeventname);
    UserEvent(eventname,eventbody);
    Hangup;
    

    Events are:

    Event: Newexten
    Privilege: call,all
    Channel: SIP/1001-b7b1a790
    Context: default
    Extension: 111
    Priority: 1
    Application: UserEvent
    AppData: justeventname
    Uniqueid: 1258239297.33
    
    Event: UserEvent
    Privilege: user,all
    UserEvent: justeventname
    
    Event: Newexten
    Privilege: call,all
    Channel: SIP/1001-b7b1a790
    Context: default
    Extension: 111
    Priority: 2
    Application: UserEvent
    AppData: eventname|eventbody
    Uniqueid: 1258239297.33
    
    Event: UserEvent
    Privilege: user,all
    UserEvent: eventname
    eventbody
    
    Event: Hangup
    Privilege: call,all
    Channel: SIP/1001-b7b1a790
    Uniqueid: 1258239297.33
    Cause: 0
    Cause-txt: Unknown
    
  • Jay Phillips

    Jay Phillips November 14th, 2009 @ 08:21 PM

    Wow, okay, I see the problem now. This is an anomaly to the AMI protocol that I didn't foresee. At the moment only "Response: Follows" messages have bodies that follow them like that.

    Fixing this will require changing the parser to expect a totally new kind of event. I can do it but I risk breaking other parts of the parser so I need to be pretty careful. Let me tinker with this...

  • dimas

    dimas November 14th, 2009 @ 09:54 PM

    Researching Asterisk source code. Now I'm convinced they expect developer to format body as 'Header1;value,Header2:value' etc. Which of course makes sense.

    Which means the specific issue I'm reporting is void and can be closed.
    However... I believe I definitely identified a problem with protocol parser (lexer). Under no circumstances should it be dying like this. Even if input is complete garbage. Think about a situation when Asterisk is upgraded and now it can send one extra event which is slightly different from others. It will be unpleasant surprise if Adhearsion event connection will be hanging each time it encounters such an event.

    Unfortunately I do not understand lexer's grammar so I can not point you to some place I consider a problem :( but general logic to me is following:
    1. I would disallow values containing cr or lf just like key can not contain them.
    2. I would use loose_crlf everywhere in protocol not requiring strict crlf even if spec says so. In fact I would rename loose_newline to newline (just to shorten name) and would replace all (or most) usages of crlf to newline.
    3. I would allow any message to have a "rest_of_message" at the end. Where rest_of_message is just rest_of_line zero or more times.

    The main idea is to organize things in a way so double CRLF always break the current message/event - first CRLF breaks current line or keyvalue pair and the second serves as message terminator.(Of course with exception of Response: Follows case) This way we can loose one message if we can not parse it properly but we will re-sync on next 2xCRLF and will get next one successfully.

    And of course-of course-of course before doing things like this, we need some unit-test coverage for the lexer. You will sleep much safer knowing that some modification of a lexer you did does not break all other things. If you create some testing framework for the lexer, I can probably participate in adding more tests.

  • Ben Klang

    Ben Klang August 7th, 2010 @ 01:58 PM

    • Assigned user changed from “Jay Phillips” to “Ben Klang”
    • Milestone order changed from “0” to “0”

    This is a duplicate of ticket #58

  • Ben Klang

    Ben Klang August 7th, 2010 @ 02:02 PM

    • Milestone set to 0.8.5
    • Milestone order changed from “3025” to “0”

    Information from #58. Jason Goecke wrote:

    It appears that if a UserEvent is sent like this:

    exten => _X.,1,UserEvent(EVENTHIS|billing=yes)

    This is when Ragel gets confused. While on the other hand if you do something like:

    exten => _X.,1,UserEvent(LOGVARIABLES|invoice:yes)

    We then get the events in Adhearsion as follows:

    INFO event_logger: Adhearsion::VoIP::Asterisk::Manager::ManagerInterfaceEvent: #<Adhearsion::VoIP::Asterisk::Manager::ManagerInterfaceEvent:0x175f110 @headers={"invoice"=>"yes", "Privilege"=>"user,all", "UserEvent"=>"LOGVARIABLES"}, @name="UserEvent">

    Which corresponds to the AMI this way:

    Event: UserEvent
    Privilege: user,all
    UserEvent: LOGVARIABLES
    invoice:yes

    So, two things here:

    1. We need to ensure we document how to use custom events on the Wiki for Adhearsion to be done properly
    2. We need to ensure that the Ragel parsing is more robust so that it drops events not understood and moves on to the next one, as opposed to not parsing anything going forward
  • Ben Klang
  • Ben Klang

    Ben Klang August 24th, 2010 @ 04:37 PM

    • Milestone set to 0.8.6
    • Milestone order changed from “15” to “0”
  • Ben Klang

    Ben Klang September 3rd, 2010 @ 02:08 PM

    • Milestone changed from 0.8.6 to 1.0.0
  • Ben Klang

    Ben Klang October 21st, 2010 @ 06:57 PM

    • Tag set to documentation
  • Ben Klang

    Ben Klang October 23rd, 2010 @ 09:52 PM

    • State changed from “open” to “resolved”

    I have added notes regarding the nature of the problem to http://github.com/adhearsion/adhearsion/wiki/Events. I've tried to look at ways to modify the Ragel to try to make Adhearsion recover more gracefully but it looks difficult (if not impossible) to catch every possible piece of data a user might put in the custom event. Documentation is the best solution I have at the moment.

    Marking this resolved unless someone has any better ideas.

Please Sign in or create a free account to add a new ticket.

With your very own profile, you can contribute to projects, track your activity, watch tickets, receive and update tickets through your email and much more.

New-ticket Create new ticket

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile ยป

Shared Ticket Bins

People watching this ticket

Referenced by

Pages