public static CallFinishedReason Parse(string reason) { var result = new CallFinishedReason(); var reasonArr = reason.Split('_'); if (reasonArr.Length == 1) { result.Reason = reasonArr[0]; } else { if (reasonArr[0] == "peer") { result.Src = Reporter.Peer; reasonArr = reasonArr.Skip(1).ToArray(); } result.Reason = reasonArr[0]; if (reasonArr.Length > 1) { result.Detail = reasonArr[1]; } } return(result); }
public async Task CallFinished(string roomId, string reasonString) { if (string.IsNullOrEmpty(roomId)) { return; } Log.SignalR(LogTag.ReceivedCallFinished, new { roomId, reason = reasonString }, Context); var reason = CallFinishedReason.Parse(reasonString); VoiceCall vc; RoomsVoiceCallsDictionary.TryGetValue(roomId, out vc); var userId = GetUserIdFromClaims(); if (vc == null) { if (reason.Reason == "unsupported" && reason.Src != CallFinishedReason.Reporter.Peer) { // Special case! Reporting about call finish and failed to initiate it // so we don't have anything for it in RoomsVoiceCallsDictionary but have to save something to DB vc = new VoiceCall { Created = DateTime.Now, CallerId = userId, CalleeId = _chatModel.UsersInRoom(roomId, userId).FirstOrDefault() ?? _chatModel.GetAbsentPrivateChatUserIds(roomId).First(), Platform = Enumerables.VoicePlatforms.OnSiteWebRtc, Source = Enumerables.SourceFeatures.PrivateTextChat }; RoomsVoiceCallsDictionary.Add(roomId, vc); _db.VoiceCalls.Add(vc); } else { return; } } else { ((DbContext)_db).Entry(vc).State = EntityState.Modified; } RoomsVoiceCallsDictionary.Remove(roomId); vc.Ended = DateTime.Now; var isCallerEvent = (userId == vc.CallerId && reason.Src != CallFinishedReason.Reporter.Peer) || (userId != vc.CallerId && reason.Src == CallFinishedReason.Reporter.Peer); byte outcome; switch (reason.Reason) { case "cancelled": outcome = Enumerables.VoiceCallOutcomes.Cancel; break; case "declined": outcome = Enumerables.VoiceCallOutcomes.Decline; break; case "unsupported": if (reason.Detail == "browser") { outcome = isCallerEvent ? Enumerables.VoiceCallOutcomes.FailOnCallerUnsupportedBrowser : Enumerables.VoiceCallOutcomes.FailOnCalleeUnsupportedBrowser; } else { outcome = isCallerEvent ? Enumerables.VoiceCallOutcomes.FailOnCallerMicNotFound : Enumerables.VoiceCallOutcomes.FailOnCalleeMicNotFound; } break; case "hangout": outcome = isCallerEvent ? Enumerables.VoiceCallOutcomes.AcceptThenCallerHangout : Enumerables.VoiceCallOutcomes.AcceptThenCalleeHangout; break; case "leftRoom": outcome = isCallerEvent ? Enumerables.VoiceCallOutcomes.AcceptThenCallerLeft : Enumerables.VoiceCallOutcomes.AcceptThenCalleeLeft; break; case "disconnected": outcome = isCallerEvent ? Enumerables.VoiceCallOutcomes.AcceptThenLostCaller : Enumerables.VoiceCallOutcomes.AcceptThenLostCallee; break; default: outcome = Enumerables.VoiceCallOutcomes.Error; break; } vc.Outcome = outcome; Log.SignalR(LogTag.SavingCallOutcome, new { roomId }, Context); await _db.SaveChangesAsync(); }