Esempio n. 1
0
        /// <summary>
        /// Ok - if we get here (!) then we have a valid event associated with a
        /// specific call. We should handle the event (obviously!) appropriately.
        /// </summary>
        /// <param name="ws">The web_service request to process</param>
        ///
        protected virtual void HandleEvent(RESTapi.web_service ws)
        {
            RESTapi.@event @event = ws.Item as RESTapi.@event;

            LoggingSingleton.Instance.Message(LogType.Library, LogLevel.Event,
                                              "Call::HandleEvent : Processing event \"{0}\"",
                                              @event.type.ToString());

            this._LastEvent     = ws.Item as RESTapi.@event;
            this._LastEventData = null;

            if (this._LastEvent.event_data != null)
            {
                this._LastEventData = this._LastEvent.event_data.ToDictionary(x => x.name, x => x.value);

                /*string _Buf = "";
                 *
                 * foreach (KeyValuePair<string, string> kv in this._LastEventData)
                 * {
                 * _Buf += string.Format("  => {0}->{1}\n", kv.Key, kv.Value);
                 * }
                 *
                 * Logger.LogMessage("Call::HandleEvent : Event has associated event data:\n{0}", _Buf);*/
            }

            switch (@event.type)
            {
            case RESTapi.event_type.incoming:
                this.CallState = CallStateType.Ringing;
                OnIncoming();
                break;

            case RESTapi.event_type.ringing:
                this.CallState = CallStateType.Ringing;
                OnRinging();
                break;

            case RESTapi.event_type.accepted:
                this.CallState = CallStateType.Ringing;
                OnAccepted();
                break;

            case RESTapi.event_type.answered:
            case RESTapi.event_type.connected:
                this.CallState = CallStateType.Connected;
                OnConnected();
                break;

            case RESTapi.event_type.alarm:
                OnAlarm();
                break;

            case RESTapi.event_type.dtmf:
                OnDtmf();
                break;

            case RESTapi.event_type.end_play:
                OnEndPlay();
                break;

            case RESTapi.event_type.hangup:
                this.CallState = CallStateType.Hangup;
                OnHangup();
                break;

            default:
                LoggingSingleton.Instance.Message(LogType.Library, LogLevel.Error,
                                                  "Call::HandleEvent : Unhandled event \"{0}\"",
                                                  @event.type.ToString());
                break;
            }
        }
        /// <summary>
        /// We received a web_service object to process... this function will
        /// determine if the request is for a new call or an existing call.
        /// Additionally, if the request is a hangup, we should delete the call
        /// from our list.
        /// </summary>
        /// <param name="ws"> The web_service request to process</param>
        ///
        public void ProcessRequest(RESTapi.web_service ws)
        {
            T currentCall = null;

            RESTapi.@event @event = ws.Item as RESTapi.@event;

            if (@event.type == RESTapi.event_type.keepalive)
            {
                LoggingSingleton.Instance.Message(LogType.Library, LogLevel.Debug1,
                                                  "CallDispatcher::ProcessRequest : Keepalive received");
                return;
            }

            String response = RestHelpers.RESTapiToXML(ws, typeof(RESTapi.web_service));

            LoggingSingleton.Instance.Message(LogType.Library, LogLevel.Debug1,
                                              "CallDispatcher::ProcessRequest : Received web service request :\n{0}",
                                              response);

            if (@event.type == RESTapi.event_type.incoming)
            {
                /// Note that we probably should check that this is not an existing
                /// call / resource id rather than assuming...
                ///
                currentCall = new T()
                {
                    Dispatcher   = this as ICallDispatcher <CallBase>,
                    Direction    = "inbound",
                    ResourceID   = @event.resource_id,
                    ResourceType = @event.resource_type,
                    CallState    = CallBase.CallStateType.Ringing,
                };

                foreach (RESTapi.event_data data in @event.event_data)
                {
                    switch (data.name.ToLower())
                    {
                    case "caller_uri": currentCall.CallerUri = data.value; break;

                    case "called_uri": currentCall.CalledUri = data.value; break;

                    case "uri":        currentCall.Uri = data.value; break;

                    case "name":       currentCall.Name = data.value; break;
                    }
                }
            }
            else
            {
                foreach (T call in Calls)
                {
                    if (call.ResourceID == @event.resource_id)
                    {
                        currentCall = call;
                        break;
                    }
                }
            }

            if (currentCall != null)
            {
                /// The following is a way of calling a protected / private member
                /// of a class - kind of like using "friend class" in C++. It uses
                /// reflection.
                ///
                MethodInfo handleEventMethod = currentCall.GetType().GetMethod("HandleEvent", BindingFlags.Instance | BindingFlags.NonPublic);

                switch (@event.type)
                {
                case RESTapi.event_type.incoming:
                    Calls.Add(currentCall);
                    handleEventMethod.Invoke(currentCall, new object[] { ws });
                    break;

                case RESTapi.event_type.hangup:
                    handleEventMethod.Invoke(currentCall, new object[] { ws });
                    Calls.Remove(currentCall);
                    break;

                default:
                    handleEventMethod.Invoke(currentCall, new object[] { ws });
                    break;
                }
            }
        } /* ProcessRequest() */