diff --git a/doc/api.oa3 b/doc/api.oa3 index c74beb0f..1f69a223 100644 --- a/doc/api.oa3 +++ b/doc/api.oa3 @@ -3696,7 +3696,13 @@ paths: - name: agent in: query description: agent token - required: true + required: false + schema: + type: string + - name: contact + in: query + description: contact token + required: false schema: type: string - name: callId @@ -4612,9 +4618,12 @@ components: Ring: type: object required: + - callId - calleeToken - index properties: + callId: + type: string calleeToken: type: string index: diff --git a/net/server/internal/api_addCall.go b/net/server/internal/api_addCall.go index e3739840..597bde1f 100644 --- a/net/server/internal/api_addCall.go +++ b/net/server/internal/api_addCall.go @@ -56,7 +56,7 @@ func AddCall(w http.ResponseWriter, r *http.Request) { // allocate bridge callerToken := hex.EncodeToString(callerBin); calleeToken := hex.EncodeToString(calleeBin); - bridgeRelay.AddBridge(callId, callerToken, calleeToken); + bridgeRelay.AddBridge(account.ID, callId, callerToken, calleeToken); // create response call := Call{ diff --git a/net/server/internal/api_addRing.go b/net/server/internal/api_addRing.go index 880e5df8..93dfa544 100644 --- a/net/server/internal/api_addRing.go +++ b/net/server/internal/api_addRing.go @@ -25,6 +25,5 @@ func AddRing(w http.ResponseWriter, r *http.Request) { } SetRing(card, ring); - WriteResponse(w, nil) } diff --git a/net/server/internal/api_keepCall.go b/net/server/internal/api_keepCall.go index b496e42b..aa13cfdf 100644 --- a/net/server/internal/api_keepCall.go +++ b/net/server/internal/api_keepCall.go @@ -1,9 +1,25 @@ package databag import ( - "net/http" + "net/http" ) -//KeepCall keeps the call alive +//KeepCall keeps call and signaling alive func KeepCall(w http.ResponseWriter, r *http.Request) { + + account, code, err := ParamAgentToken(r, false) + if err != nil { + ErrResponse(w, code, err) + return + } + + var callId string + if err := ParseRequest(r, w, &callId); err != nil { + ErrResponse(w, http.StatusBadRequest, err) + return + } + + bridgeRelay.KeepAlive(account.ID, callId); + WriteResponse(w, nil); } + diff --git a/net/server/internal/api_removeCall.go b/net/server/internal/api_removeCall.go new file mode 100644 index 00000000..c9830635 --- /dev/null +++ b/net/server/internal/api_removeCall.go @@ -0,0 +1,38 @@ +package databag + +import ( + "net/http" + "errors" +) + +//RemoveCall adds an active call with ice signal and relay +func RemoveCall(w http.ResponseWriter, r *http.Request) { + + var callId string + if err := ParseRequest(r, w, &callId); err != nil { + ErrResponse(w, http.StatusBadRequest, err) + return + } + + tokenType := ParamTokenType(r) + if tokenType == APPTokenAgent { + account, code, err := ParamAgentToken(r, false) + if err != nil { + ErrResponse(w, code, err) + return + } + bridgeRelay.RemoveBridge(account.ID, callId, ""); + } else if tokenType == APPTokenContact { + card, code, err := ParamContactToken(r, false) + if err != nil { + ErrResponse(w, code, err) + return + } + bridgeRelay.RemoveBridge(card.Account.ID, callId, card.CardSlot.CardSlotID); + } else { + err := errors.New("unknown token type") + ErrResponse(w, http.StatusBadRequest, err) + return + } + WriteResponse(w, nil); +} diff --git a/net/server/internal/api_status.go b/net/server/internal/api_status.go index 8a1d5ffa..ae52b0cf 100644 --- a/net/server/internal/api_status.go +++ b/net/server/internal/api_status.go @@ -127,6 +127,7 @@ func SetRing(card *store.Card, ring Ring) { // serialize ring activity var phone Phone + phone.CallID = ring.CallID phone.CalleeToken = ring.CalleeToken phone.CardID = card.CardSlot.CardSlotID var a Activity diff --git a/net/server/internal/bridge.go b/net/server/internal/bridge.go index e719216c..7bae141f 100644 --- a/net/server/internal/bridge.go +++ b/net/server/internal/bridge.go @@ -15,8 +15,11 @@ type BridgeStatus struct { } type Bridge struct { + accountId uint callId string + cardId string expires int64 + closed bool callerToken string calleeToken string caller *websocket.Conn @@ -28,12 +31,14 @@ type BridgeRelay struct { bridges []Bridge } -func (s *BridgeRelay) AddBridge(callId string, callerToken string, calleeToken string) { +func (s *BridgeRelay) AddBridge(accountId uint, callId string, callerToken string, calleeToken string) { s.sync.Lock() defer s.sync.Unlock() bridge := Bridge{ + accountId: accountId, callId: callId, expires: time.Now().Unix() + (BridgeKeepAlive * 3), + closed: false, callerToken: callerToken, calleeToken: calleeToken, } @@ -54,7 +59,7 @@ func setStatus(bridge Bridge, status string) { } } -func (s *BridgeRelay) KeepAlive(callId string) { +func (s *BridgeRelay) KeepAlive(accountId uint, callId string) { s.sync.Lock() defer s.sync.Unlock() now := time.Now().Unix() @@ -62,7 +67,7 @@ func (s *BridgeRelay) KeepAlive(callId string) { for _, bridge := range s.bridges { if bridge.expires > now { bridges = append(bridges, bridge) - if bridge.callId == callId { + if bridge.callId == callId && bridge.accountId == accountId { bridge.expires = now + (BridgeKeepAlive * 3) if bridge.caller != nil { if err := bridge.caller.WriteMessage(websocket.PingMessage, nil); err != nil { @@ -82,12 +87,12 @@ func (s *BridgeRelay) KeepAlive(callId string) { s.bridges = bridges } -func (s *BridgeRelay) RemoveBridge(callId string) { +func (s *BridgeRelay) RemoveBridge(accountId uint, callId string, cardId string) { s.sync.Lock() defer s.sync.Unlock() var bridges []Bridge for _, bridge := range s.bridges { - if bridge.callId == callId { + if bridge.callId == callId && bridge.accountId == accountId && (bridge.cardId == cardId || cardId == "") { setStatus(bridge, "closed"); } else { bridges = append(bridges, bridge) diff --git a/net/server/internal/models.go b/net/server/internal/models.go index 13c55f8b..f0ab4ab9 100644 --- a/net/server/internal/models.go +++ b/net/server/internal/models.go @@ -415,10 +415,12 @@ type Revision struct { Card int64 `json:"card"` } -//Ring from contact initiating call +//Phone call indicator from contact initiating call type Phone struct { CardID string `json:"cardId"` + CallID string `json:"callId"` + CalleeToken string `json:"calleeToken"` } @@ -525,6 +527,8 @@ type Call struct { type Ring struct { + CallID string `json:"callId"` + CalleeToken string `json:"calleeToken"` Index int32 `json:"index"`