Handles events on existing video call (acceptance, termination, metadata exchange). (in response to msg = {note what=call}).
(msg *ClientComMessage)
| 239 | // Handles events on existing video call (acceptance, termination, metadata exchange). |
| 240 | // (in response to msg = {note what=call}). |
| 241 | func (t *Topic) handleCallEvent(msg *ClientComMessage) { |
| 242 | if t.currentCall == nil { |
| 243 | // Must initiate call first. |
| 244 | logs.Warn.Printf("topic[%s]: No call in progress", t.name) |
| 245 | return |
| 246 | } |
| 247 | if t.isInactive() { |
| 248 | // Topic is paused or being deleted. |
| 249 | return |
| 250 | } |
| 251 | |
| 252 | call := msg.Note |
| 253 | if t.currentCall.seq != call.SeqId { |
| 254 | // Call not found. |
| 255 | logs.Info.Printf("topic[%s]: invalid seq id - current call (%d) vs received (%d)", t.name, t.currentCall.seq, call.SeqId) |
| 256 | return |
| 257 | } |
| 258 | |
| 259 | asUid := types.ParseUserId(msg.AsUser) |
| 260 | |
| 261 | if _, userFound := t.perUser[asUid]; !userFound { |
| 262 | // User not found in topic. |
| 263 | logs.Warn.Printf("topic[%s]: could not find user %s", t.name, asUid.UserId()) |
| 264 | return |
| 265 | } |
| 266 | |
| 267 | switch call.Event { |
| 268 | case constCallEventRinging, constCallEventAccept: |
| 269 | // Invariants: |
| 270 | // 1. Call has been initiated but not been established yet. |
| 271 | if len(t.currentCall.parties) != 1 { |
| 272 | return |
| 273 | } |
| 274 | originatorUid, originator := t.getCallOriginator() |
| 275 | if originator == nil { |
| 276 | // No originator session: terminating. |
| 277 | t.terminateCallInProgress(false) |
| 278 | return |
| 279 | } |
| 280 | // 2. These events may only arrive from the callee. |
| 281 | if originator.sid == msg.sess.sid || originatorUid == asUid { |
| 282 | return |
| 283 | } |
| 284 | // Prepare a {info} message to forward to the call originator. |
| 285 | forwardMsg := t.currentCall.infoMessage(call.Event) |
| 286 | forwardMsg.Info.From = msg.AsUser |
| 287 | forwardMsg.Info.Topic = t.original(originatorUid) |
| 288 | if call.Event == constCallEventAccept { |
| 289 | // The call has been accepted. |
| 290 | // Send a replacement {data} message to the topic. |
| 291 | msgCopy := *msg |
| 292 | msgCopy.AsUser = originatorUid.UserId() |
| 293 | replaceWith := constCallMsgAccepted |
| 294 | var origHead map[string]any |
| 295 | if msgCopy.Pub != nil { |
| 296 | origHead = msgCopy.Pub.Head |
| 297 | } // else fetch the original message from store and use its head. |
| 298 | head := t.currentCall.messageHead(origHead, replaceWith, 0) |
no test coverage detected