machine.rl

Path: lib/adhearsion/voip/asterisk/ami/machine.rl
Last Update: Wed Mar 05 15:31:30 -0800 2008

module Adhearsion

        module VoIP
                module Asterisk
                        class AMI
                                module Machine
                                %%{
                                    machine ami;

                                                cr = "\r";
                                                lf = "\n";
                                                crlf = cr lf;

                                                action _key       { mark("key")        }
                                                action key                { set("key");                }
                                                action _value { mark("value") }
                                                action value      { set("value"); }
                                                Attr = [a-zA-Z\-]+ >_key %key ': ' (any* -- crlf) >_value %value crlf;
                                                Privilege = "Privilege" >_key %key ': ' (any* -- crlf) >_value %value crlf;
                                                ActionID = "ActionID" >_key %key ': ' (any* -- crlf) >_value %value crlf;

                                                action _event { mark("event") }
                                                action event      { set("event"); @current_packet = EventPacket.new(@__ragel_event) }
                                                Event = "Event: " alpha+ >_event %event crlf;

                                                action _success { @current_packet = Packet.new; }
                                                action _error     { @current_packet = ErrorPacket.new; }
                                                Response  = "Response: ";
                                                Success           = Response "Success" >_success crlf;
                                                Pong                      = Response "Pong" >_success crlf;
                                                Error             = Response "Error" >_error crlf;
                                                Events            = Response "Events " ("On" | "Off") >_success crlf;

                                                action _follows { @current_packet = FollowsPacket.new; }
                                                Follows           = Response "Follows" >_follows crlf;
                                                EndFollows        = "--END COMMAND--" crlf;

                                                # Capture the prompt. Signal any waiters.
                                                Prompt = "Asterisk Call Manager/";
                                                prompt := |*
                                                        graph+   >{ mark("version"); };
                                                        crlf             >{ set("version"); @signal.signal } => { fgoto main; };
                                                        *|;

                                                # For typical commands with responses with headers
                                                response_normal := |*
                                                        Attr => { pair; };
                                                        crlf => { packet; fgoto main; };
                                                        *|;

                                                # For immediate or raw commands
                                                Raw = (any+ >{ mark_array("raw"); } -- lf) lf;

                                                # For immediate or raw commands
                                                Imm = (any+ >{ mark_array("raw") } -- crlf) crlf %{ insert("raw") };

                                                # For raw commands
                                                response_follows := |*
                                                        Privilege                        => { pair; };
                                                        ActionID                                 => { pair; };
                                                        Raw                                              => { insert("raw") };
                                                        EndFollows crlf => { packet; fgoto main; };
                                                        *|;

                                                main := |*
                                                        Prompt   @{ fgoto prompt;                                                 };
                                                        Success @{ fgoto response_normal;        };
                                                        Pong             @{ fgoto response_normal;         };
                                                        Error    @{ fgoto response_normal;         };
                                                        Event    @{ fgoto response_normal;         };
                                                        Events   @{ fgoto response_normal;        };
                                                        Follows @{ fgoto response_follows;       };

                                                        # Must also handle immediate responses with raw data
                                                        Imm crlf crlf => { @current_packet = ImmediatePacket.new; packet; };
                                                *|;
                                }%%

                                        class << self
                                                def extended(base)
                                                        # Rename the Ragel variables. Not strictly necessary if
                                                        # we were to make accessors for them.
                                                        base.instance_eval do
                                                                %%{
                                                                        variable p @__ragel_p;
                                                                        variable pe @__ragel_pe;
                                                                        variable cs @__ragel_cs;
                                                                        variable act @__ragel_act;
                                                                        variable data @__ragel_data;
                                                                        variable tokstart @__ragel_tokstart;
                                                                        variable tokend @__ragel_tokend;
                                                                        write data nofinal;
                                                                }%%
                                                        end
                                                end
                                        end

                                        private
                                        def ragel_init
                                                %% write init;
                                        end

                                        def ragel_exec
                                                %% write exec;
                                        end
                                end
                        end
                end
        end

end

[Validate]