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); VoiceCall vc; var reason = CallFinishedReason.Parse(reasonString); RoomsVoiceCallsDictionary.TryGetValue(roomId, out vc); var userId = Context.User.Identity.GetClaims().Id; if (vc == null) { if (reason.Reason == "unsupported" && reason.Src != CallFinishedReason.Reporter.Peer) { // Special case #2. unsupported_join stands for voice call attempt from the same user that was already joined to the same room // We're not finishing established call in this case if (reason.Detail == "join") { return; } // 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 = TextChatController.PartnerInPrivateRoom(roomId, userId), Platform = 1, // Formerly obtained from VoicePlatforms table (table abandonned when VoiceOut got removed) 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.CallerHangout : Enumerables.VoiceCallOutcomes.CalleeHangout; break; case "leftRoom": outcome = isCallerEvent ? Enumerables.VoiceCallOutcomes.CallerLeft : Enumerables.VoiceCallOutcomes.CalleeLeft; break; case "disconnected": outcome = isCallerEvent ? Enumerables.VoiceCallOutcomes.LostCaller : Enumerables.VoiceCallOutcomes.LostCallee; break; default: outcome = Enumerables.VoiceCallOutcomes.Error; break; } vc.Outcome = outcome; Log.SignalR(LogTag.SavingCallOutcome, new { roomId }, Context); await _db.SaveChangesAsync(); }