add: signal server

This commit is contained in:
Charles Hathaway
2023-09-20 22:09:15 -07:00
parent 922ba64a84
commit 9bbe917e59
25 changed files with 5097 additions and 3 deletions
+14
View File
@@ -0,0 +1,14 @@
version: v1
managed:
enabled: true
go_package_prefix:
default: github.com/chathaway-codes/home-sensors/v2/gen
plugins:
- plugin: buf.build/protocolbuffers/go
out: gen
opt: paths=source_relative
- plugin: buf.build/connectrpc/go
out: gen
opt: paths=source_relative
- plugin: buf.build/protocolbuffers/dart:v21.1.1
out: gen
+7
View File
@@ -0,0 +1,7 @@
version: v1
breaking:
use:
- FILE
lint:
use:
- DEFAULT
+27 -2
View File
@@ -1,7 +1,32 @@
package main package main
import "fmt" import (
"fmt"
"log"
"net/http"
"connectrpc.com/grpcreflect"
servicepb "github.com/chathaway-codes/home-sensors/v2/gen/genconnect"
"github.com/chathaway-codes/home-sensors/v2/pkg/signaler"
)
func main() { func main() {
fmt.Printf("Hello world!\n") mux := http.NewServeMux()
reflector := grpcreflect.NewStaticReflector(
servicepb.SignalerServiceName,
)
path, _ := grpcreflect.NewHandlerV1(reflector)
fmt.Printf("Got path %s\n", path)
mux.Handle(grpcreflect.NewHandlerV1(reflector))
path, _ = grpcreflect.NewHandlerV1Alpha(reflector)
fmt.Printf("Got path %s\n", path)
mux.Handle(grpcreflect.NewHandlerV1Alpha(reflector))
path, _ = servicepb.NewSignalerServiceHandler(signaler.New())
fmt.Printf("Got path %s\n", path)
mux.Handle(servicepb.NewSignalerServiceHandler(signaler.New()))
if err := http.ListenAndServe("127.0.0.1:8080", mux); err != nil {
log.Fatalf("Failed to listen for HTTP traffic: %v", err)
}
} }
+229
View File
@@ -0,0 +1,229 @@
//go:build !js
// +build !js
package main
import (
"context"
"fmt"
"io"
"log"
"net/http"
"os"
"time"
"connectrpc.com/connect"
pb "github.com/chathaway-codes/home-sensors/v2/gen"
servicepb "github.com/chathaway-codes/home-sensors/v2/gen/genconnect"
"github.com/pion/webrtc/v3"
"github.com/pion/webrtc/v3/pkg/media"
"github.com/pion/webrtc/v3/pkg/media/h264reader"
"google.golang.org/protobuf/proto"
)
const (
videoFileName = "/home/charles/Downloads/simpsons_movie_1080p_hddvd_trailer/The Simpsons Movie - 1080p Trailer.mp4"
oggPageDuration = time.Millisecond * 20
h264FrameDuration = time.Millisecond * 33
)
func main() { //nolint
ctx := context.Background()
client := servicepb.NewSignalerServiceClient(&http.Client{}, "http://localhost:8080/")
// Assert that we have an audio or video file
_, err := os.Stat(videoFileName)
haveVideoFile := !os.IsNotExist(err)
// Create a new RTCPeerConnection
peerConnection, err := webrtc.NewPeerConnection(webrtc.Configuration{
ICEServers: []webrtc.ICEServer{
{
URLs: []string{"stun:stun.l.google.com:19302"},
},
},
})
if err != nil {
panic(err)
}
defer func() {
if cErr := peerConnection.Close(); cErr != nil {
fmt.Printf("cannot close peerConnection: %v\n", cErr)
}
}()
iceConnectedCtx, iceConnectedCtxCancel := context.WithCancel(context.Background())
if haveVideoFile {
// Create a video track
videoTrack, videoTrackErr := webrtc.NewTrackLocalStaticSample(webrtc.RTPCodecCapability{MimeType: webrtc.MimeTypeH264}, "video", "pion")
if videoTrackErr != nil {
panic(videoTrackErr)
}
rtpSender, videoTrackErr := peerConnection.AddTrack(videoTrack)
if videoTrackErr != nil {
panic(videoTrackErr)
}
// Read incoming RTCP packets
// Before these packets are returned they are processed by interceptors. For things
// like NACK this needs to be called.
go func() {
rtcpBuf := make([]byte, 1500)
for {
if _, _, rtcpErr := rtpSender.Read(rtcpBuf); rtcpErr != nil {
return
}
}
}()
go func() {
// Open a H264 file and start reading using our IVFReader
file, h264Err := os.Open(videoFileName)
if h264Err != nil {
panic(h264Err)
}
h264, h264Err := h264reader.NewReader(file)
if h264Err != nil {
panic(h264Err)
}
// Wait for connection established
<-iceConnectedCtx.Done()
// Send our video file frame at a time. Pace our sending so we send it at the same speed it should be played back as.
// This isn't required since the video is timestamped, but we will such much higher loss if we send all at once.
//
// It is important to use a time.Ticker instead of time.Sleep because
// * avoids accumulating skew, just calling time.Sleep didn't compensate for the time spent parsing the data
// * works around latency issues with Sleep (see https://github.com/golang/go/issues/44343)
ticker := time.NewTicker(h264FrameDuration)
for ; true; <-ticker.C {
nal, h264Err := h264.NextNAL()
if h264Err == io.EOF {
fmt.Printf("All video frames parsed and sent")
os.Exit(0)
}
if h264Err != nil {
panic(h264Err)
}
if h264Err = videoTrack.WriteSample(media.Sample{Data: nal.Data, Duration: h264FrameDuration}); h264Err != nil {
panic(h264Err)
}
}
}()
}
// Set the handler for ICE connection state
// This will notify you when the peer has connected/disconnected
peerConnection.OnICEConnectionStateChange(func(connectionState webrtc.ICEConnectionState) {
fmt.Printf("Connection State has changed %s \n", connectionState.String())
if connectionState == webrtc.ICEConnectionStateConnected {
iceConnectedCtxCancel()
}
})
// Set the handler for Peer connection state
// This will notify you when the peer has connected/disconnected
peerConnection.OnConnectionStateChange(func(s webrtc.PeerConnectionState) {
fmt.Printf("Peer Connection State has changed: %s\n", s.String())
if s == webrtc.PeerConnectionStateFailed {
// Wait until PeerConnection has had no network activity for 30 seconds or another failure. It may be reconnected using an ICE Restart.
// Use webrtc.PeerConnectionStateDisconnected if you are interested in detecting faster timeout.
// Note that the PeerConnection may come back from PeerConnectionStateDisconnected.
fmt.Println("Peer Connection has gone to failed exiting")
os.Exit(0)
}
})
var iceCandidates []*pb.IceCandidate
peerConnection.OnICECandidate(func(i *webrtc.ICECandidate) {
if i == nil {
return
}
c := i.ToJSON()
iceCandidates = append(iceCandidates, &pb.IceCandidate{
Candidate: c.Candidate,
SdpMid: c.SDPMid,
SdpLineIndex: proto.Int32(int32(*c.SDPMLineIndex)),
UsernameFragment: proto.String(*c.UsernameFragment),
})
})
// Wait for a session request
var session *pb.Session
for session == nil {
resp, err := client.ListSessions(ctx, connect.NewRequest(&pb.ListSessionsRequest{}))
if err != nil {
log.Fatalf("error creating session: %v", err)
}
if len(resp.Msg.Sessions) > 0 {
session = resp.Msg.Sessions[0]
}
time.Sleep(time.Millisecond * 500)
}
// Add ICE candidates from remote
for _, candidate := range session.GetClientIceCandidates() {
var sdpMLine *uint16
if candidate.SdpLineIndex != nil {
t := uint16(candidate.GetSdpLineIndex())
sdpMLine = &t
}
peerConnection.AddICECandidate(webrtc.ICECandidateInit{
Candidate: candidate.GetCandidate(),
SDPMid: candidate.SdpMid,
SDPMLineIndex: sdpMLine,
})
}
cameraOffer, err := peerConnection.CreateOffer(nil)
if err != nil {
log.Fatalf("error creating session: %v", err)
}
// Set the remote SessionDescription
if err = peerConnection.SetRemoteDescription(cameraOffer); err != nil {
panic(err)
}
// Create channel that is blocked until ICE Gathering is complete
gatherComplete := webrtc.GatheringCompletePromise(peerConnection)
// Block until ICE Gathering is complete, disabling trickle ICE
// we do this because we only can exchange one signaling message
// in a production application you should exchange ICE Candidates via OnICECandidate
log.Printf("Waiting to gather ICE")
<-gatherComplete
log.Printf("Done gathering ICE")
session.CameraIceCandidates = iceCandidates
session.CameraOffer = &pb.IceSessionDescription{
SdpType: int64(cameraOffer.Type),
Sdp: cameraOffer.SDP,
}
// Send it back
resp, err := client.UpdateSession(ctx, connect.NewRequest(&pb.UpdateSessionRequest{
Session: session,
WaitForUpdate: true,
}))
if err != nil {
log.Fatalf("error creating session: %v", err)
}
answer := webrtc.SessionDescription{
Type: webrtc.SDPType(resp.Msg.ClientAnswer.SdpType),
SDP: resp.Msg.ClientAnswer.Sdp,
}
// Sets the LocalDescription, and starts our UDP listeners
if err = peerConnection.SetLocalDescription(answer); err != nil {
panic(err)
}
// Block forever
select {}
}
+347
View File
@@ -0,0 +1,347 @@
// Code generated by protoc-gen-connect-go. DO NOT EDIT.
//
// Source: signaler_service.proto
package genconnect
import (
connect "connectrpc.com/connect"
context "context"
errors "errors"
gen "github.com/chathaway-codes/home-sensors/v2/gen"
http "net/http"
strings "strings"
)
// This is a compile-time assertion to ensure that this generated file and the connect package are
// compatible. If you get a compiler error that this constant is not defined, this code was
// generated with a version of connect newer than the one compiled into your binary. You can fix the
// problem by either regenerating this code with an older version of connect or updating the connect
// version compiled into your binary.
const _ = connect.IsAtLeastVersion0_1_0
const (
// SignalerServiceName is the fully-qualified name of the SignalerService service.
SignalerServiceName = "signaler.SignalerService"
)
// These constants are the fully-qualified names of the RPCs defined in this package. They're
// exposed at runtime as Spec.Procedure and as the final two segments of the HTTP route.
//
// Note that these are different from the fully-qualified method names used by
// google.golang.org/protobuf/reflect/protoreflect. To convert from these constants to
// reflection-formatted method names, remove the leading slash and convert the remaining slash to a
// period.
const (
// SignalerServiceCreateAuthTokenProcedure is the fully-qualified name of the SignalerService's
// CreateAuthToken RPC.
SignalerServiceCreateAuthTokenProcedure = "/signaler.SignalerService/CreateAuthToken"
// SignalerServiceListCamerasProcedure is the fully-qualified name of the SignalerService's
// ListCameras RPC.
SignalerServiceListCamerasProcedure = "/signaler.SignalerService/ListCameras"
// SignalerServiceCreateSessionProcedure is the fully-qualified name of the SignalerService's
// CreateSession RPC.
SignalerServiceCreateSessionProcedure = "/signaler.SignalerService/CreateSession"
// SignalerServiceUpdateSessionProcedure is the fully-qualified name of the SignalerService's
// UpdateSession RPC.
SignalerServiceUpdateSessionProcedure = "/signaler.SignalerService/UpdateSession"
// SignalerServiceListSessionsProcedure is the fully-qualified name of the SignalerService's
// ListSessions RPC.
SignalerServiceListSessionsProcedure = "/signaler.SignalerService/ListSessions"
// SignalerServiceCreateIceCandidateProcedure is the fully-qualified name of the SignalerService's
// CreateIceCandidate RPC.
SignalerServiceCreateIceCandidateProcedure = "/signaler.SignalerService/CreateIceCandidate"
// SignalerServicePopIceCandidateProcedure is the fully-qualified name of the SignalerService's
// PopIceCandidate RPC.
SignalerServicePopIceCandidateProcedure = "/signaler.SignalerService/PopIceCandidate"
// SignalerServiceCreateIceSessionDescriptionProcedure is the fully-qualified name of the
// SignalerService's CreateIceSessionDescription RPC.
SignalerServiceCreateIceSessionDescriptionProcedure = "/signaler.SignalerService/CreateIceSessionDescription"
// SignalerServicePopIceSessionDescriptionProcedure is the fully-qualified name of the
// SignalerService's PopIceSessionDescription RPC.
SignalerServicePopIceSessionDescriptionProcedure = "/signaler.SignalerService/PopIceSessionDescription"
)
// SignalerServiceClient is a client for the signaler.SignalerService service.
type SignalerServiceClient interface {
CreateAuthToken(context.Context, *connect.Request[gen.CreateAuthTokenRequest]) (*connect.Response[gen.AuthToken], error)
ListCameras(context.Context, *connect.Request[gen.ListCamerasRequest]) (*connect.Response[gen.ListCamerasResponse], error)
// CreateSession creates a new session that can be seen bv the provided Camera and Peer.
//
// Optionally, wait_for_update can be set to prevent returning until the Camera has seen the
// session request, populated candidates, and returned a session offer.
CreateSession(context.Context, *connect.Request[gen.CreateSessionRequest]) (*connect.Response[gen.Session], error)
// UpdateSession updates the session
UpdateSession(context.Context, *connect.Request[gen.UpdateSessionRequest]) (*connect.Response[gen.Session], error)
// ListSessions lists all sessions the client should consider.
//
// TODO: it would be better if we could alert a camera to poll for sessions
// i.e., with websockets (or streaming RPCs).
ListSessions(context.Context, *connect.Request[gen.ListSessionsRequest]) (*connect.Response[gen.ListSessionsResponse], error)
// CreateIceCandidate adds the provided candidate to the list of candidates.
CreateIceCandidate(context.Context, *connect.Request[gen.CreateIceCandidateRequest]) (*connect.Response[gen.IceCandidate], error)
// PopIceCandidate delete a candidate from the list of candidates and returns it.
//
// If there are no candidates, this blocks until one becomes available.
PopIceCandidate(context.Context, *connect.Request[gen.PopIceCandidateRequest]) (*connect.Response[gen.IceCandidate], error)
CreateIceSessionDescription(context.Context, *connect.Request[gen.CreateIceSessionDescriptionRequest]) (*connect.Response[gen.IceSessionDescription], error)
PopIceSessionDescription(context.Context, *connect.Request[gen.PopIceSessionDescriptionRequest]) (*connect.Response[gen.IceSessionDescription], error)
}
// NewSignalerServiceClient constructs a client for the signaler.SignalerService service. By
// default, it uses the Connect protocol with the binary Protobuf Codec, asks for gzipped responses,
// and sends uncompressed requests. To use the gRPC or gRPC-Web protocols, supply the
// connect.WithGRPC() or connect.WithGRPCWeb() options.
//
// The URL supplied here should be the base URL for the Connect or gRPC server (for example,
// http://api.acme.com or https://acme.com/grpc).
func NewSignalerServiceClient(httpClient connect.HTTPClient, baseURL string, opts ...connect.ClientOption) SignalerServiceClient {
baseURL = strings.TrimRight(baseURL, "/")
return &signalerServiceClient{
createAuthToken: connect.NewClient[gen.CreateAuthTokenRequest, gen.AuthToken](
httpClient,
baseURL+SignalerServiceCreateAuthTokenProcedure,
opts...,
),
listCameras: connect.NewClient[gen.ListCamerasRequest, gen.ListCamerasResponse](
httpClient,
baseURL+SignalerServiceListCamerasProcedure,
opts...,
),
createSession: connect.NewClient[gen.CreateSessionRequest, gen.Session](
httpClient,
baseURL+SignalerServiceCreateSessionProcedure,
opts...,
),
updateSession: connect.NewClient[gen.UpdateSessionRequest, gen.Session](
httpClient,
baseURL+SignalerServiceUpdateSessionProcedure,
opts...,
),
listSessions: connect.NewClient[gen.ListSessionsRequest, gen.ListSessionsResponse](
httpClient,
baseURL+SignalerServiceListSessionsProcedure,
opts...,
),
createIceCandidate: connect.NewClient[gen.CreateIceCandidateRequest, gen.IceCandidate](
httpClient,
baseURL+SignalerServiceCreateIceCandidateProcedure,
opts...,
),
popIceCandidate: connect.NewClient[gen.PopIceCandidateRequest, gen.IceCandidate](
httpClient,
baseURL+SignalerServicePopIceCandidateProcedure,
opts...,
),
createIceSessionDescription: connect.NewClient[gen.CreateIceSessionDescriptionRequest, gen.IceSessionDescription](
httpClient,
baseURL+SignalerServiceCreateIceSessionDescriptionProcedure,
opts...,
),
popIceSessionDescription: connect.NewClient[gen.PopIceSessionDescriptionRequest, gen.IceSessionDescription](
httpClient,
baseURL+SignalerServicePopIceSessionDescriptionProcedure,
opts...,
),
}
}
// signalerServiceClient implements SignalerServiceClient.
type signalerServiceClient struct {
createAuthToken *connect.Client[gen.CreateAuthTokenRequest, gen.AuthToken]
listCameras *connect.Client[gen.ListCamerasRequest, gen.ListCamerasResponse]
createSession *connect.Client[gen.CreateSessionRequest, gen.Session]
updateSession *connect.Client[gen.UpdateSessionRequest, gen.Session]
listSessions *connect.Client[gen.ListSessionsRequest, gen.ListSessionsResponse]
createIceCandidate *connect.Client[gen.CreateIceCandidateRequest, gen.IceCandidate]
popIceCandidate *connect.Client[gen.PopIceCandidateRequest, gen.IceCandidate]
createIceSessionDescription *connect.Client[gen.CreateIceSessionDescriptionRequest, gen.IceSessionDescription]
popIceSessionDescription *connect.Client[gen.PopIceSessionDescriptionRequest, gen.IceSessionDescription]
}
// CreateAuthToken calls signaler.SignalerService.CreateAuthToken.
func (c *signalerServiceClient) CreateAuthToken(ctx context.Context, req *connect.Request[gen.CreateAuthTokenRequest]) (*connect.Response[gen.AuthToken], error) {
return c.createAuthToken.CallUnary(ctx, req)
}
// ListCameras calls signaler.SignalerService.ListCameras.
func (c *signalerServiceClient) ListCameras(ctx context.Context, req *connect.Request[gen.ListCamerasRequest]) (*connect.Response[gen.ListCamerasResponse], error) {
return c.listCameras.CallUnary(ctx, req)
}
// CreateSession calls signaler.SignalerService.CreateSession.
func (c *signalerServiceClient) CreateSession(ctx context.Context, req *connect.Request[gen.CreateSessionRequest]) (*connect.Response[gen.Session], error) {
return c.createSession.CallUnary(ctx, req)
}
// UpdateSession calls signaler.SignalerService.UpdateSession.
func (c *signalerServiceClient) UpdateSession(ctx context.Context, req *connect.Request[gen.UpdateSessionRequest]) (*connect.Response[gen.Session], error) {
return c.updateSession.CallUnary(ctx, req)
}
// ListSessions calls signaler.SignalerService.ListSessions.
func (c *signalerServiceClient) ListSessions(ctx context.Context, req *connect.Request[gen.ListSessionsRequest]) (*connect.Response[gen.ListSessionsResponse], error) {
return c.listSessions.CallUnary(ctx, req)
}
// CreateIceCandidate calls signaler.SignalerService.CreateIceCandidate.
func (c *signalerServiceClient) CreateIceCandidate(ctx context.Context, req *connect.Request[gen.CreateIceCandidateRequest]) (*connect.Response[gen.IceCandidate], error) {
return c.createIceCandidate.CallUnary(ctx, req)
}
// PopIceCandidate calls signaler.SignalerService.PopIceCandidate.
func (c *signalerServiceClient) PopIceCandidate(ctx context.Context, req *connect.Request[gen.PopIceCandidateRequest]) (*connect.Response[gen.IceCandidate], error) {
return c.popIceCandidate.CallUnary(ctx, req)
}
// CreateIceSessionDescription calls signaler.SignalerService.CreateIceSessionDescription.
func (c *signalerServiceClient) CreateIceSessionDescription(ctx context.Context, req *connect.Request[gen.CreateIceSessionDescriptionRequest]) (*connect.Response[gen.IceSessionDescription], error) {
return c.createIceSessionDescription.CallUnary(ctx, req)
}
// PopIceSessionDescription calls signaler.SignalerService.PopIceSessionDescription.
func (c *signalerServiceClient) PopIceSessionDescription(ctx context.Context, req *connect.Request[gen.PopIceSessionDescriptionRequest]) (*connect.Response[gen.IceSessionDescription], error) {
return c.popIceSessionDescription.CallUnary(ctx, req)
}
// SignalerServiceHandler is an implementation of the signaler.SignalerService service.
type SignalerServiceHandler interface {
CreateAuthToken(context.Context, *connect.Request[gen.CreateAuthTokenRequest]) (*connect.Response[gen.AuthToken], error)
ListCameras(context.Context, *connect.Request[gen.ListCamerasRequest]) (*connect.Response[gen.ListCamerasResponse], error)
// CreateSession creates a new session that can be seen bv the provided Camera and Peer.
//
// Optionally, wait_for_update can be set to prevent returning until the Camera has seen the
// session request, populated candidates, and returned a session offer.
CreateSession(context.Context, *connect.Request[gen.CreateSessionRequest]) (*connect.Response[gen.Session], error)
// UpdateSession updates the session
UpdateSession(context.Context, *connect.Request[gen.UpdateSessionRequest]) (*connect.Response[gen.Session], error)
// ListSessions lists all sessions the client should consider.
//
// TODO: it would be better if we could alert a camera to poll for sessions
// i.e., with websockets (or streaming RPCs).
ListSessions(context.Context, *connect.Request[gen.ListSessionsRequest]) (*connect.Response[gen.ListSessionsResponse], error)
// CreateIceCandidate adds the provided candidate to the list of candidates.
CreateIceCandidate(context.Context, *connect.Request[gen.CreateIceCandidateRequest]) (*connect.Response[gen.IceCandidate], error)
// PopIceCandidate delete a candidate from the list of candidates and returns it.
//
// If there are no candidates, this blocks until one becomes available.
PopIceCandidate(context.Context, *connect.Request[gen.PopIceCandidateRequest]) (*connect.Response[gen.IceCandidate], error)
CreateIceSessionDescription(context.Context, *connect.Request[gen.CreateIceSessionDescriptionRequest]) (*connect.Response[gen.IceSessionDescription], error)
PopIceSessionDescription(context.Context, *connect.Request[gen.PopIceSessionDescriptionRequest]) (*connect.Response[gen.IceSessionDescription], error)
}
// NewSignalerServiceHandler builds an HTTP handler from the service implementation. It returns the
// path on which to mount the handler and the handler itself.
//
// By default, handlers support the Connect, gRPC, and gRPC-Web protocols with the binary Protobuf
// and JSON codecs. They also support gzip compression.
func NewSignalerServiceHandler(svc SignalerServiceHandler, opts ...connect.HandlerOption) (string, http.Handler) {
signalerServiceCreateAuthTokenHandler := connect.NewUnaryHandler(
SignalerServiceCreateAuthTokenProcedure,
svc.CreateAuthToken,
opts...,
)
signalerServiceListCamerasHandler := connect.NewUnaryHandler(
SignalerServiceListCamerasProcedure,
svc.ListCameras,
opts...,
)
signalerServiceCreateSessionHandler := connect.NewUnaryHandler(
SignalerServiceCreateSessionProcedure,
svc.CreateSession,
opts...,
)
signalerServiceUpdateSessionHandler := connect.NewUnaryHandler(
SignalerServiceUpdateSessionProcedure,
svc.UpdateSession,
opts...,
)
signalerServiceListSessionsHandler := connect.NewUnaryHandler(
SignalerServiceListSessionsProcedure,
svc.ListSessions,
opts...,
)
signalerServiceCreateIceCandidateHandler := connect.NewUnaryHandler(
SignalerServiceCreateIceCandidateProcedure,
svc.CreateIceCandidate,
opts...,
)
signalerServicePopIceCandidateHandler := connect.NewUnaryHandler(
SignalerServicePopIceCandidateProcedure,
svc.PopIceCandidate,
opts...,
)
signalerServiceCreateIceSessionDescriptionHandler := connect.NewUnaryHandler(
SignalerServiceCreateIceSessionDescriptionProcedure,
svc.CreateIceSessionDescription,
opts...,
)
signalerServicePopIceSessionDescriptionHandler := connect.NewUnaryHandler(
SignalerServicePopIceSessionDescriptionProcedure,
svc.PopIceSessionDescription,
opts...,
)
return "/signaler.SignalerService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
switch r.URL.Path {
case SignalerServiceCreateAuthTokenProcedure:
signalerServiceCreateAuthTokenHandler.ServeHTTP(w, r)
case SignalerServiceListCamerasProcedure:
signalerServiceListCamerasHandler.ServeHTTP(w, r)
case SignalerServiceCreateSessionProcedure:
signalerServiceCreateSessionHandler.ServeHTTP(w, r)
case SignalerServiceUpdateSessionProcedure:
signalerServiceUpdateSessionHandler.ServeHTTP(w, r)
case SignalerServiceListSessionsProcedure:
signalerServiceListSessionsHandler.ServeHTTP(w, r)
case SignalerServiceCreateIceCandidateProcedure:
signalerServiceCreateIceCandidateHandler.ServeHTTP(w, r)
case SignalerServicePopIceCandidateProcedure:
signalerServicePopIceCandidateHandler.ServeHTTP(w, r)
case SignalerServiceCreateIceSessionDescriptionProcedure:
signalerServiceCreateIceSessionDescriptionHandler.ServeHTTP(w, r)
case SignalerServicePopIceSessionDescriptionProcedure:
signalerServicePopIceSessionDescriptionHandler.ServeHTTP(w, r)
default:
http.NotFound(w, r)
}
})
}
// UnimplementedSignalerServiceHandler returns CodeUnimplemented from all methods.
type UnimplementedSignalerServiceHandler struct{}
func (UnimplementedSignalerServiceHandler) CreateAuthToken(context.Context, *connect.Request[gen.CreateAuthTokenRequest]) (*connect.Response[gen.AuthToken], error) {
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("signaler.SignalerService.CreateAuthToken is not implemented"))
}
func (UnimplementedSignalerServiceHandler) ListCameras(context.Context, *connect.Request[gen.ListCamerasRequest]) (*connect.Response[gen.ListCamerasResponse], error) {
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("signaler.SignalerService.ListCameras is not implemented"))
}
func (UnimplementedSignalerServiceHandler) CreateSession(context.Context, *connect.Request[gen.CreateSessionRequest]) (*connect.Response[gen.Session], error) {
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("signaler.SignalerService.CreateSession is not implemented"))
}
func (UnimplementedSignalerServiceHandler) UpdateSession(context.Context, *connect.Request[gen.UpdateSessionRequest]) (*connect.Response[gen.Session], error) {
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("signaler.SignalerService.UpdateSession is not implemented"))
}
func (UnimplementedSignalerServiceHandler) ListSessions(context.Context, *connect.Request[gen.ListSessionsRequest]) (*connect.Response[gen.ListSessionsResponse], error) {
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("signaler.SignalerService.ListSessions is not implemented"))
}
func (UnimplementedSignalerServiceHandler) CreateIceCandidate(context.Context, *connect.Request[gen.CreateIceCandidateRequest]) (*connect.Response[gen.IceCandidate], error) {
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("signaler.SignalerService.CreateIceCandidate is not implemented"))
}
func (UnimplementedSignalerServiceHandler) PopIceCandidate(context.Context, *connect.Request[gen.PopIceCandidateRequest]) (*connect.Response[gen.IceCandidate], error) {
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("signaler.SignalerService.PopIceCandidate is not implemented"))
}
func (UnimplementedSignalerServiceHandler) CreateIceSessionDescription(context.Context, *connect.Request[gen.CreateIceSessionDescriptionRequest]) (*connect.Response[gen.IceSessionDescription], error) {
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("signaler.SignalerService.CreateIceSessionDescription is not implemented"))
}
func (UnimplementedSignalerServiceHandler) PopIceSessionDescription(context.Context, *connect.Request[gen.PopIceSessionDescriptionRequest]) (*connect.Response[gen.IceSessionDescription], error) {
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("signaler.SignalerService.PopIceSessionDescription is not implemented"))
}
+76
View File
@@ -0,0 +1,76 @@
//
// Generated code. Do not modify.
// source: internal/token.proto
//
// @dart = 2.12
// ignore_for_file: annotate_overrides, camel_case_types, comment_references
// ignore_for_file: constant_identifier_names, library_prefixes
// ignore_for_file: non_constant_identifier_names, prefer_final_fields
// ignore_for_file: unnecessary_import, unnecessary_this, unused_import
import 'dart:core' as $core;
import 'package:protobuf/protobuf.dart' as $pb;
class AuthToken extends $pb.GeneratedMessage {
factory AuthToken({
$core.String? uid,
$core.Iterable<$core.String>? homes,
}) {
final $result = create();
if (uid != null) {
$result.uid = uid;
}
if (homes != null) {
$result.homes.addAll(homes);
}
return $result;
}
AuthToken._() : super();
factory AuthToken.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
factory AuthToken.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'AuthToken', package: const $pb.PackageName(_omitMessageNames ? '' : 'token'), createEmptyInstance: create)
..aOS(1, _omitFieldNames ? '' : 'uid')
..pPS(2, _omitFieldNames ? '' : 'homes')
..hasRequiredFields = false
;
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
'Will be removed in next major version')
AuthToken clone() => AuthToken()..mergeFromMessage(this);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
'Will be removed in next major version')
AuthToken copyWith(void Function(AuthToken) updates) => super.copyWith((message) => updates(message as AuthToken)) as AuthToken;
$pb.BuilderInfo get info_ => _i;
@$core.pragma('dart2js:noInline')
static AuthToken create() => AuthToken._();
AuthToken createEmptyInstance() => create();
static $pb.PbList<AuthToken> createRepeated() => $pb.PbList<AuthToken>();
@$core.pragma('dart2js:noInline')
static AuthToken getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<AuthToken>(create);
static AuthToken? _defaultInstance;
@$pb.TagNumber(1)
$core.String get uid => $_getSZ(0);
@$pb.TagNumber(1)
set uid($core.String v) { $_setString(0, v); }
@$pb.TagNumber(1)
$core.bool hasUid() => $_has(0);
@$pb.TagNumber(1)
void clearUid() => clearField(1);
@$pb.TagNumber(2)
$core.List<$core.String> get homes => $_getList(1);
}
const _omitFieldNames = $core.bool.fromEnvironment('protobuf.omit_field_names');
const _omitMessageNames = $core.bool.fromEnvironment('protobuf.omit_message_names');
+159
View File
@@ -0,0 +1,159 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.31.0
// protoc (unknown)
// source: internal/token.proto
package internal
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
type AuthToken struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Uid string `protobuf:"bytes,1,opt,name=uid,proto3" json:"uid,omitempty"`
Homes []string `protobuf:"bytes,2,rep,name=homes,proto3" json:"homes,omitempty"`
}
func (x *AuthToken) Reset() {
*x = AuthToken{}
if protoimpl.UnsafeEnabled {
mi := &file_internal_token_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *AuthToken) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*AuthToken) ProtoMessage() {}
func (x *AuthToken) ProtoReflect() protoreflect.Message {
mi := &file_internal_token_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use AuthToken.ProtoReflect.Descriptor instead.
func (*AuthToken) Descriptor() ([]byte, []int) {
return file_internal_token_proto_rawDescGZIP(), []int{0}
}
func (x *AuthToken) GetUid() string {
if x != nil {
return x.Uid
}
return ""
}
func (x *AuthToken) GetHomes() []string {
if x != nil {
return x.Homes
}
return nil
}
var File_internal_token_proto protoreflect.FileDescriptor
var file_internal_token_proto_rawDesc = []byte{
0x0a, 0x14, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x6f, 0x6b, 0x65, 0x6e,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x33, 0x0a,
0x09, 0x41, 0x75, 0x74, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69,
0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05,
0x68, 0x6f, 0x6d, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x68, 0x6f, 0x6d,
0x65, 0x73, 0x42, 0x84, 0x01, 0x0a, 0x09, 0x63, 0x6f, 0x6d, 0x2e, 0x74, 0x6f, 0x6b, 0x65, 0x6e,
0x42, 0x0a, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x37,
0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x68, 0x61, 0x74, 0x68,
0x61, 0x77, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x2f, 0x68, 0x6f, 0x6d, 0x65, 0x2d,
0x73, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x73, 0x2f, 0x76, 0x32, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x69,
0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0xa2, 0x02, 0x03, 0x54, 0x58, 0x58, 0xaa, 0x02, 0x05,
0x54, 0x6f, 0x6b, 0x65, 0x6e, 0xca, 0x02, 0x05, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0xe2, 0x02, 0x11,
0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74,
0x61, 0xea, 0x02, 0x05, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x33,
}
var (
file_internal_token_proto_rawDescOnce sync.Once
file_internal_token_proto_rawDescData = file_internal_token_proto_rawDesc
)
func file_internal_token_proto_rawDescGZIP() []byte {
file_internal_token_proto_rawDescOnce.Do(func() {
file_internal_token_proto_rawDescData = protoimpl.X.CompressGZIP(file_internal_token_proto_rawDescData)
})
return file_internal_token_proto_rawDescData
}
var file_internal_token_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
var file_internal_token_proto_goTypes = []interface{}{
(*AuthToken)(nil), // 0: token.AuthToken
}
var file_internal_token_proto_depIdxs = []int32{
0, // [0:0] is the sub-list for method output_type
0, // [0:0] is the sub-list for method input_type
0, // [0:0] is the sub-list for extension type_name
0, // [0:0] is the sub-list for extension extendee
0, // [0:0] is the sub-list for field type_name
}
func init() { file_internal_token_proto_init() }
func file_internal_token_proto_init() {
if File_internal_token_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_internal_token_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*AuthToken); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_internal_token_proto_rawDesc,
NumEnums: 0,
NumMessages: 1,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_internal_token_proto_goTypes,
DependencyIndexes: file_internal_token_proto_depIdxs,
MessageInfos: file_internal_token_proto_msgTypes,
}.Build()
File_internal_token_proto = out.File
file_internal_token_proto_rawDesc = nil
file_internal_token_proto_goTypes = nil
file_internal_token_proto_depIdxs = nil
}
+11
View File
@@ -0,0 +1,11 @@
//
// Generated code. Do not modify.
// source: internal/token.proto
//
// @dart = 2.12
// ignore_for_file: annotate_overrides, camel_case_types, comment_references
// ignore_for_file: constant_identifier_names, library_prefixes
// ignore_for_file: non_constant_identifier_names, prefer_final_fields
// ignore_for_file: unnecessary_import, unnecessary_this, unused_import
+28
View File
@@ -0,0 +1,28 @@
//
// Generated code. Do not modify.
// source: internal/token.proto
//
// @dart = 2.12
// ignore_for_file: annotate_overrides, camel_case_types, comment_references
// ignore_for_file: constant_identifier_names, library_prefixes
// ignore_for_file: non_constant_identifier_names, prefer_final_fields
// ignore_for_file: unnecessary_import, unnecessary_this, unused_import
import 'dart:convert' as $convert;
import 'dart:core' as $core;
import 'dart:typed_data' as $typed_data;
@$core.Deprecated('Use authTokenDescriptor instead')
const AuthToken$json = {
'1': 'AuthToken',
'2': [
{'1': 'uid', '3': 1, '4': 1, '5': 9, '10': 'uid'},
{'1': 'homes', '3': 2, '4': 3, '5': 9, '10': 'homes'},
],
};
/// Descriptor for `AuthToken`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List authTokenDescriptor = $convert.base64Decode(
'CglBdXRoVG9rZW4SEAoDdWlkGAEgASgJUgN1aWQSFAoFaG9tZXMYAiADKAlSBWhvbWVz');
+14
View File
@@ -0,0 +1,14 @@
//
// Generated code. Do not modify.
// source: internal/token.proto
//
// @dart = 2.12
// ignore_for_file: annotate_overrides, camel_case_types, comment_references
// ignore_for_file: constant_identifier_names
// ignore_for_file: deprecated_member_use_from_same_package, library_prefixes
// ignore_for_file: non_constant_identifier_names, prefer_final_fields
// ignore_for_file: unnecessary_import, unnecessary_this, unused_import
export 'token.pb.dart';
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+11
View File
@@ -0,0 +1,11 @@
//
// Generated code. Do not modify.
// source: signaler_service.proto
//
// @dart = 2.12
// ignore_for_file: annotate_overrides, camel_case_types, comment_references
// ignore_for_file: constant_identifier_names, library_prefixes
// ignore_for_file: non_constant_identifier_names, prefer_final_fields
// ignore_for_file: unnecessary_import, unnecessary_this, unused_import
+338
View File
@@ -0,0 +1,338 @@
//
// Generated code. Do not modify.
// source: signaler_service.proto
//
// @dart = 2.12
// ignore_for_file: annotate_overrides, camel_case_types, comment_references
// ignore_for_file: constant_identifier_names, library_prefixes
// ignore_for_file: non_constant_identifier_names, prefer_final_fields
// ignore_for_file: unnecessary_import, unnecessary_this, unused_import
import 'dart:convert' as $convert;
import 'dart:core' as $core;
import 'dart:typed_data' as $typed_data;
@$core.Deprecated('Use createAuthTokenRequestDescriptor instead')
const CreateAuthTokenRequest$json = {
'1': 'CreateAuthTokenRequest',
'2': [
{'1': 'home', '3': 1, '4': 1, '5': 9, '10': 'home'},
{'1': 'camera', '3': 2, '4': 1, '5': 11, '6': '.signaler.CreateAuthTokenRequest.Camera', '9': 0, '10': 'camera'},
{'1': 'client', '3': 3, '4': 1, '5': 11, '6': '.signaler.CreateAuthTokenRequest.Client', '9': 0, '10': 'client'},
],
'3': [CreateAuthTokenRequest_Camera$json, CreateAuthTokenRequest_Client$json],
'8': [
{'1': 'type'},
],
};
@$core.Deprecated('Use createAuthTokenRequestDescriptor instead')
const CreateAuthTokenRequest_Camera$json = {
'1': 'Camera',
'2': [
{'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'},
],
};
@$core.Deprecated('Use createAuthTokenRequestDescriptor instead')
const CreateAuthTokenRequest_Client$json = {
'1': 'Client',
};
/// Descriptor for `CreateAuthTokenRequest`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List createAuthTokenRequestDescriptor = $convert.base64Decode(
'ChZDcmVhdGVBdXRoVG9rZW5SZXF1ZXN0EhIKBGhvbWUYASABKAlSBGhvbWUSQQoGY2FtZXJhGA'
'IgASgLMicuc2lnbmFsZXIuQ3JlYXRlQXV0aFRva2VuUmVxdWVzdC5DYW1lcmFIAFIGY2FtZXJh'
'EkEKBmNsaWVudBgDIAEoCzInLnNpZ25hbGVyLkNyZWF0ZUF1dGhUb2tlblJlcXVlc3QuQ2xpZW'
'50SABSBmNsaWVudBoYCgZDYW1lcmESDgoCaWQYASABKAlSAmlkGggKBkNsaWVudEIGCgR0eXBl');
@$core.Deprecated('Use listCamerasRequestDescriptor instead')
const ListCamerasRequest$json = {
'1': 'ListCamerasRequest',
};
/// Descriptor for `ListCamerasRequest`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List listCamerasRequestDescriptor = $convert.base64Decode(
'ChJMaXN0Q2FtZXJhc1JlcXVlc3Q=');
@$core.Deprecated('Use listCamerasResponseDescriptor instead')
const ListCamerasResponse$json = {
'1': 'ListCamerasResponse',
'2': [
{'1': 'cameras', '3': 1, '4': 3, '5': 11, '6': '.signaler.Camera', '10': 'cameras'},
],
};
/// Descriptor for `ListCamerasResponse`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List listCamerasResponseDescriptor = $convert.base64Decode(
'ChNMaXN0Q2FtZXJhc1Jlc3BvbnNlEioKB2NhbWVyYXMYASADKAsyEC5zaWduYWxlci5DYW1lcm'
'FSB2NhbWVyYXM=');
@$core.Deprecated('Use createSessionRequestDescriptor instead')
const CreateSessionRequest$json = {
'1': 'CreateSessionRequest',
'2': [
{'1': 'session', '3': 1, '4': 1, '5': 11, '6': '.signaler.Session', '10': 'session'},
{'1': 'wait_for_update', '3': 2, '4': 1, '5': 8, '10': 'waitForUpdate'},
],
};
/// Descriptor for `CreateSessionRequest`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List createSessionRequestDescriptor = $convert.base64Decode(
'ChRDcmVhdGVTZXNzaW9uUmVxdWVzdBIrCgdzZXNzaW9uGAEgASgLMhEuc2lnbmFsZXIuU2Vzc2'
'lvblIHc2Vzc2lvbhImCg93YWl0X2Zvcl91cGRhdGUYAiABKAhSDXdhaXRGb3JVcGRhdGU=');
@$core.Deprecated('Use updateSessionRequestDescriptor instead')
const UpdateSessionRequest$json = {
'1': 'UpdateSessionRequest',
'2': [
{'1': 'session', '3': 1, '4': 1, '5': 11, '6': '.signaler.Session', '10': 'session'},
{'1': 'wait_for_update', '3': 2, '4': 1, '5': 8, '10': 'waitForUpdate'},
],
};
/// Descriptor for `UpdateSessionRequest`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List updateSessionRequestDescriptor = $convert.base64Decode(
'ChRVcGRhdGVTZXNzaW9uUmVxdWVzdBIrCgdzZXNzaW9uGAEgASgLMhEuc2lnbmFsZXIuU2Vzc2'
'lvblIHc2Vzc2lvbhImCg93YWl0X2Zvcl91cGRhdGUYAiABKAhSDXdhaXRGb3JVcGRhdGU=');
@$core.Deprecated('Use listSessionsRequestDescriptor instead')
const ListSessionsRequest$json = {
'1': 'ListSessionsRequest',
};
/// Descriptor for `ListSessionsRequest`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List listSessionsRequestDescriptor = $convert.base64Decode(
'ChNMaXN0U2Vzc2lvbnNSZXF1ZXN0');
@$core.Deprecated('Use listSessionsResponseDescriptor instead')
const ListSessionsResponse$json = {
'1': 'ListSessionsResponse',
'2': [
{'1': 'sessions', '3': 1, '4': 3, '5': 11, '6': '.signaler.Session', '10': 'sessions'},
],
};
/// Descriptor for `ListSessionsResponse`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List listSessionsResponseDescriptor = $convert.base64Decode(
'ChRMaXN0U2Vzc2lvbnNSZXNwb25zZRItCghzZXNzaW9ucxgBIAMoCzIRLnNpZ25hbGVyLlNlc3'
'Npb25SCHNlc3Npb25z');
@$core.Deprecated('Use createIceCandidateRequestDescriptor instead')
const CreateIceCandidateRequest$json = {
'1': 'CreateIceCandidateRequest',
'2': [
{'1': 'session_identifier', '3': 1, '4': 1, '5': 11, '6': '.signaler.Session.Identifier', '10': 'sessionIdentifier'},
{'1': 'candidate', '3': 2, '4': 1, '5': 11, '6': '.signaler.IceCandidate', '10': 'candidate'},
],
};
/// Descriptor for `CreateIceCandidateRequest`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List createIceCandidateRequestDescriptor = $convert.base64Decode(
'ChlDcmVhdGVJY2VDYW5kaWRhdGVSZXF1ZXN0EksKEnNlc3Npb25faWRlbnRpZmllchgBIAEoCz'
'IcLnNpZ25hbGVyLlNlc3Npb24uSWRlbnRpZmllclIRc2Vzc2lvbklkZW50aWZpZXISNAoJY2Fu'
'ZGlkYXRlGAIgASgLMhYuc2lnbmFsZXIuSWNlQ2FuZGlkYXRlUgljYW5kaWRhdGU=');
@$core.Deprecated('Use popIceCandidateRequestDescriptor instead')
const PopIceCandidateRequest$json = {
'1': 'PopIceCandidateRequest',
'2': [
{'1': 'session_identifier', '3': 1, '4': 1, '5': 11, '6': '.signaler.Session.Identifier', '10': 'sessionIdentifier'},
],
};
/// Descriptor for `PopIceCandidateRequest`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List popIceCandidateRequestDescriptor = $convert.base64Decode(
'ChZQb3BJY2VDYW5kaWRhdGVSZXF1ZXN0EksKEnNlc3Npb25faWRlbnRpZmllchgBIAEoCzIcLn'
'NpZ25hbGVyLlNlc3Npb24uSWRlbnRpZmllclIRc2Vzc2lvbklkZW50aWZpZXI=');
@$core.Deprecated('Use createIceSessionDescriptionRequestDescriptor instead')
const CreateIceSessionDescriptionRequest$json = {
'1': 'CreateIceSessionDescriptionRequest',
'2': [
{'1': 'session_identifier', '3': 1, '4': 1, '5': 11, '6': '.signaler.Session.Identifier', '10': 'sessionIdentifier'},
{'1': 'description', '3': 2, '4': 1, '5': 11, '6': '.signaler.IceSessionDescription', '10': 'description'},
],
};
/// Descriptor for `CreateIceSessionDescriptionRequest`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List createIceSessionDescriptionRequestDescriptor = $convert.base64Decode(
'CiJDcmVhdGVJY2VTZXNzaW9uRGVzY3JpcHRpb25SZXF1ZXN0EksKEnNlc3Npb25faWRlbnRpZm'
'llchgBIAEoCzIcLnNpZ25hbGVyLlNlc3Npb24uSWRlbnRpZmllclIRc2Vzc2lvbklkZW50aWZp'
'ZXISQQoLZGVzY3JpcHRpb24YAiABKAsyHy5zaWduYWxlci5JY2VTZXNzaW9uRGVzY3JpcHRpb2'
'5SC2Rlc2NyaXB0aW9u');
@$core.Deprecated('Use popIceSessionDescriptionRequestDescriptor instead')
const PopIceSessionDescriptionRequest$json = {
'1': 'PopIceSessionDescriptionRequest',
'2': [
{'1': 'session_identifier', '3': 1, '4': 1, '5': 11, '6': '.signaler.Session.Identifier', '10': 'sessionIdentifier'},
],
};
/// Descriptor for `PopIceSessionDescriptionRequest`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List popIceSessionDescriptionRequestDescriptor = $convert.base64Decode(
'Ch9Qb3BJY2VTZXNzaW9uRGVzY3JpcHRpb25SZXF1ZXN0EksKEnNlc3Npb25faWRlbnRpZmllch'
'gBIAEoCzIcLnNpZ25hbGVyLlNlc3Npb24uSWRlbnRpZmllclIRc2Vzc2lvbklkZW50aWZpZXI=');
@$core.Deprecated('Use cameraDescriptor instead')
const Camera$json = {
'1': 'Camera',
'2': [
{'1': 'identifier', '3': 1, '4': 1, '5': 11, '6': '.signaler.Camera.Identifier', '10': 'identifier'},
],
'3': [Camera_Identifier$json],
};
@$core.Deprecated('Use cameraDescriptor instead')
const Camera_Identifier$json = {
'1': 'Identifier',
'2': [
{'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'},
],
};
/// Descriptor for `Camera`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List cameraDescriptor = $convert.base64Decode(
'CgZDYW1lcmESOwoKaWRlbnRpZmllchgBIAEoCzIbLnNpZ25hbGVyLkNhbWVyYS5JZGVudGlmaW'
'VyUgppZGVudGlmaWVyGhwKCklkZW50aWZpZXISDgoCaWQYASABKAlSAmlk');
@$core.Deprecated('Use iceCandidateDescriptor instead')
const IceCandidate$json = {
'1': 'IceCandidate',
'2': [
{'1': 'candidate', '3': 1, '4': 1, '5': 9, '10': 'candidate'},
{'1': 'sdp_mid', '3': 2, '4': 1, '5': 9, '9': 0, '10': 'sdpMid', '17': true},
{'1': 'sdp_line_index', '3': 3, '4': 1, '5': 5, '9': 1, '10': 'sdpLineIndex', '17': true},
{'1': 'username_fragment', '3': 4, '4': 1, '5': 9, '9': 2, '10': 'usernameFragment', '17': true},
],
'8': [
{'1': '_sdp_mid'},
{'1': '_sdp_line_index'},
{'1': '_username_fragment'},
],
};
/// Descriptor for `IceCandidate`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List iceCandidateDescriptor = $convert.base64Decode(
'CgxJY2VDYW5kaWRhdGUSHAoJY2FuZGlkYXRlGAEgASgJUgljYW5kaWRhdGUSHAoHc2RwX21pZB'
'gCIAEoCUgAUgZzZHBNaWSIAQESKQoOc2RwX2xpbmVfaW5kZXgYAyABKAVIAVIMc2RwTGluZUlu'
'ZGV4iAEBEjAKEXVzZXJuYW1lX2ZyYWdtZW50GAQgASgJSAJSEHVzZXJuYW1lRnJhZ21lbnSIAQ'
'FCCgoIX3NkcF9taWRCEQoPX3NkcF9saW5lX2luZGV4QhQKEl91c2VybmFtZV9mcmFnbWVudA==');
@$core.Deprecated('Use iceSessionDescriptionDescriptor instead')
const IceSessionDescription$json = {
'1': 'IceSessionDescription',
'2': [
{'1': 'sdp_type', '3': 1, '4': 1, '5': 3, '10': 'sdpType'},
{'1': 'sdp', '3': 2, '4': 1, '5': 9, '10': 'sdp'},
],
};
/// Descriptor for `IceSessionDescription`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List iceSessionDescriptionDescriptor = $convert.base64Decode(
'ChVJY2VTZXNzaW9uRGVzY3JpcHRpb24SGQoIc2RwX3R5cGUYASABKANSB3NkcFR5cGUSEAoDc2'
'RwGAIgASgJUgNzZHA=');
@$core.Deprecated('Use sessionDescriptor instead')
const Session$json = {
'1': 'Session',
'2': [
{'1': 'id', '3': 1, '4': 1, '5': 11, '6': '.signaler.Session.Identifier', '10': 'id'},
{'1': 'camera', '3': 2, '4': 1, '5': 11, '6': '.signaler.Camera.Identifier', '10': 'camera'},
{'1': 'client_ice_candidates', '3': 3, '4': 3, '5': 11, '6': '.signaler.IceCandidate', '10': 'clientIceCandidates'},
{'1': 'camera_ice_candidates', '3': 4, '4': 3, '5': 11, '6': '.signaler.IceCandidate', '10': 'cameraIceCandidates'},
{'1': 'camera_offer', '3': 5, '4': 1, '5': 11, '6': '.signaler.IceSessionDescription', '10': 'cameraOffer'},
{'1': 'client_answer', '3': 6, '4': 1, '5': 11, '6': '.signaler.IceSessionDescription', '10': 'clientAnswer'},
],
'3': [Session_Identifier$json],
};
@$core.Deprecated('Use sessionDescriptor instead')
const Session_Identifier$json = {
'1': 'Identifier',
'2': [
{'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'},
],
};
/// Descriptor for `Session`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List sessionDescriptor = $convert.base64Decode(
'CgdTZXNzaW9uEiwKAmlkGAEgASgLMhwuc2lnbmFsZXIuU2Vzc2lvbi5JZGVudGlmaWVyUgJpZB'
'IzCgZjYW1lcmEYAiABKAsyGy5zaWduYWxlci5DYW1lcmEuSWRlbnRpZmllclIGY2FtZXJhEkoK'
'FWNsaWVudF9pY2VfY2FuZGlkYXRlcxgDIAMoCzIWLnNpZ25hbGVyLkljZUNhbmRpZGF0ZVITY2'
'xpZW50SWNlQ2FuZGlkYXRlcxJKChVjYW1lcmFfaWNlX2NhbmRpZGF0ZXMYBCADKAsyFi5zaWdu'
'YWxlci5JY2VDYW5kaWRhdGVSE2NhbWVyYUljZUNhbmRpZGF0ZXMSQgoMY2FtZXJhX29mZmVyGA'
'UgASgLMh8uc2lnbmFsZXIuSWNlU2Vzc2lvbkRlc2NyaXB0aW9uUgtjYW1lcmFPZmZlchJECg1j'
'bGllbnRfYW5zd2VyGAYgASgLMh8uc2lnbmFsZXIuSWNlU2Vzc2lvbkRlc2NyaXB0aW9uUgxjbG'
'llbnRBbnN3ZXIaHAoKSWRlbnRpZmllchIOCgJpZBgBIAEoCVICaWQ=');
@$core.Deprecated('Use authTokenDescriptor instead')
const AuthToken$json = {
'1': 'AuthToken',
'2': [
{'1': 'token', '3': 1, '4': 1, '5': 9, '10': 'token'},
],
};
/// Descriptor for `AuthToken`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List authTokenDescriptor = $convert.base64Decode(
'CglBdXRoVG9rZW4SFAoFdG9rZW4YASABKAlSBXRva2Vu');
const $core.Map<$core.String, $core.dynamic> SignalerServiceBase$json = {
'1': 'SignalerService',
'2': [
{'1': 'CreateAuthToken', '2': '.signaler.CreateAuthTokenRequest', '3': '.signaler.AuthToken'},
{'1': 'ListCameras', '2': '.signaler.ListCamerasRequest', '3': '.signaler.ListCamerasResponse'},
{'1': 'CreateSession', '2': '.signaler.CreateSessionRequest', '3': '.signaler.Session'},
{'1': 'UpdateSession', '2': '.signaler.UpdateSessionRequest', '3': '.signaler.Session'},
{'1': 'ListSessions', '2': '.signaler.ListSessionsRequest', '3': '.signaler.ListSessionsResponse'},
{'1': 'CreateIceCandidate', '2': '.signaler.CreateIceCandidateRequest', '3': '.signaler.IceCandidate'},
{'1': 'PopIceCandidate', '2': '.signaler.PopIceCandidateRequest', '3': '.signaler.IceCandidate'},
{'1': 'CreateIceSessionDescription', '2': '.signaler.CreateIceSessionDescriptionRequest', '3': '.signaler.IceSessionDescription'},
{'1': 'PopIceSessionDescription', '2': '.signaler.PopIceSessionDescriptionRequest', '3': '.signaler.IceSessionDescription'},
],
};
@$core.Deprecated('Use signalerServiceDescriptor instead')
const $core.Map<$core.String, $core.Map<$core.String, $core.dynamic>> SignalerServiceBase$messageJson = {
'.signaler.CreateAuthTokenRequest': CreateAuthTokenRequest$json,
'.signaler.CreateAuthTokenRequest.Camera': CreateAuthTokenRequest_Camera$json,
'.signaler.CreateAuthTokenRequest.Client': CreateAuthTokenRequest_Client$json,
'.signaler.AuthToken': AuthToken$json,
'.signaler.ListCamerasRequest': ListCamerasRequest$json,
'.signaler.ListCamerasResponse': ListCamerasResponse$json,
'.signaler.Camera': Camera$json,
'.signaler.Camera.Identifier': Camera_Identifier$json,
'.signaler.CreateSessionRequest': CreateSessionRequest$json,
'.signaler.Session': Session$json,
'.signaler.Session.Identifier': Session_Identifier$json,
'.signaler.IceCandidate': IceCandidate$json,
'.signaler.IceSessionDescription': IceSessionDescription$json,
'.signaler.UpdateSessionRequest': UpdateSessionRequest$json,
'.signaler.ListSessionsRequest': ListSessionsRequest$json,
'.signaler.ListSessionsResponse': ListSessionsResponse$json,
'.signaler.CreateIceCandidateRequest': CreateIceCandidateRequest$json,
'.signaler.PopIceCandidateRequest': PopIceCandidateRequest$json,
'.signaler.CreateIceSessionDescriptionRequest': CreateIceSessionDescriptionRequest$json,
'.signaler.PopIceSessionDescriptionRequest': PopIceSessionDescriptionRequest$json,
};
/// Descriptor for `SignalerService`. Decode as a `google.protobuf.ServiceDescriptorProto`.
final $typed_data.Uint8List signalerServiceDescriptor = $convert.base64Decode(
'Cg9TaWduYWxlclNlcnZpY2USSAoPQ3JlYXRlQXV0aFRva2VuEiAuc2lnbmFsZXIuQ3JlYXRlQX'
'V0aFRva2VuUmVxdWVzdBoTLnNpZ25hbGVyLkF1dGhUb2tlbhJKCgtMaXN0Q2FtZXJhcxIcLnNp'
'Z25hbGVyLkxpc3RDYW1lcmFzUmVxdWVzdBodLnNpZ25hbGVyLkxpc3RDYW1lcmFzUmVzcG9uc2'
'USQgoNQ3JlYXRlU2Vzc2lvbhIeLnNpZ25hbGVyLkNyZWF0ZVNlc3Npb25SZXF1ZXN0GhEuc2ln'
'bmFsZXIuU2Vzc2lvbhJCCg1VcGRhdGVTZXNzaW9uEh4uc2lnbmFsZXIuVXBkYXRlU2Vzc2lvbl'
'JlcXVlc3QaES5zaWduYWxlci5TZXNzaW9uEk0KDExpc3RTZXNzaW9ucxIdLnNpZ25hbGVyLkxp'
'c3RTZXNzaW9uc1JlcXVlc3QaHi5zaWduYWxlci5MaXN0U2Vzc2lvbnNSZXNwb25zZRJRChJDcm'
'VhdGVJY2VDYW5kaWRhdGUSIy5zaWduYWxlci5DcmVhdGVJY2VDYW5kaWRhdGVSZXF1ZXN0GhYu'
'c2lnbmFsZXIuSWNlQ2FuZGlkYXRlEksKD1BvcEljZUNhbmRpZGF0ZRIgLnNpZ25hbGVyLlBvcE'
'ljZUNhbmRpZGF0ZVJlcXVlc3QaFi5zaWduYWxlci5JY2VDYW5kaWRhdGUSbAobQ3JlYXRlSWNl'
'U2Vzc2lvbkRlc2NyaXB0aW9uEiwuc2lnbmFsZXIuQ3JlYXRlSWNlU2Vzc2lvbkRlc2NyaXB0aW'
'9uUmVxdWVzdBofLnNpZ25hbGVyLkljZVNlc3Npb25EZXNjcmlwdGlvbhJmChhQb3BJY2VTZXNz'
'aW9uRGVzY3JpcHRpb24SKS5zaWduYWxlci5Qb3BJY2VTZXNzaW9uRGVzY3JpcHRpb25SZXF1ZX'
'N0Gh8uc2lnbmFsZXIuSWNlU2Vzc2lvbkRlc2NyaXB0aW9u');
+67
View File
@@ -0,0 +1,67 @@
//
// Generated code. Do not modify.
// source: signaler_service.proto
//
// @dart = 2.12
// ignore_for_file: annotate_overrides, camel_case_types, comment_references
// ignore_for_file: constant_identifier_names
// ignore_for_file: deprecated_member_use_from_same_package, library_prefixes
// ignore_for_file: non_constant_identifier_names, prefer_final_fields
// ignore_for_file: unnecessary_import, unnecessary_this, unused_import
import 'dart:async' as $async;
import 'dart:core' as $core;
import 'package:protobuf/protobuf.dart' as $pb;
import 'signaler_service.pb.dart' as $0;
import 'signaler_service.pbjson.dart';
export 'signaler_service.pb.dart';
abstract class SignalerServiceBase extends $pb.GeneratedService {
$async.Future<$0.AuthToken> createAuthToken($pb.ServerContext ctx, $0.CreateAuthTokenRequest request);
$async.Future<$0.ListCamerasResponse> listCameras($pb.ServerContext ctx, $0.ListCamerasRequest request);
$async.Future<$0.Session> createSession($pb.ServerContext ctx, $0.CreateSessionRequest request);
$async.Future<$0.Session> updateSession($pb.ServerContext ctx, $0.UpdateSessionRequest request);
$async.Future<$0.ListSessionsResponse> listSessions($pb.ServerContext ctx, $0.ListSessionsRequest request);
$async.Future<$0.IceCandidate> createIceCandidate($pb.ServerContext ctx, $0.CreateIceCandidateRequest request);
$async.Future<$0.IceCandidate> popIceCandidate($pb.ServerContext ctx, $0.PopIceCandidateRequest request);
$async.Future<$0.IceSessionDescription> createIceSessionDescription($pb.ServerContext ctx, $0.CreateIceSessionDescriptionRequest request);
$async.Future<$0.IceSessionDescription> popIceSessionDescription($pb.ServerContext ctx, $0.PopIceSessionDescriptionRequest request);
$pb.GeneratedMessage createRequest($core.String methodName) {
switch (methodName) {
case 'CreateAuthToken': return $0.CreateAuthTokenRequest();
case 'ListCameras': return $0.ListCamerasRequest();
case 'CreateSession': return $0.CreateSessionRequest();
case 'UpdateSession': return $0.UpdateSessionRequest();
case 'ListSessions': return $0.ListSessionsRequest();
case 'CreateIceCandidate': return $0.CreateIceCandidateRequest();
case 'PopIceCandidate': return $0.PopIceCandidateRequest();
case 'CreateIceSessionDescription': return $0.CreateIceSessionDescriptionRequest();
case 'PopIceSessionDescription': return $0.PopIceSessionDescriptionRequest();
default: throw $core.ArgumentError('Unknown method: $methodName');
}
}
$async.Future<$pb.GeneratedMessage> handleCall($pb.ServerContext ctx, $core.String methodName, $pb.GeneratedMessage request) {
switch (methodName) {
case 'CreateAuthToken': return this.createAuthToken(ctx, request as $0.CreateAuthTokenRequest);
case 'ListCameras': return this.listCameras(ctx, request as $0.ListCamerasRequest);
case 'CreateSession': return this.createSession(ctx, request as $0.CreateSessionRequest);
case 'UpdateSession': return this.updateSession(ctx, request as $0.UpdateSessionRequest);
case 'ListSessions': return this.listSessions(ctx, request as $0.ListSessionsRequest);
case 'CreateIceCandidate': return this.createIceCandidate(ctx, request as $0.CreateIceCandidateRequest);
case 'PopIceCandidate': return this.popIceCandidate(ctx, request as $0.PopIceCandidateRequest);
case 'CreateIceSessionDescription': return this.createIceSessionDescription(ctx, request as $0.CreateIceSessionDescriptionRequest);
case 'PopIceSessionDescription': return this.popIceSessionDescription(ctx, request as $0.PopIceSessionDescriptionRequest);
default: throw $core.ArgumentError('Unknown method: $methodName');
}
}
$core.Map<$core.String, $core.dynamic> get $json => SignalerServiceBase$json;
$core.Map<$core.String, $core.Map<$core.String, $core.dynamic>> get $messageJson => SignalerServiceBase$messageJson;
}
+82
View File
@@ -0,0 +1,82 @@
//
// Generated code. Do not modify.
// source: token/token.proto
//
// @dart = 2.12
// ignore_for_file: annotate_overrides, camel_case_types, comment_references
// ignore_for_file: constant_identifier_names, library_prefixes
// ignore_for_file: non_constant_identifier_names, prefer_final_fields
// ignore_for_file: unnecessary_import, unnecessary_this, unused_import
import 'dart:core' as $core;
import 'package:protobuf/protobuf.dart' as $pb;
class AuthToken extends $pb.GeneratedMessage {
factory AuthToken({
$core.String? uid,
$core.String? home,
}) {
final $result = create();
if (uid != null) {
$result.uid = uid;
}
if (home != null) {
$result.home = home;
}
return $result;
}
AuthToken._() : super();
factory AuthToken.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
factory AuthToken.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'AuthToken', package: const $pb.PackageName(_omitMessageNames ? '' : 'token'), createEmptyInstance: create)
..aOS(1, _omitFieldNames ? '' : 'uid')
..aOS(2, _omitFieldNames ? '' : 'home')
..hasRequiredFields = false
;
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
'Will be removed in next major version')
AuthToken clone() => AuthToken()..mergeFromMessage(this);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
'Will be removed in next major version')
AuthToken copyWith(void Function(AuthToken) updates) => super.copyWith((message) => updates(message as AuthToken)) as AuthToken;
$pb.BuilderInfo get info_ => _i;
@$core.pragma('dart2js:noInline')
static AuthToken create() => AuthToken._();
AuthToken createEmptyInstance() => create();
static $pb.PbList<AuthToken> createRepeated() => $pb.PbList<AuthToken>();
@$core.pragma('dart2js:noInline')
static AuthToken getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<AuthToken>(create);
static AuthToken? _defaultInstance;
@$pb.TagNumber(1)
$core.String get uid => $_getSZ(0);
@$pb.TagNumber(1)
set uid($core.String v) { $_setString(0, v); }
@$pb.TagNumber(1)
$core.bool hasUid() => $_has(0);
@$pb.TagNumber(1)
void clearUid() => clearField(1);
@$pb.TagNumber(2)
$core.String get home => $_getSZ(1);
@$pb.TagNumber(2)
set home($core.String v) { $_setString(1, v); }
@$pb.TagNumber(2)
$core.bool hasHome() => $_has(1);
@$pb.TagNumber(2)
void clearHome() => clearField(2);
}
const _omitFieldNames = $core.bool.fromEnvironment('protobuf.omit_field_names');
const _omitMessageNames = $core.bool.fromEnvironment('protobuf.omit_message_names');
+158
View File
@@ -0,0 +1,158 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.31.0
// protoc (unknown)
// source: token/token.proto
package token
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
type AuthToken struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Uid string `protobuf:"bytes,1,opt,name=uid,proto3" json:"uid,omitempty"`
Home string `protobuf:"bytes,2,opt,name=home,proto3" json:"home,omitempty"`
}
func (x *AuthToken) Reset() {
*x = AuthToken{}
if protoimpl.UnsafeEnabled {
mi := &file_token_token_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *AuthToken) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*AuthToken) ProtoMessage() {}
func (x *AuthToken) ProtoReflect() protoreflect.Message {
mi := &file_token_token_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use AuthToken.ProtoReflect.Descriptor instead.
func (*AuthToken) Descriptor() ([]byte, []int) {
return file_token_token_proto_rawDescGZIP(), []int{0}
}
func (x *AuthToken) GetUid() string {
if x != nil {
return x.Uid
}
return ""
}
func (x *AuthToken) GetHome() string {
if x != nil {
return x.Home
}
return ""
}
var File_token_token_proto protoreflect.FileDescriptor
var file_token_token_proto_rawDesc = []byte{
0x0a, 0x11, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x2f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x2e, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x12, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x31, 0x0a, 0x09, 0x41, 0x75,
0x74, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x01,
0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x6f, 0x6d,
0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x6f, 0x6d, 0x65, 0x42, 0x81, 0x01,
0x0a, 0x09, 0x63, 0x6f, 0x6d, 0x2e, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x42, 0x0a, 0x54, 0x6f, 0x6b,
0x65, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x34, 0x67, 0x69, 0x74, 0x68, 0x75,
0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x68, 0x61, 0x74, 0x68, 0x61, 0x77, 0x61, 0x79, 0x2d,
0x63, 0x6f, 0x64, 0x65, 0x73, 0x2f, 0x68, 0x6f, 0x6d, 0x65, 0x2d, 0x73, 0x65, 0x6e, 0x73, 0x6f,
0x72, 0x73, 0x2f, 0x76, 0x32, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0xa2,
0x02, 0x03, 0x54, 0x58, 0x58, 0xaa, 0x02, 0x05, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0xca, 0x02, 0x05,
0x54, 0x6f, 0x6b, 0x65, 0x6e, 0xe2, 0x02, 0x11, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x5c, 0x47, 0x50,
0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x05, 0x54, 0x6f, 0x6b, 0x65,
0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
file_token_token_proto_rawDescOnce sync.Once
file_token_token_proto_rawDescData = file_token_token_proto_rawDesc
)
func file_token_token_proto_rawDescGZIP() []byte {
file_token_token_proto_rawDescOnce.Do(func() {
file_token_token_proto_rawDescData = protoimpl.X.CompressGZIP(file_token_token_proto_rawDescData)
})
return file_token_token_proto_rawDescData
}
var file_token_token_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
var file_token_token_proto_goTypes = []interface{}{
(*AuthToken)(nil), // 0: token.AuthToken
}
var file_token_token_proto_depIdxs = []int32{
0, // [0:0] is the sub-list for method output_type
0, // [0:0] is the sub-list for method input_type
0, // [0:0] is the sub-list for extension type_name
0, // [0:0] is the sub-list for extension extendee
0, // [0:0] is the sub-list for field type_name
}
func init() { file_token_token_proto_init() }
func file_token_token_proto_init() {
if File_token_token_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_token_token_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*AuthToken); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_token_token_proto_rawDesc,
NumEnums: 0,
NumMessages: 1,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_token_token_proto_goTypes,
DependencyIndexes: file_token_token_proto_depIdxs,
MessageInfos: file_token_token_proto_msgTypes,
}.Build()
File_token_token_proto = out.File
file_token_token_proto_rawDesc = nil
file_token_token_proto_goTypes = nil
file_token_token_proto_depIdxs = nil
}
+11
View File
@@ -0,0 +1,11 @@
//
// Generated code. Do not modify.
// source: token/token.proto
//
// @dart = 2.12
// ignore_for_file: annotate_overrides, camel_case_types, comment_references
// ignore_for_file: constant_identifier_names, library_prefixes
// ignore_for_file: non_constant_identifier_names, prefer_final_fields
// ignore_for_file: unnecessary_import, unnecessary_this, unused_import
+28
View File
@@ -0,0 +1,28 @@
//
// Generated code. Do not modify.
// source: token/token.proto
//
// @dart = 2.12
// ignore_for_file: annotate_overrides, camel_case_types, comment_references
// ignore_for_file: constant_identifier_names, library_prefixes
// ignore_for_file: non_constant_identifier_names, prefer_final_fields
// ignore_for_file: unnecessary_import, unnecessary_this, unused_import
import 'dart:convert' as $convert;
import 'dart:core' as $core;
import 'dart:typed_data' as $typed_data;
@$core.Deprecated('Use authTokenDescriptor instead')
const AuthToken$json = {
'1': 'AuthToken',
'2': [
{'1': 'uid', '3': 1, '4': 1, '5': 9, '10': 'uid'},
{'1': 'home', '3': 2, '4': 1, '5': 9, '10': 'home'},
],
};
/// Descriptor for `AuthToken`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List authTokenDescriptor = $convert.base64Decode(
'CglBdXRoVG9rZW4SEAoDdWlkGAEgASgJUgN1aWQSEgoEaG9tZRgCIAEoCVIEaG9tZQ==');
+14
View File
@@ -0,0 +1,14 @@
//
// Generated code. Do not modify.
// source: token/token.proto
//
// @dart = 2.12
// ignore_for_file: annotate_overrides, camel_case_types, comment_references
// ignore_for_file: constant_identifier_names
// ignore_for_file: deprecated_member_use_from_same_package, library_prefixes
// ignore_for_file: non_constant_identifier_names, prefer_final_fields
// ignore_for_file: unnecessary_import, unnecessary_this, unused_import
export 'token.pb.dart';
+38
View File
@@ -1,3 +1,41 @@
module github.com/chathaway-codes/home-sensors/v2 module github.com/chathaway-codes/home-sensors/v2
go 1.21.1 go 1.21.1
require (
connectrpc.com/connect v1.11.1
connectrpc.com/grpcreflect v1.2.0
github.com/gofrs/uuid/v5 v5.0.0
github.com/pion/example-webrtc-applications/v3 v3.0.5
github.com/pion/webrtc/v3 v3.2.20
google.golang.org/grpc v1.58.1
google.golang.org/protobuf v1.31.0
)
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/uuid v1.3.1 // indirect
github.com/pion/datachannel v1.5.5 // indirect
github.com/pion/dtls/v2 v2.2.7 // indirect
github.com/pion/ice/v2 v2.3.11 // indirect
github.com/pion/interceptor v0.1.18 // indirect
github.com/pion/logging v0.2.2 // indirect
github.com/pion/mdns v0.0.8 // indirect
github.com/pion/randutil v0.1.0 // indirect
github.com/pion/rtcp v1.2.10 // indirect
github.com/pion/rtp v1.8.1 // indirect
github.com/pion/sctp v1.8.8 // indirect
github.com/pion/sdp/v3 v3.0.6 // indirect
github.com/pion/srtp/v2 v2.0.17 // indirect
github.com/pion/stun v0.6.1 // indirect
github.com/pion/transport/v2 v2.2.3 // indirect
github.com/pion/turn/v2 v2.1.3 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/stretchr/testify v1.8.4 // indirect
golang.org/x/crypto v0.12.0 // indirect
golang.org/x/net v0.14.0 // indirect
golang.org/x/sys v0.11.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
+259
View File
@@ -0,0 +1,259 @@
connectrpc.com/connect v1.11.1 h1:dqRwblixqkVh+OFBOOL1yIf1jS/yP0MSJLijRj29bFg=
connectrpc.com/connect v1.11.1/go.mod h1:3AGaO6RRGMx5IKFfqbe3hvK1NqLosFNP2BxDYTPmNPo=
connectrpc.com/grpcreflect v1.2.0 h1:Q6og1S7HinmtbEuBvARLNwYmTbhEGRpHDhqrPNlmK+U=
connectrpc.com/grpcreflect v1.2.0/go.mod h1:nwSOKmE8nU5u/CidgHtPYk1PFI3U9ignz7iDMxOYkSY=
github.com/at-wat/ebml-go v0.16.0/go.mod h1:w1cJs7zmGsb5nnSvhWGKLCxvfu4FVx5ERvYDIalj1ww=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
github.com/gofrs/uuid/v5 v5.0.0 h1:p544++a97kEL+svbcFbCQVM9KFu0Yo25UoISXGNNH9M=
github.com/gofrs/uuid/v5 v5.0.0/go.mod h1:CDOjlDMVAtN56jqyRUZh58JT31Tiw7/oQyEXZV+9bD8=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4=
github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/hybridgroup/mjpeg v0.0.0-20140228234708-4680f319790e/go.mod h1:eagM805MRKrioHYuU7iKLUyFPVKqVV6um5DAvCkUtXs=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/notedit/janus-go v0.0.0-20210115013133-fdce1b146d0e/go.mod h1:BN/Txse3qz8tZOmCm2OfajB2wHVujWmX3o9nVdsI6gE=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/ginkgo v1.16.1/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E=
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.11.0/go.mod h1:azGKhqFUon9Vuj0YmTfLSmx0FUwqXYSTl5re8lQLTUg=
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pion/datachannel v1.4.21/go.mod h1:oiNyP4gHx2DIwRzX/MFyH0Rz/Gz05OgBlayAI2hAWjg=
github.com/pion/datachannel v1.5.5 h1:10ef4kwdjije+M9d7Xm9im2Y3O6A6ccQb0zcqZcJew8=
github.com/pion/datachannel v1.5.5/go.mod h1:iMz+lECmfdCMqFRhXhcA/219B0SQlbpoR2V118yimL0=
github.com/pion/dtls/v2 v2.0.9/go.mod h1:O0Wr7si/Zj5/EBFlDzDd6UtVxx25CE1r7XM7BQKYQho=
github.com/pion/dtls/v2 v2.2.7 h1:cSUBsETxepsCSFSxC3mc/aDo14qQLMSL+O6IjG28yV8=
github.com/pion/dtls/v2 v2.2.7/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s=
github.com/pion/example-webrtc-applications/v3 v3.0.5 h1:Bycp74ODTRa+zKa6dpy3uHOW/kwg2XEBmGjFTWfVPpA=
github.com/pion/example-webrtc-applications/v3 v3.0.5/go.mod h1:jQDdp7mkpHvTtw8GC77xPdVYUuiALSJVdFG3FYYBs4A=
github.com/pion/ice/v2 v2.1.10/go.mod h1:kV4EODVD5ux2z8XncbLHIOtcXKtYXVgLVCeVqnpoeP0=
github.com/pion/ice/v2 v2.1.12/go.mod h1:ovgYHUmwYLlRvcCLI67PnQ5YGe+upXZbGgllBDG/ktU=
github.com/pion/ice/v2 v2.3.11 h1:rZjVmUwyT55cmN8ySMpL7rsS8KYsJERsrxJLLxpKhdw=
github.com/pion/ice/v2 v2.3.11/go.mod h1:hPcLC3kxMa+JGRzMHqQzjoSj3xtE9F+eoncmXLlCL4E=
github.com/pion/interceptor v0.0.15/go.mod h1:pg3J253eGi5bqyKzA74+ej5Y19ez2jkWANVnF+Z9Dfk=
github.com/pion/interceptor v0.1.18 h1:Hk26334NUQeUcJNR27YHYKT+sWNhhegQ9KFz5Nn6yMQ=
github.com/pion/interceptor v0.1.18/go.mod h1:tpvvF4cPM6NGxFA1DUMbhabzQBxdWMATDGEUYOR9x6I=
github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY=
github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms=
github.com/pion/mdns v0.0.5/go.mod h1:UgssrvdD3mxpi8tMxAXbsppL3vJ4Jipw1mTCW+al01g=
github.com/pion/mdns v0.0.8 h1:HhicWIg7OX5PVilyBO6plhMetInbzkVJAhbdJiAeVaI=
github.com/pion/mdns v0.0.8/go.mod h1:hYE72WX8WDveIhg7fmXgMKivD3Puklk0Ymzog0lSyaI=
github.com/pion/randutil v0.1.0 h1:CFG1UdESneORglEsnimhUjf33Rwjubwj6xfiOXBa3mA=
github.com/pion/randutil v0.1.0/go.mod h1:XcJrSMMbbMRhASFVOlj/5hQial/Y8oH/HVo7TBZq+j8=
github.com/pion/rtcp v1.2.6/go.mod h1:52rMNPWFsjr39z9B9MhnkqhPLoeHTv1aN63o/42bWE0=
github.com/pion/rtcp v1.2.10 h1:nkr3uj+8Sp97zyItdN60tE/S6vk4al5CPRR6Gejsdjc=
github.com/pion/rtcp v1.2.10/go.mod h1:ztfEwXZNLGyF1oQDttz/ZKIBaeeg/oWbRYqzBM9TL1I=
github.com/pion/rtp v1.7.0/go.mod h1:bDb5n+BFZxXx0Ea7E5qe+klMuqiBrP+w8XSjiWtCUko=
github.com/pion/rtp v1.7.1/go.mod h1:bDb5n+BFZxXx0Ea7E5qe+klMuqiBrP+w8XSjiWtCUko=
github.com/pion/rtp v1.8.1 h1:26OxTc6lKg/qLSGir5agLyj0QKaOv8OP5wps2SFnVNQ=
github.com/pion/rtp v1.8.1/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU=
github.com/pion/sctp v1.7.10/go.mod h1:EhpTUQu1/lcK3xI+eriS6/96fWetHGCvBi9MSsnaBN0=
github.com/pion/sctp v1.7.12/go.mod h1:xFe9cLMZ5Vj6eOzpyiKjT9SwGM4KpK/8Jbw5//jc+0s=
github.com/pion/sctp v1.8.5/go.mod h1:SUFFfDpViyKejTAdwD1d/HQsCu+V/40cCs2nZIvC3s0=
github.com/pion/sctp v1.8.8 h1:5EdnnKI4gpyR1a1TwbiS/wxEgcUWBHsc7ILAjARJB+U=
github.com/pion/sctp v1.8.8/go.mod h1:igF9nZBrjh5AtmKc7U30jXltsFHicFCXSmWA2GWRaWs=
github.com/pion/sdp/v2 v2.4.0/go.mod h1:L2LxrOpSTJbAns244vfPChbciR/ReU1KWfG04OpkR7E=
github.com/pion/sdp/v3 v3.0.4/go.mod h1:bNiSknmJE0HYBprTHXKPQ3+JjacTv5uap92ueJZKsRk=
github.com/pion/sdp/v3 v3.0.6 h1:WuDLhtuFUUVpTfus9ILC4HRyHsW6TdugjEX/QY9OiUw=
github.com/pion/sdp/v3 v3.0.6/go.mod h1:iiFWFpQO8Fy3S5ldclBkpXqmWy02ns78NOKoLLL0YQw=
github.com/pion/srtp/v2 v2.0.5/go.mod h1:8k6AJlal740mrZ6WYxc4Dg6qDqqhxoRG2GSjlUhDF0A=
github.com/pion/srtp/v2 v2.0.17 h1:ECuOk+7uIpY6HUlTb0nXhfvu4REG2hjtC4ronYFCZE4=
github.com/pion/srtp/v2 v2.0.17/go.mod h1:y5WSHcJY4YfNB/5r7ca5YjHeIr1H3LM1rKArGGs8jMc=
github.com/pion/stun v0.3.5/go.mod h1:gDMim+47EeEtfWogA37n6qXZS88L5V6LqFcf+DZA2UA=
github.com/pion/stun v0.6.1 h1:8lp6YejULeHBF8NmV8e2787BogQhduZugh5PdhDyyN4=
github.com/pion/stun v0.6.1/go.mod h1:/hO7APkX4hZKu/D0f2lHzNyvdkTGtIy3NDmLR7kSz/8=
github.com/pion/transport v0.10.1/go.mod h1:PBis1stIILMiis0PewDw91WJeLJkyIMcEk+DwKOzf4A=
github.com/pion/transport v0.12.2/go.mod h1:N3+vZQD9HlDP5GWkZ85LohxNsDcNgofQmyL6ojX5d8Q=
github.com/pion/transport v0.12.3/go.mod h1:OViWW9SP2peE/HbwBvARicmAVnesphkNkCVZIWJ6q9A=
github.com/pion/transport v0.14.1 h1:XSM6olwW+o8J4SCmOBb/BpwZypkHeyM0PGFCxNQBr40=
github.com/pion/transport v0.14.1/go.mod h1:4tGmbk00NeYA3rUa9+n+dzCCoKkcy3YlYb99Jn2fNnI=
github.com/pion/transport/v2 v2.2.1/go.mod h1:cXXWavvCnFF6McHTft3DWS9iic2Mftcz1Aq29pGcU5g=
github.com/pion/transport/v2 v2.2.2/go.mod h1:OJg3ojoBJopjEeECq2yJdXH9YVrUJ1uQ++NjXLOUorc=
github.com/pion/transport/v2 v2.2.3 h1:XcOE3/x41HOSKbl1BfyY1TF1dERx7lVvlMCbXU7kfvA=
github.com/pion/transport/v2 v2.2.3/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0=
github.com/pion/turn/v2 v2.0.5/go.mod h1:APg43CFyt/14Uy7heYUOGWdkem/Wu4PhCO/bjyrTqMw=
github.com/pion/turn/v2 v2.1.3 h1:pYxTVWG2gpC97opdRc5IGsQ1lJ9O/IlNhkzj7MMrGAA=
github.com/pion/turn/v2 v2.1.3/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY=
github.com/pion/udp v0.1.1/go.mod h1:6AFo+CMdKQm7UiA0eUPA8/eVCTx8jBIITLZHc9DWX5M=
github.com/pion/webrtc/v3 v3.1.0-beta.3/go.mod h1:I4O6v2pkiXdVmcn7sUhCNwHUAepGU19PVEyR204s1qc=
github.com/pion/webrtc/v3 v3.2.20 h1:BQJiXQsJq9LgLp3op7rLy1y8d2WD+LtiS9cpY0uQ22A=
github.com/pion/webrtc/v3 v3.2.20/go.mod h1:vVURQTBOG5BpWKOJz3nlr23NfTDeyKVmubRNqzQp+Tg=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
gocv.io/x/gocv v0.28.0/go.mod h1:oc6FvfYqfBp99p+yOEzs9tbYF9gOrAQSeL/dyIPefJU=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210812204632-0ba0e8f03122/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE=
golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I=
golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk=
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201201195509-5d6afe98e0b7/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210331212208-0fccb6fa2b5c/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ=
golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14=
golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo=
golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o=
golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc=
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 h1:bVf09lpb+OJbByTj913DRJioFFAjf/ZGxEz7MajTp2U=
google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM=
google.golang.org/grpc v1.58.1 h1:OL+Vz23DTtrrldqHK49FUOPHyY75rvFqJfXC84NYW58=
google.golang.org/grpc v1.58.1/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+235
View File
@@ -0,0 +1,235 @@
// Package signaler implements a signaler server.
package signaler
import (
"context"
"encoding/base64"
"fmt"
"net/http"
"sync"
"time"
"connectrpc.com/connect"
pb "github.com/chathaway-codes/home-sensors/v2/gen"
internalpb "github.com/chathaway-codes/home-sensors/v2/gen/token"
"github.com/gofrs/uuid/v5"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"google.golang.org/protobuf/proto"
)
type camera struct {
id string
}
type Server struct {
mu sync.Mutex
camerasByHome map[string]map[string]*camera
sessionsByCamera map[string]map[string]*pb.Session
sessionsById map[string]*pb.Session
waitersBySessionId map[string][]chan<- bool
}
func New() *Server {
return &Server{
camerasByHome: make(map[string]map[string]*camera),
sessionsByCamera: make(map[string]map[string]*pb.Session),
sessionsById: make(map[string]*pb.Session),
waitersBySessionId: make(map[string][]chan<- bool),
}
}
func (s *Server) CreateAuthToken(ctx context.Context, request *connect.Request[pb.CreateAuthTokenRequest]) (*connect.Response[pb.AuthToken], error) {
req := request.Msg
switch req.Type.(type) {
case *pb.CreateAuthTokenRequest_Camera_:
id := req.GetCamera().GetId()
s.mu.Lock()
thisCamera := &camera{
id: id,
}
home := req.GetHome()
if _, ok := s.camerasByHome[home]; !ok {
s.camerasByHome[home] = make(map[string]*camera)
}
s.camerasByHome[home][id] = thisCamera
s.mu.Unlock()
}
myUUID, err := uuid.NewV4()
if err != nil {
return nil, fmt.Errorf("error creating UUID: %v", err)
}
id := myUUID.String()
token := &internalpb.AuthToken{
Uid: id,
Home: req.GetHome(),
}
bytes, err := proto.Marshal(token)
if err != nil {
return nil, status.Errorf(codes.Internal, "failed to generate token: %v", err)
}
outToken := base64.URLEncoding.EncodeToString(bytes)
return connect.NewResponse(&pb.AuthToken{
Token: outToken,
}), nil
}
func (s *Server) ListCameras(ctx context.Context, request *connect.Request[pb.ListCamerasRequest]) (*connect.Response[pb.ListCamerasResponse], error) {
authToken, err := getAuthToken(request)
if err != nil {
return nil, err
}
s.mu.Lock()
defer s.mu.Unlock()
var cameras []*pb.Camera
for _, camera := range s.camerasByHome[authToken.Home] {
cameras = append(cameras, &pb.Camera{
Identifier: &pb.Camera_Identifier{
Id: camera.id,
},
})
}
return connect.NewResponse(&pb.ListCamerasResponse{Cameras: cameras}), nil
}
// CreateSession creates a new session that can be seen bv the provided Camera and Peer.
//
// Optionally, wait_for_update can be set to prevent returning until the Camera has seen the
// session request, populated candidates, and returned a session offer.
func (s *Server) CreateSession(ctx context.Context, request *connect.Request[pb.CreateSessionRequest]) (*connect.Response[pb.Session], error) {
req := request.Msg
if req.GetSession() == nil {
return nil, status.Errorf(codes.InvalidArgument, "nil session")
}
myUUID, err := uuid.NewV4()
if err != nil {
return nil, fmt.Errorf("error creating UUID: %v", err)
}
id := myUUID.String()
req.GetSession().Id = &pb.Session_Identifier{Id: id}
s.upsertSession(req.GetSession(), req.GetWaitForUpdate())
s.mu.Lock()
defer s.mu.Unlock()
// Spin off goroutine to eventually cleanup the session
go s.scheduleCleanup(id, time.Minute)
returnSession := s.sessionsById[id]
return connect.NewResponse(returnSession), nil
}
// UpdateSession updates the session
func (s *Server) UpdateSession(ctx context.Context, request *connect.Request[pb.UpdateSessionRequest]) (*connect.Response[pb.Session], error) {
req := request.Msg
id := req.GetSession().GetId().GetId()
s.mu.Lock()
if _, ok := s.sessionsById[id]; !ok {
s.mu.Unlock()
return nil, status.Errorf(codes.NotFound, "no such session %q", id)
}
s.mu.Unlock()
s.upsertSession(req.GetSession(), req.WaitForUpdate)
s.mu.Lock()
defer s.mu.Unlock()
returnSession := s.sessionsById[id]
return connect.NewResponse(returnSession), nil
}
// ListSessions lists all sessions the client should consider.
//
// TODO: it would be better if we could alert a camera to poll for sessions
// i.e., with websockets (or streaming RPCs).
func (s *Server) ListSessions(context.Context, *connect.Request[pb.ListSessionsRequest]) (*connect.Response[pb.ListSessionsResponse], error) {
var sessions []*pb.Session
for _, session := range s.sessionsById {
sessions = append(sessions, session)
}
return connect.NewResponse(&pb.ListSessionsResponse{Sessions: sessions}), nil
}
func (s *Server) CreateIceCandidate(context.Context, *connect.Request[pb.CreateIceCandidateRequest]) (*connect.Response[pb.IceCandidate], error) {
return nil, fmt.Errorf("")
}
func (s *Server) PopIceCandidate(context.Context, *connect.Request[pb.PopIceCandidateRequest]) (*connect.Response[pb.IceCandidate], error) {
return nil, fmt.Errorf("")
}
func (s *Server) CreateIceSessionDescription(context.Context, *connect.Request[pb.CreateIceSessionDescriptionRequest]) (*connect.Response[pb.IceSessionDescription], error) {
return nil, fmt.Errorf("")
}
func (s *Server) PopIceSessionDescription(context.Context, *connect.Request[pb.PopIceSessionDescriptionRequest]) (*connect.Response[pb.IceSessionDescription], error) {
return nil, fmt.Errorf("")
}
// upsertSession updates or creates a session, optionally blocking until the session is updated
// again in the future.
//
// WARN: this function locks and unlocks s.mu; make sure no locks are held or it will block forever.
func (s *Server) upsertSession(session *pb.Session, waitForUpdate bool) {
s.mu.Lock()
defer s.mu.Unlock()
id := session.Id.Id
s.sessionsById[id] = session
cameraID := session.GetCamera().GetId()
if _, ok := s.sessionsByCamera[cameraID]; !ok {
s.sessionsByCamera[cameraID] = make(map[string]*pb.Session)
}
s.sessionsByCamera[cameraID][id] = session
// Alert anything that needs to go
for _, waiter := range s.waitersBySessionId[id] {
waiter <- true
close(waiter)
}
s.waitersBySessionId[id] = nil
if waitForUpdate {
waitChan := make(chan bool)
s.waitersBySessionId[id] = append(s.waitersBySessionId[id], waitChan)
defer func() {
<-waitChan
}()
}
}
func (s *Server) scheduleCleanup(sessionID string, waitPeriod time.Duration) {
time.Sleep(waitPeriod)
s.mu.Lock()
defer s.mu.Unlock()
session := s.sessionsById[sessionID]
for _, water := range s.waitersBySessionId[sessionID] {
water <- true
close(water)
}
delete(s.sessionsByCamera[session.GetCamera().GetId()], sessionID)
delete(s.sessionsById, sessionID)
delete(s.waitersBySessionId, sessionID)
}
func getAuthToken[T any](req *connect.Request[T]) (*internalpb.AuthToken, error) {
authHeader := req.Header().Get(http.CanonicalHeaderKey("Authorization"))
bytes, err := base64.URLEncoding.DecodeString(authHeader)
if err != nil {
return nil, status.Errorf(codes.InvalidArgument, "malformed authorization header (extract)")
}
authToken := &internalpb.AuthToken{}
if err := proto.Unmarshal(bytes, authToken); err != nil {
return nil, status.Errorf(codes.InvalidArgument, "malformed authorization header (parse)")
}
return authToken, nil
}
+60 -1
View File
@@ -1,6 +1,9 @@
syntax = "proto3"; syntax = "proto3";
package signaler;
service SignalerService { service SignalerService {
rpc CreateAuthToken(CreateAuthTokenRequest) returns (AuthToken);
rpc ListCameras(ListCamerasRequest) returns (ListCamerasResponse); rpc ListCameras(ListCamerasRequest) returns (ListCamerasResponse);
// CreateSession creates a new session that can be seen bv the provided Camera and Peer. // CreateSession creates a new session that can be seen bv the provided Camera and Peer.
@@ -15,6 +18,34 @@ service SignalerService {
// TODO: it would be better if we could alert a camera to poll for sessions // TODO: it would be better if we could alert a camera to poll for sessions
// i.e., with websockets (or streaming RPCs). // i.e., with websockets (or streaming RPCs).
rpc ListSessions(ListSessionsRequest) returns (ListSessionsResponse); rpc ListSessions(ListSessionsRequest) returns (ListSessionsResponse);
// CreateIceCandidate adds the provided candidate to the list of candidates.
rpc CreateIceCandidate(CreateIceCandidateRequest) returns (IceCandidate);
// PopIceCandidate delete a candidate from the list of candidates and returns it.
//
// If there are no candidates, this blocks until one becomes available.
rpc PopIceCandidate(PopIceCandidateRequest) returns (IceCandidate);
rpc CreateIceSessionDescription(CreateIceSessionDescriptionRequest) returns (IceSessionDescription);
rpc PopIceSessionDescription(PopIceSessionDescriptionRequest) returns (IceSessionDescription);
}
message CreateAuthTokenRequest{
// Homes this auth token should be registered too.
string home = 1;
message Camera {
// Used to uniquely identifier this camera so clients can open
// sessions with it.
string id = 1;
}
message Client {}
oneof type {
Camera camera = 2;
Client client = 3;
}
} }
message ListCamerasRequest {} message ListCamerasRequest {}
@@ -41,6 +72,30 @@ message UpdateSessionRequest {
bool wait_for_update = 2; bool wait_for_update = 2;
} }
message ListSessionsRequest {}
message ListSessionsResponse {
repeated Session sessions = 1;
}
message CreateIceCandidateRequest {
Session.Identifier session_identifier = 1;
IceCandidate candidate = 2;
}
message PopIceCandidateRequest {
Session.Identifier session_identifier = 1;
}
message CreateIceSessionDescriptionRequest {
Session.Identifier session_identifier = 1;
IceSessionDescription description = 2;
}
message PopIceSessionDescriptionRequest {
Session.Identifier session_identifier = 1;
}
message Camera { message Camera {
message Identifier { message Identifier {
string id = 1; string id = 1;
@@ -58,7 +113,7 @@ message IceCandidate {
message IceSessionDescription { message IceSessionDescription {
// Copied from https://pkg.go.dev/github.com/pion/webrtc/v4#SessionDescription // Copied from https://pkg.go.dev/github.com/pion/webrtc/v4#SessionDescription
int sdp_type = 1; int64 sdp_type = 1;
string sdp = 2; string sdp = 2;
} }
@@ -73,4 +128,8 @@ message Session {
IceSessionDescription camera_offer = 5; IceSessionDescription camera_offer = 5;
IceSessionDescription client_answer = 6; IceSessionDescription client_answer = 6;
}
message AuthToken {
string token = 1;
} }
+7
View File
@@ -0,0 +1,7 @@
syntax = "proto3";
package token;
message AuthToken {
string uid = 1;
string home = 2;
}