/// <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() */