243 lines
7.6 KiB
Go
243 lines
7.6 KiB
Go
package localserver
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"strconv"
|
|
|
|
"github.com/pion/webrtc/v3"
|
|
)
|
|
|
|
const (
|
|
HOSTED_SQUAD_OFFER ReqType = "hosted_squad_offer"
|
|
HOSTED_SQUAD_ANSWER ReqType = "hosted_squad_answer"
|
|
HOSTED_SQUAD_COUNTER_OFFER ReqType = "hosted_squad_counter_offer"
|
|
JOIN_SQUAD ReqType = "join_hosted_squad"
|
|
HOSTED_SQUAD_ACCESS_DENIED ReqType = "hosted_squad_hosted_squad_access_denied"
|
|
QUIT_SQUAD ReqType = "hosted_squad_stop_call"
|
|
HOSTED_SQUAD_ACCESS_GRANTED ReqType = "hosted_squad_access_granted"
|
|
INCOMING_HOSTED_SQUAD_MEMBER ReqType = "incoming_hosted_squad_member"
|
|
LEAVING_HOSTED_SQUAD_MEMBER ReqType = "leaving_hosted_squad_member"
|
|
HOSTED_SQUAD_WEBRTC_RENNEGOTIATION_OFFER ReqType = "hosted_squad_rennegotiation_offer"
|
|
HOSTED_SQUAD_WEBRTC_RENNEGOTIATION_ANSWER ReqType = "hosted_squad_rennegotiation_answer"
|
|
HOSTED_SQUAD_WEBRTC_CANDIDATE ReqType = "hosted_squad_webrtc_candidate"
|
|
NEW_SQUAD ReqType = "new_hosted_squad"
|
|
NEW_AUTHORIZED_SQUAD_MEMBER = "new_authorized_squad_member"
|
|
REMOVED_SQUAD_AUTHORIZED_MEMBER = "removed_squad_authorized_member"
|
|
DELETE_SQUAD = "delete_hosted_squad"
|
|
DISCONNECT_SQUAD_MEMBER = "disconnect_squad_member"
|
|
UPDATE_SQUAD_LAST_INTERACTION_TIME = "update_squad_last_interaction_time"
|
|
NEW_SQUAD_CHAT_ACTIVITY = "new_squad_chat_activity"
|
|
)
|
|
|
|
type SquadGrpcMiddleware struct {
|
|
Manager *SquadManager
|
|
stream SignalingService_LinkClient
|
|
}
|
|
|
|
func NewSquadGrpcMiddleware(manager *SquadManager) (squadGrpcMiddleware *SquadGrpcMiddleware) {
|
|
squadGrpcMiddleware = &SquadGrpcMiddleware{
|
|
Manager: manager,
|
|
}
|
|
return
|
|
}
|
|
|
|
func (zm *SquadGrpcMiddleware) signalCandidate(to string, candidate *webrtc.ICECandidate) (err error) {
|
|
bs, err := json.Marshal(map[string]string{
|
|
"from": zm.Manager.ID,
|
|
"to": to,
|
|
"candidate": candidate.ToJSON().Candidate,
|
|
"sdpMid": *candidate.ToJSON().SDPMid,
|
|
"sdpMLineIndex": strconv.Itoa(int(*candidate.ToJSON().SDPMLineIndex)),
|
|
})
|
|
if err != nil {
|
|
return
|
|
}
|
|
err = zm.stream.Send(&SignalingMessage{
|
|
Type: string(HOSTED_SQUAD_WEBRTC_CANDIDATE),
|
|
From: zm.Manager.ID,
|
|
To: to,
|
|
Payload: bs,
|
|
})
|
|
return
|
|
}
|
|
|
|
func (zm *SquadGrpcMiddleware) Process(ctx context.Context, req *SignalingMessage, stream SignalingService_LinkClient) (err error) {
|
|
done, errCh := make(chan struct{}), make(chan error)
|
|
go func() {
|
|
defer func() {
|
|
done <- struct{}{}
|
|
}()
|
|
var payload map[string]string
|
|
if e := json.Unmarshal(req.Payload, &payload); e != nil {
|
|
errCh <- e
|
|
return
|
|
}
|
|
switch req.Type {
|
|
case string(INCOMING_HOSTED_SQUAD_MEMBER):
|
|
case string(DELETE_SQUAD):
|
|
if err := validateRequest(payload, "squadId"); err != nil {
|
|
return
|
|
}
|
|
if err := zm.Manager.DeleteSquad(payload["squadId"]); err != nil {
|
|
errCh <- err
|
|
return
|
|
}
|
|
case string(LEAVING_HOSTED_SQUAD_MEMBER):
|
|
if err := validateRequest(payload, "squadId"); err != nil {
|
|
return
|
|
}
|
|
if err := zm.Manager.HandleLeavingMember(req.GetFrom(), payload["squadId"], false); err != nil {
|
|
errCh <- err
|
|
return
|
|
}
|
|
case string(REMOVED_SQUAD_AUTHORIZED_MEMBER):
|
|
fmt.Println("got there biatch")
|
|
if err := validateRequest(payload, "squadId", "userId"); err != nil {
|
|
return
|
|
}
|
|
if _, ok := zm.Manager.Squads[payload["squadId"]]; !ok {
|
|
err = fmt.Errorf("no such squad")
|
|
return
|
|
}
|
|
reqChan := make(chan *SquadRequest)
|
|
d, e := zm.Manager.Squads[payload["squadId"]].SquadRequestScheduler.Schedule(reqChan)
|
|
go func() {
|
|
defer close(reqChan)
|
|
reqChan <- &SquadRequest{
|
|
ReqType: string(REMOVED_SQUAD_AUTHORIZED_MEMBER),
|
|
From: payload["userId"],
|
|
Payload: map[string]interface{}{
|
|
"userId": payload["userId"],
|
|
},
|
|
}
|
|
}()
|
|
select {
|
|
case <-d:
|
|
fmt.Println("uwuwuwuwuwuwuw donnnnee")
|
|
case ee := <-e:
|
|
fmt.Println("uuuuuuwuuuuuu", ee)
|
|
}
|
|
return
|
|
case string(NEW_AUTHORIZED_SQUAD_MEMBER):
|
|
if err := validateRequest(payload, "squadId", "userId"); err != nil {
|
|
return
|
|
}
|
|
if _, ok := zm.Manager.Squads[payload["squadId"]]; !ok {
|
|
err = fmt.Errorf("no such squad")
|
|
return
|
|
}
|
|
reqChan := make(chan *SquadRequest)
|
|
d, e := zm.Manager.Squads[payload["squadId"]].SquadRequestScheduler.Schedule(reqChan)
|
|
go func() {
|
|
defer close(reqChan)
|
|
reqChan <- &SquadRequest{
|
|
ReqType: string(NEW_AUTHORIZED_SQUAD_MEMBER),
|
|
From: payload["userId"],
|
|
Payload: map[string]interface{}{
|
|
"userId": payload["userId"],
|
|
},
|
|
}
|
|
}()
|
|
select {
|
|
case <-d:
|
|
case <-e:
|
|
}
|
|
return
|
|
case string(NEW_SQUAD):
|
|
// logger.Println(payload)
|
|
if err := validateRequest(payload, "squadId", "squadName", "squadImageURL", "squadOwner", "squadCreationDate"); err != nil {
|
|
errCh <- err
|
|
return
|
|
}
|
|
squad, err := NewSquad(zm.Manager.ID, payload["squadId"], payload["squadName"], payload["squadImageURL"], payload["squadOwner"], payload["squadCreationDate"], true, []string{payload["squadOwner"]})
|
|
if err != nil {
|
|
errCh <- err
|
|
return
|
|
}
|
|
_ = atomicallyExecute(zm.Manager.squadFlag, func() (err error) {
|
|
zm.Manager.Squads[squad.ID] = squad
|
|
return
|
|
})
|
|
case string(HOSTED_SQUAD_OFFER):
|
|
if err := validateRequest(payload, SDP); err != nil {
|
|
errCh <- err
|
|
return
|
|
}
|
|
if err := zm.Manager.HandleOffer(ctx, req.GetFrom(), req.GetTo(), payload, zm.signalCandidate); err != nil {
|
|
errCh <- err
|
|
return
|
|
}
|
|
case string(HOSTED_SQUAD_ANSWER):
|
|
if err := validateRequest(payload, SDP); err != nil {
|
|
errCh <- err
|
|
return
|
|
}
|
|
if err := zm.Manager.HandleAnswer(ctx, req.GetFrom(), req.GetTo(), payload); err != nil {
|
|
errCh <- err
|
|
return
|
|
}
|
|
case string(HOSTED_SQUAD_COUNTER_OFFER):
|
|
if err := zm.Manager.HandleCounterOffer(ctx, req.GetFrom(), req.GetTo(), payload); err != nil {
|
|
errCh <- err
|
|
return
|
|
}
|
|
case string(HOSTED_SQUAD_WEBRTC_RENNEGOTIATION_OFFER):
|
|
// logger.Println("received negotiation offer")
|
|
if err := validateRequest(payload, SDP); err != nil {
|
|
errCh <- err
|
|
return
|
|
}
|
|
if err := zm.Manager.HandleRennegotiationOffer(req.GetFrom(), payload[SDP]); err != nil {
|
|
errCh <- err
|
|
return
|
|
}
|
|
case string(HOSTED_SQUAD_WEBRTC_RENNEGOTIATION_ANSWER):
|
|
// logger.Println("received negotiation answer")
|
|
if err := validateRequest(payload, SDP); err != nil {
|
|
errCh <- err
|
|
return
|
|
}
|
|
if err := zm.Manager.HandleRennegotiationAnswer(req.GetFrom(), payload[SDP]); err != nil {
|
|
errCh <- err
|
|
return
|
|
}
|
|
case string(HOSTED_SQUAD_WEBRTC_CANDIDATE):
|
|
if err := validateRequest(payload, "candidate", "sdpMLineIndex", "sdpMid"); err != nil {
|
|
errCh <- err
|
|
return
|
|
}
|
|
// logger.Println(payload)
|
|
i, err := strconv.Atoi(payload["sdpMLineIndex"])
|
|
if err != nil {
|
|
errCh <- err
|
|
return
|
|
}
|
|
SDPMLineIndex := uint16(i)
|
|
sdpMid := payload["sdpMid"]
|
|
// logger.Println(sdpMid, SDPMLineIndex)
|
|
if err := zm.Manager.AddCandidate(&webrtc.ICECandidateInit{
|
|
Candidate: payload["candidate"],
|
|
SDPMid: &sdpMid,
|
|
SDPMLineIndex: &SDPMLineIndex,
|
|
}, req.GetFrom()); err != nil {
|
|
errCh <- err
|
|
return
|
|
}
|
|
default:
|
|
// logger.Println("no request for squad grpc middleware")
|
|
// logger.Println(payload)
|
|
// logger.Println(req.Type)
|
|
}
|
|
}()
|
|
select {
|
|
case <-ctx.Done():
|
|
return ctx.Err()
|
|
case err = <-errCh:
|
|
return
|
|
case <-done:
|
|
return
|
|
}
|
|
}
|