private ConferenceUser GetUser(FSEvent evt) { String member_id = evt.get_header("Member-ID"); ConferenceUser user = (from u in users where u.id == member_id select u).FirstOrDefault(); return(user); }
private void BroadcastEvent(FSEvent evt) { if (NewEvent != null) { NewEvent(this, evt); } }
private static void HandleCustomEvent(FSEvent evt, string uuid) { if (evt.subclass_name == "portaudio::ringing") { Utils.DebugEventDump(evt); if ((from c in calls where c._leg_a_uuid == uuid && c.call_ended == false select c).Count() > 0) //only care about first ring { return; } Call call = new Call(); call.SetCallInfoFromEvent(evt); String gw_id = (from c in channels where c.Key == call.leg_b_uuid select c.Value.gateway_id).SingleOrDefault(); call.account = (from a in Account.accounts where a.gateway_id == gw_id select a).SingleOrDefault(); calls.Add(call); call.UpdateCallState(CALL_STATE.Ringing, active_call ?? call); } else if (evt.subclass_name == "portaudio::makecall") { Utils.DebugEventDump(evt); if (evt.get_header("fail") == "true") { MessageBox.Show("Make Call failed!!!, came from portaudio not sure why"); return; } Call call = new Call(); call.is_outgoing = true; call.SetCallInfoFromEvent(evt); if (call.other_party_number == "fsc_conference") { call.visibility = Visibility.Collapsed; Conference.instance.our_conference_call = call; call.is_conference_call = true; } calls.Add(call); call.UpdateCallState(call.is_conference_call ? CALL_STATE.Answered : CALL_STATE.Ringing, call); } else if (evt.subclass_name == "portaudio::callheld" || evt.subclass_name == "portaudio::callresumed") { String paid_str = evt.get_header("variable_pa_call_id"); if (String.IsNullOrEmpty(paid_str)) { return; } int portaudio_id = Int32.Parse(paid_str); Call call = (from c in calls where c.portaudio_id == portaudio_id && c.call_ended == false select c).SingleOrDefault(); if (call == null) { return; } if (evt.subclass_name == "portaudio::callresumed") { call.UpdateCallState(CALL_STATE.Answered, call); } else { call.UpdateCallState(call.state == CALL_STATE.Ringing ? CALL_STATE.Hold_Ringing : CALL_STATE.Hold, call == active_call ? null : active_call); } } }
private static void HandleDTMFEvent(FSEvent evt, string uuid) { String digit = evt.get_header("DTMF-Digit"); var call = (from c in calls where (c.leg_a_uuid == uuid || c.leg_b_uuid == uuid) && c.call_ended == false select c).SingleOrDefault(); if (call != null && call.state == CALL_STATE.Answered && digit.Length == 1) { PortAudio.PlayDTMF(digit[0], call.leg_a_uuid); } }
public static void HandleOutgoingEvent(FSEvent evt, String uuid) //capture an outgoing call the other leg { String other_leg = evt.get_header("Other-Leg-Unique-ID"); Call call = (from c in calls where c.leg_a_uuid == other_leg && c.call_ended == false select c).SingleOrDefault(); if (call == null || !call.is_outgoing) { return; } call.leg_b_uuid = uuid; }
public static void HandleGatewayEvent(FSEvent evt) { String gateway = evt.get_header("Gateway"); Account account = (from a in accounts where a.gateway_id == gateway select a).SingleOrDefault(); if (account == null) { return; } account.state = evt.get_header("State"); }
public static void NewEvent(object sender, FSEvent evt) { switch (evt.event_id) { case switch_event_types_t.SWITCH_EVENT_CUSTOM: if (evt.subclass_name == "sofia::gateway_state") { HandleGatewayEvent(evt); } break; } }
public static void HandleHangupCompleteEvent(FSEvent evt, String uuid) { Utils.DebugEventDump(evt); Call call = (from c in calls where c.call_ended == false && (c.leg_a_uuid == uuid || c.leg_b_uuid == uuid) select c).SingleOrDefault(); if (call == null || call.call_ended) { return; } CALL_STATE new_state = CALL_STATE.None; if (call.state != CALL_STATE.Answered && call.state != CALL_STATE.Missed && call.state != CALL_STATE.Hold) { if (String.IsNullOrEmpty(call.note)) { call.note = evt.get_header("variable_sip_hangup_phrase"); } if (!call.is_outgoing && call.state == CALL_STATE.Ringing) { new_state = CALL_STATE.Missed; } else { new_state = CALL_STATE.Failed; } } else if (call.state == CALL_STATE.Answered || call.state == CALL_STATE.Hold) { new_state = CALL_STATE.Ended; } if (new_state == CALL_STATE.None) { throw new Exception("Not sure what happened call was at state...: " + call.state); } Call new_active_call; if (Call.active_call != call) { new_active_call = Call.active_call; } else { new_active_call = (from c in calls where c.state == CALL_STATE.Ringing && c.is_outgoing == false && c != call select c).FirstOrDefault(); } call.UpdateCallState(new_state, new_active_call); }
public static void DebugEventDump(FSEvent evt) { #if DEBUG_LOG_EVENTS String event_dump = evt.event_id.ToString(); if (!String.IsNullOrEmpty(evt.subclass_name)) event_dump += " " + evt.subclass_name; event_dump += ":\n"; switch_event_header hdr = evt.first_header; while (hdr != null) { event_dump += "\t" + hdr.name + ": " + hdr.value + "\n"; hdr = hdr.next; } DebugWrite(event_dump + "\n"); #endif }
private static void handleChannelCreateEvent(FSEvent evt, string uuid) { Channel c; if (!channels.TryGetValue(uuid, out c)) { c = new Channel(); channels.Add(uuid, c); } String gateway = evt.get_header("variable_sip_gateway"); if (!String.IsNullOrEmpty(gateway)) { c.gateway_id = gateway; } }
private void SetCallInfoFromEvent(FSEvent evt) { leg_a_uuid = evt.get_header("Unique-ID"); leg_b_uuid = evt.get_header("Other-Leg-Unique-ID"); if (is_outgoing) { bool is_sip_direct = false; if (DestNumberRegex == null) { DestNumberRegex = new Regex("sofia/gateway/([0-9]+)/(.+)", RegexOptions.Compiled); } Match match = DestNumberRegex.Match(evt.get_header("Caller-Destination-Number")); if (!match.Success) { if (DestSipRegex == null) { DestSipRegex = new Regex("gw_ref=([0-9]+)}sofia/softphone/(.+)", RegexOptions.Compiled); } match = DestSipRegex.Match(evt.get_header("Caller-Destination-Number")); is_sip_direct = true; } if (match.Success && match.Groups.Count == 3) { String gw_id = match.Groups[1].Value; account = (from a in Account.accounts where a.gateway_id == gw_id select a).SingleOrDefault(); other_party_number = is_sip_direct ? "sip:" + match.Groups[2].Value : match.Groups[2].Value; } } else { other_party_name = evt.get_header("Caller-Caller-ID-Name"); other_party_number = evt.get_header("Caller-Caller-ID-Number"); } if (String.IsNullOrEmpty(other_party_name)) { other_party_name = other_party_number; } String paid_str = evt.get_header("variable_pa_call_id"); if (!String.IsNullOrEmpty(paid_str)) { portaudio_id = Int32.Parse(paid_str); } }
public static void DebugEventDump(FSEvent evt) { #if DEBUG_LOG_EVENTS String event_dump = evt.event_id.ToString(); if (!String.IsNullOrEmpty(evt.subclass_name)) { event_dump += " " + evt.subclass_name; } event_dump += ":\n"; switch_event_header hdr = evt.first_header; while (hdr != null) { event_dump += "\t" + hdr.name + ": " + hdr.value + "\n"; hdr = hdr.next; } DebugWrite(event_dump + "\n"); #endif }
public static void NewFSEvent(object sender, FSEvent evt) { if (evt.event_id != switch_event_types_t.SWITCH_EVENT_MODULE_LOAD) { Utils.DebugEventDump(evt); } String uuid = evt.get_header("Unique-ID"); switch (evt.event_id) { case switch_event_types_t.SWITCH_EVENT_CHANNEL_CREATE: handleChannelCreateEvent(evt, uuid); break; case switch_event_types_t.SWITCH_EVENT_CHANNEL_OUTGOING: HandleOutgoingEvent(evt, uuid); break; case switch_event_types_t.SWITCH_EVENT_CHANNEL_HANGUP_COMPLETE: HandleHangupCompleteEvent(evt, uuid); break; case switch_event_types_t.SWITCH_EVENT_CHANNEL_ANSWER: String dest = "Caller-Destination-Number"; if (dest != "fsc_conference") { HandleChannelAnswerEvent(evt, uuid); } break; case switch_event_types_t.SWITCH_EVENT_CUSTOM: HandleCustomEvent(evt, uuid); break; case switch_event_types_t.SWITCH_EVENT_CHANNEL_DESTROY: channels.Remove(uuid); break; case switch_event_types_t.SWITCH_EVENT_DTMF: HandleDTMFEvent(evt, uuid); break; } }
private static void HandleChannelAnswerEvent(FSEvent evt, String uuid) { Call call = (from c in calls where c.leg_b_uuid == uuid && c.call_ended == false select c).SingleOrDefault(); if (call == null) { String orig_dest = evt.get_header("Other-Leg-Destination-Number"); if (orig_dest != "auto_answer") { return; } call = new Call(); call.SetCallInfoFromEvent(evt); String gw_id = (from c in channels where c.Key == call.leg_b_uuid select c.Value.gateway_id).SingleOrDefault(); call.account = (from a in Account.accounts where a.gateway_id == gw_id select a).SingleOrDefault(); calls.Add(call); call.UpdateCallState(CALL_STATE.Ringing, call); } if (call.state == CALL_STATE.Answered) { return; } if (call.state == CALL_STATE.Ringing || (call.state == CALL_STATE.Hold_Ringing && !call.is_outgoing)) { call.UpdateCallState(CALL_STATE.Answered, (call.is_outgoing || call.is_conference_call) ? active_call : call); } else if (call.state == CALL_STATE.Hold_Ringing) { call.UpdateCallState(CALL_STATE.Hold, active_call); } else { throw new Exception("Unknown state, call answered but was not in a state of hold_ring or ringing"); } }
private void SetCallInfoFromEvent(FSEvent evt) { leg_a_uuid = evt.get_header("Unique-ID"); leg_b_uuid = evt.get_header("Other-Leg-Unique-ID"); if (is_outgoing) { bool is_sip_direct = false; if (DestNumberRegex == null) DestNumberRegex = new Regex("sofia/gateway/([0-9]+)/(.+)", RegexOptions.Compiled); Match match = DestNumberRegex.Match(evt.get_header("Caller-Destination-Number")); if (! match.Success){ if (DestSipRegex == null) DestSipRegex = new Regex("gw_ref=([0-9]+)}sofia/softphone/(.+)", RegexOptions.Compiled); match = DestSipRegex.Match(evt.get_header("Caller-Destination-Number")); is_sip_direct = true; } if (match.Success && match.Groups.Count == 3) { String gw_id = match.Groups[1].Value; account = (from a in Account.accounts where a.gateway_id == gw_id select a).SingleOrDefault(); other_party_number = is_sip_direct ? "sip:" + match.Groups[2].Value : match.Groups[2].Value; } } else { other_party_name = evt.get_header("Caller-Caller-ID-Name"); other_party_number = evt.get_header("Caller-Caller-ID-Number"); } if (String.IsNullOrEmpty(other_party_name)) other_party_name = other_party_number; String paid_str = evt.get_header("variable_pa_call_id"); if (!String.IsNullOrEmpty(paid_str)) portaudio_id = Int32.Parse(paid_str); }
private static void HandleDTMFEvent(FSEvent evt, string uuid) { String digit = evt.get_header("DTMF-Digit"); var call = (from c in calls where (c.leg_a_uuid == uuid || c.leg_b_uuid == uuid) && c.call_ended==false select c).SingleOrDefault(); if (call != null && call.state == CALL_STATE.Answered && digit.Length == 1) PortAudio.PlayDTMF(digit[0], call.leg_a_uuid); }
private static void HandleCustomEvent(FSEvent evt, string uuid) { if (evt.subclass_name == "portaudio::ringing") { Utils.DebugEventDump(evt); if ((from c in calls where c._leg_a_uuid == uuid && c.call_ended == false select c).Count() > 0)//only care about first ring return; Call call = new Call(); call.SetCallInfoFromEvent(evt); String gw_id = (from c in channels where c.Key == call.leg_b_uuid select c.Value.gateway_id).SingleOrDefault(); call.account = (from a in Account.accounts where a.gateway_id == gw_id select a).SingleOrDefault(); calls.Add(call); call.UpdateCallState(CALL_STATE.Ringing, active_call ?? call); } else if (evt.subclass_name == "portaudio::makecall") { Utils.DebugEventDump(evt); if (evt.get_header("fail") == "true") { MessageBox.Show("Make Call failed!!!, came from portaudio not sure why"); return; } Call call = new Call(); call.is_outgoing = true; call.SetCallInfoFromEvent(evt); if (call.other_party_number == "fsc_conference"){ call.visibility = Visibility.Collapsed; Conference.instance.our_conference_call = call; call.is_conference_call = true; } calls.Add(call); call.UpdateCallState(call.is_conference_call ? CALL_STATE.Answered : CALL_STATE.Ringing, call); } else if (evt.subclass_name == "portaudio::callheld" || evt.subclass_name == "portaudio::callresumed") { String paid_str = evt.get_header("variable_pa_call_id"); if (String.IsNullOrEmpty(paid_str)) return; int portaudio_id = Int32.Parse(paid_str); Call call = (from c in calls where c.portaudio_id == portaudio_id && c.call_ended == false select c).SingleOrDefault(); if (call == null) return; if (evt.subclass_name == "portaudio::callresumed") call.UpdateCallState(CALL_STATE.Answered, call); else call.UpdateCallState(call.state == CALL_STATE.Ringing ? CALL_STATE.Hold_Ringing : CALL_STATE.Hold, call == active_call ? null : active_call); } }
private static void handleChannelCreateEvent(FSEvent evt, string uuid) { Channel c; if (!channels.TryGetValue(uuid, out c)) { c = new Channel(); channels.Add(uuid, c); } String gateway = evt.get_header("variable_sip_gateway"); if (!String.IsNullOrEmpty(gateway)) c.gateway_id = gateway; }
private static void HandleChannelAnswerEvent(FSEvent evt, String uuid) { Call call = (from c in calls where c.leg_b_uuid == uuid && c.call_ended == false select c).SingleOrDefault(); if (call == null){ String orig_dest = evt.get_header("Other-Leg-Destination-Number"); if (orig_dest != "auto_answer") return; call = new Call(); call.SetCallInfoFromEvent(evt); String gw_id = (from c in channels where c.Key == call.leg_b_uuid select c.Value.gateway_id).SingleOrDefault(); call.account = (from a in Account.accounts where a.gateway_id == gw_id select a).SingleOrDefault(); calls.Add(call); call.UpdateCallState(CALL_STATE.Ringing, call); } if (call.state == CALL_STATE.Answered) return; if (call.state == CALL_STATE.Ringing || (call.state == CALL_STATE.Hold_Ringing && !call.is_outgoing)) call.UpdateCallState(CALL_STATE.Answered, (call.is_outgoing || call.is_conference_call) ? active_call : call); else if (call.state == CALL_STATE.Hold_Ringing) call.UpdateCallState(CALL_STATE.Hold, active_call); else throw new Exception("Unknown state, call answered but was not in a state of hold_ring or ringing"); }
public static void HandleHangupCompleteEvent(FSEvent evt, String uuid) { Utils.DebugEventDump(evt); Call call = (from c in calls where c.call_ended == false && (c.leg_a_uuid == uuid || c.leg_b_uuid == uuid) select c).SingleOrDefault(); if (call == null || call.call_ended) return; CALL_STATE new_state = CALL_STATE.None; if (call.state != CALL_STATE.Answered && call.state != CALL_STATE.Missed && call.state != CALL_STATE.Hold) { if (String.IsNullOrEmpty(call.note)) call.note = evt.get_header("variable_sip_hangup_phrase"); if (!call.is_outgoing && call.state == CALL_STATE.Ringing) new_state = CALL_STATE.Missed; else new_state = CALL_STATE.Failed; } else if (call.state == CALL_STATE.Answered || call.state == CALL_STATE.Hold) new_state = CALL_STATE.Ended; if (new_state == CALL_STATE.None) throw new Exception("Not sure what happened call was at state...: " + call.state); Call new_active_call; if (Call.active_call != call) new_active_call = Call.active_call; else new_active_call = (from c in calls where c.state == CALL_STATE.Ringing && c.is_outgoing == false && c != call select c).FirstOrDefault(); call.UpdateCallState(new_state, new_active_call); }
private ConferenceUser GetUser(FSEvent evt) { String member_id = evt.get_header("Member-ID"); ConferenceUser user = (from u in users where u.id == member_id select u).FirstOrDefault(); return user; }
public void NewFSEvent(object sender, FSEvent evt) { if (evt.event_id != switch_event_types_t.SWITCH_EVENT_CUSTOM || evt.subclass_name != "conference::maintenance" || evt.get_header("Conference-Name") != "fsc_conference") return; String type = evt.get_header("Action"); ConferenceUser user; switch (type) { case "add-member": String member_id = evt.get_header("Member-ID"); String uuid = evt.get_header("Unique-ID"); String source = evt.get_header("Caller-Source"); String direction = evt.get_header("Call-Direction"); user = new ConferenceUser { id = member_id, uuid = uuid, party_name = evt.get_header("Caller-Caller-ID-Name"), party_number = evt.get_header("Caller-Caller-ID-Number") }; if (source == "mod_portaudio" && direction == "inbound") { user.party_number = user.party_name = "You"; user.is_us = true; } users.Add(user); break; case "del-member": user = GetUser(evt); if (user == null) return; users.Remove(user); break; case "start-talking": user = GetUser(evt); if (user == null) return; user.state |= ConferenceUser.USER_STATE.TALK; break; case "stop-talking": user = GetUser(evt); if (user == null) return; user.state ^= ConferenceUser.USER_STATE.TALK; break; case "floor-change": user = GetUser(evt); if (user == null) return; foreach (var u in users) u.state ^= ConferenceUser.USER_STATE.FLOOR; user.state |= ConferenceUser.USER_STATE.FLOOR; break; } }
private void BroadcastEvent(FSEvent evt) { if (NewEvent != null) NewEvent(this, evt); }
private void SetCallInfoFromEvent(FSEvent evt) { leg_a_uuid = evt.get_header("Unique-ID"); leg_b_uuid = evt.get_header("Other-Leg-Unique-ID"); if (is_outgoing) { bool is_sip_direct = false; if (DestNumberRegex == null) { DestNumberRegex = new Regex("sofia/gateway/([0-9]+)/(.+)", RegexOptions.Compiled); } Match match = DestNumberRegex.Match(evt.get_header("Caller-Destination-Number")); if (!match.Success) { if (DestSipRegex == null) { DestSipRegex = new Regex("gw_ref=([0-9]+)}sofia/softphone/(.+)", RegexOptions.Compiled); } match = DestSipRegex.Match(evt.get_header("Caller-Destination-Number")); is_sip_direct = true; } if (match.Success && match.Groups.Count == 3) { String gw_id = match.Groups[1].Value; account = (from a in Account.accounts where a.gateway_id == gw_id select a).SingleOrDefault(); other_party_number = is_sip_direct ? "sip:" + match.Groups[2].Value : match.Groups[2].Value; } } else { other_party_name = evt.get_header("Caller-Caller-ID-Name"); other_party_number = evt.get_header("Caller-Caller-ID-Number"); } if (CALL_NUMBER_PREFIX_STRIPS != null) { foreach (var strip in CALL_NUMBER_PREFIX_STRIPS) { if (strip.min_length != 0 && other_party_number.Length < strip.min_length) { continue; } if (strip.max_length != 0 && other_party_number.Length > strip.max_length) { continue; } if (!String.IsNullOrWhiteSpace(strip.starts_with) && other_party_number.StartsWith(strip.starts_with)) { other_party_number = other_party_number.Substring(strip.starts_with.Length); break; } } } if (String.IsNullOrEmpty(other_party_name)) { other_party_name = other_party_number; } String paid_str = evt.get_header("variable_pa_call_id"); if (!String.IsNullOrEmpty(paid_str)) { portaudio_id = Int32.Parse(paid_str); } }
public static void NewEvent(object sender, FSEvent evt) { switch (evt.event_id) { case switch_event_types_t.SWITCH_EVENT_CUSTOM: if (evt.subclass_name == "sofia::gateway_state") HandleGatewayEvent(evt); break; } }
public static void HandleGatewayEvent(FSEvent evt) { String gateway = evt.get_header("Gateway"); Account account = (from a in accounts where a.gateway_id == gateway select a).SingleOrDefault(); if (account == null) return; account.state = evt.get_header("State"); }
//capture an outgoing call the other leg public static void HandleOutgoingEvent(FSEvent evt, String uuid) { String other_leg = evt.get_header("Other-Leg-Unique-ID"); Call call = (from c in calls where c.leg_a_uuid == other_leg && c.call_ended == false select c).SingleOrDefault(); if (call == null || !call.is_outgoing) return; call.leg_b_uuid = uuid; }
public void NewFSEvent(object sender, FSEvent evt) { if (evt.event_id != switch_event_types_t.SWITCH_EVENT_CUSTOM || evt.subclass_name != "conference::maintenance" || evt.get_header("Conference-Name") != "fsc_conference") { return; } String type = evt.get_header("Action"); ConferenceUser user; switch (type) { case "add-member": String member_id = evt.get_header("Member-ID"); String uuid = evt.get_header("Unique-ID"); String source = evt.get_header("Caller-Source"); String direction = evt.get_header("Call-Direction"); user = new ConferenceUser { id = member_id, uuid = uuid, party_name = evt.get_header("Caller-Caller-ID-Name"), party_number = evt.get_header("Caller-Caller-ID-Number") }; if (source == "mod_portaudio" && direction == "inbound") { user.party_number = user.party_name = "You"; user.is_us = true; } users.Add(user); break; case "del-member": user = GetUser(evt); if (user == null) { return; } users.Remove(user); break; case "start-talking": user = GetUser(evt); if (user == null) { return; } user.state |= ConferenceUser.USER_STATE.TALK; break; case "stop-talking": user = GetUser(evt); if (user == null) { return; } user.state ^= ConferenceUser.USER_STATE.TALK; break; case "floor-change": user = GetUser(evt); if (user == null) { return; } foreach (var u in users) { u.state ^= ConferenceUser.USER_STATE.FLOOR; } user.state |= ConferenceUser.USER_STATE.FLOOR; break; } }
public static void NewFSEvent(object sender, FSEvent evt) { if (evt.event_id != switch_event_types_t.SWITCH_EVENT_MODULE_LOAD) Utils.DebugEventDump(evt); String uuid = evt.get_header("Unique-ID"); switch (evt.event_id) { case switch_event_types_t.SWITCH_EVENT_CHANNEL_CREATE: handleChannelCreateEvent(evt, uuid); break; case switch_event_types_t.SWITCH_EVENT_CHANNEL_OUTGOING: HandleOutgoingEvent(evt, uuid); break; case switch_event_types_t.SWITCH_EVENT_CHANNEL_HANGUP_COMPLETE: HandleHangupCompleteEvent(evt, uuid); break; case switch_event_types_t.SWITCH_EVENT_CHANNEL_ANSWER: String dest = "Caller-Destination-Number"; if (dest != "fsc_conference") HandleChannelAnswerEvent(evt, uuid); break; case switch_event_types_t.SWITCH_EVENT_CUSTOM: HandleCustomEvent(evt, uuid); break; case switch_event_types_t.SWITCH_EVENT_CHANNEL_DESTROY: channels.Remove(uuid); break; case switch_event_types_t.SWITCH_EVENT_DTMF: HandleDTMFEvent(evt, uuid); break; } }