Add websocket pb stuff

This commit is contained in:
Daniel 2024-08-04 00:55:28 -04:00
parent 0204cab4d5
commit 9394046f31
15 changed files with 1082 additions and 58 deletions

1
.gitignore vendored
View file

@ -1,4 +1,5 @@
config.yaml config.yaml
mydb.sql mydb.sql
/gordio /gordio
/calls
Session.vim Session.vim

View file

@ -1,5 +1,6 @@
all: all:
go build -o gordio ./cmd/gordio/ go build -o gordio ./cmd/gordio/
go build -o calls ./cmd/calls/
generate: generate:
sqlc generate -f sql/sqlc.yaml sqlc generate -f sql/sqlc.yaml

140
cmd/calls/main.go Normal file
View file

@ -0,0 +1,140 @@
package main
import (
"encoding/json"
"flag"
"log"
"net/http"
"net/http/cookiejar"
"net/url"
"os"
"os/signal"
"strings"
"time"
"dynatron.me/x/stillbox/pkg/pb"
"github.com/gorilla/websocket"
"google.golang.org/protobuf/proto"
)
var (
addr = flag.String("addr", "localhost:8080", "http service address")
username = flag.String("user", "", "username")
password = flag.String("password", "", "password")
)
func main() {
flag.Parse()
log.SetFlags(0)
interrupt := make(chan os.Signal, 1)
signal.Notify(interrupt, os.Interrupt)
loginForm := url.Values{}
loginForm.Add("username", *username)
loginForm.Add("password", *password)
loginReq, err := http.NewRequest("POST", "http://"+*addr+"/login", strings.NewReader(loginForm.Encode()))
if err != nil {
log.Fatal(err)
}
loginReq.Header.Add("Content-Type", "application/x-www-form-urlencoded")
jar, err := cookiejar.New(nil)
if err != nil {
log.Fatal(err)
}
client := &http.Client{
Jar: jar,
}
resp, err := client.Do(loginReq)
if err != nil {
log.Fatal(err)
}
jwt := struct {
JWT string `json:"jwt"`
}{}
err = json.NewDecoder(resp.Body).Decode(&jwt)
if err != nil {
log.Fatal(err)
}
u := url.URL{Scheme: "ws", Host: *addr, Path: "/ws"}
log.Printf("connecting to %s", u.String())
dialer := websocket.Dialer{
Proxy: http.ProxyFromEnvironment,
HandshakeTimeout: 45 * time.Second,
Jar: jar,
}
c, _, err := dialer.Dial(u.String(), nil)
if err != nil {
log.Fatal("dial:", err)
}
defer c.Close()
done := make(chan struct{})
go func() {
defer close(done)
for {
t, message, err := c.ReadMessage()
if err != nil {
log.Println("read:", err)
return
}
if t == websocket.BinaryMessage {
var m pb.Message
err := proto.Unmarshal(message, &m)
if err != nil {
log.Fatal(err)
}
switch v := m.ToClientMessage.(type) {
case *pb.Message_Call:
case *pb.Message_Notification:
log.Println(v.Notification.Msg)
}
}
}
}()
ticker := time.NewTicker(time.Second)
defer ticker.Stop()
for {
select {
case <-done:
return
case t := <-ticker.C:
err := c.WriteMessage(websocket.TextMessage, []byte(t.String()))
if err != nil {
log.Println("write:", err)
return
}
case <-interrupt:
log.Println("interrupt")
// Cleanly close the connection by sending a close message and then
// waiting (with timeout) for the server to close the connection.
err := c.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""))
if err != nil {
log.Println("write close:", err)
return
}
select {
case <-done:
case <-time.After(time.Second):
}
return
}
}
}

2
go.mod
View file

@ -10,11 +10,13 @@ require (
github.com/go-chi/render v1.0.3 github.com/go-chi/render v1.0.3
github.com/golang-migrate/migrate/v4 v4.17.1 github.com/golang-migrate/migrate/v4 v4.17.1
github.com/google/uuid v1.4.0 github.com/google/uuid v1.4.0
github.com/gorilla/websocket v1.5.3
github.com/jackc/pgx/v5 v5.6.0 github.com/jackc/pgx/v5 v5.6.0
github.com/rs/zerolog v1.33.0 github.com/rs/zerolog v1.33.0
github.com/spf13/cobra v1.8.1 github.com/spf13/cobra v1.8.1
golang.org/x/crypto v0.21.0 golang.org/x/crypto v0.21.0
golang.org/x/term v0.18.0 golang.org/x/term v0.18.0
google.golang.org/protobuf v1.33.0
gopkg.in/yaml.v3 v3.0.1 gopkg.in/yaml.v3 v3.0.1
) )

8
go.sum
View file

@ -41,8 +41,12 @@ github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang-migrate/migrate/v4 v4.17.1 h1:4zQ6iqL6t6AiItphxJctQb3cFqWiSpMnX7wLTPnnYO4= github.com/golang-migrate/migrate/v4 v4.17.1 h1:4zQ6iqL6t6AiItphxJctQb3cFqWiSpMnX7wLTPnnYO4=
github.com/golang-migrate/migrate/v4 v4.17.1/go.mod h1:m8hinFyWBn0SA4QKHuKh175Pm9wjmxj3S2Mia7dbXzM= github.com/golang-migrate/migrate/v4 v4.17.1/go.mod h1:m8hinFyWBn0SA4QKHuKh175Pm9wjmxj3S2Mia7dbXzM=
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4=
github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
@ -135,6 +139,10 @@ golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/tools v0.10.0 h1:tvDr/iQoUqNdohiYm0LmmKcBk+q86lb9EprIUFhHHGg= golang.org/x/tools v0.10.0 h1:tvDr/iQoUqNdohiYm0LmmKcBk+q86lb9EprIUFhHHGg=
golang.org/x/tools v0.10.0/go.mod h1:UJwyiVBsOA2uwvK/e5OY3GTpDUJriEd+/YlqAwLPmyM= golang.org/x/tools v0.10.0/go.mod h1:UJwyiVBsOA2uwvK/e5OY3GTpDUJriEd+/YlqAwLPmyM=
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk=
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=

View file

@ -2,6 +2,7 @@ package auth
import ( import (
"context" "context"
"fmt"
"net/http" "net/http"
"time" "time"
@ -90,7 +91,7 @@ func (a *authenticator) newToken(uid int32) string {
} }
func (a *authenticator) PublicRoutes(r chi.Router) { func (a *authenticator) PublicRoutes(r chi.Router) {
r.Post("/auth", a.routeAuth) r.Post("/login", a.routeAuth)
} }
func (a *authenticator) routeAuth(w http.ResponseWriter, r *http.Request) { func (a *authenticator) routeAuth(w http.ResponseWriter, r *http.Request) {
@ -101,7 +102,7 @@ func (a *authenticator) routeAuth(w http.ResponseWriter, r *http.Request) {
} }
username, password := r.PostFormValue("username"), r.PostFormValue("password") username, password := r.PostFormValue("username"), r.PostFormValue("password")
if username == "" || password == "" { if username == "" || password == "" {
http.Error(w, "blank credentials", http.StatusBadRequest) http.Error(w, "blank credentials"+fmt.Sprint(r.Form), http.StatusBadRequest)
return return
} }

View file

@ -0,0 +1,63 @@
package nexus
import (
"io"
"sync"
"dynatron.me/x/stillbox/pkg/pb"
"github.com/rs/zerolog/log"
"google.golang.org/protobuf/proto"
)
type Client interface {
sync.Locker
Connection
Conn() Connection
HandleCommand(*pb.Command)
HandleMessage([]byte)
}
type client struct {
sync.RWMutex
Connection
nexus *Nexus
}
type Connection interface {
io.Closer
Send(*pb.Message)
}
func (n *Nexus) NewClient(conn Connection) Client {
sess := &client{
Connection: conn,
nexus: n,
}
return sess
}
func (c *client) Registry() Registry {
return c.nexus
}
func (c *client) Conn() Connection {
return c.Connection
}
func (c *client) HandleMessage(mesgBytes []byte) {
var msg pb.Command
err := proto.Unmarshal(mesgBytes, &msg)
if err != nil {
log.Error().Err(err).Msg("command unmarshal")
return
}
c.HandleCommand(&msg)
}

View file

@ -0,0 +1,25 @@
package nexus
import (
"dynatron.me/x/stillbox/pkg/pb"
"github.com/rs/zerolog/log"
)
func (c *client) HandleCommand(cmd *pb.Command) {
switch cc := cmd.Command.(type) {
case *pb.Command_LiveCommand:
c.Live(cc.LiveCommand)
case *pb.Command_SearchCommand:
default:
log.Error().Msgf("unknown command %T", cmd)
}
}
func (c *client) Live(cmd *pb.Live) {
switch cmd.State {
case pb.LiveState_LS_STOPPED:
case pb.LiveState_LS_LIVE:
case pb.LiveState_LS_PAUSED:
}
}

43
pkg/gordio/nexus/nexus.go Normal file
View file

@ -0,0 +1,43 @@
package nexus
import (
"sync"
)
type Nexus struct {
sync.RWMutex
clients map[*client]struct{}
*wsManager
}
type Registry interface {
NewClient(Connection) Client
Register(Client)
Unregister(Client)
}
func New() *Nexus {
n := &Nexus{
clients: make(map[*client]struct{}),
}
n.wsManager = newWsManager(n)
return n
}
func (n *Nexus) Register(c Client) {
n.Lock()
defer n.Unlock()
n.clients[c.(*client)] = struct{}{}
}
func (n *Nexus) Unregister(c Client) {
n.Lock()
defer n.Unlock()
delete(n.clients, c.(*client))
}

View file

@ -0,0 +1,158 @@
package nexus
import (
"io"
"net/http"
"time"
"dynatron.me/x/stillbox/pkg/pb"
"github.com/go-chi/chi/v5"
"github.com/gorilla/websocket"
"github.com/rs/zerolog/log"
"google.golang.org/protobuf/proto"
)
const (
maxMessageSize = 1024 * 1024 * 10 // 10MB
pongWait = 60 * time.Second
pingInterval = (pongWait * 9) / 10
writeWait = 10 * time.Second
qSize = 256 // 256 messages
)
type wsManager struct {
Registry
}
func newWsManager(r Registry) *wsManager {
return &wsManager{
Registry: r,
}
}
type wsConn struct {
*websocket.Conn
out chan *pb.Message
}
func (w *wsConn) Send(msg *pb.Message) {
w.out <- msg
}
func newWsConn(c *websocket.Conn) *wsConn {
return &wsConn{
Conn: c,
out: make(chan *pb.Message, qSize),
}
}
var upgrader = websocket.Upgrader{
ReadBufferSize: 1024,
WriteBufferSize: 1024,
}
func (wm *wsManager) serveWS(w http.ResponseWriter, r *http.Request) {
conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
log.Error().Err(err).Msg("upgrade failed")
http.Error(w, "upgrade failed", http.StatusInternalServerError)
return
}
cli := wm.NewClient(newWsConn(conn))
wm.Register(cli)
wsc := newWsConn(conn)
go wsc.readPump(wm, cli)
go wsc.writePump()
}
func (conn *wsConn) readPump(reg Registry, c Client) {
defer func() {
reg.Unregister(c)
conn.Close()
}()
conn.SetReadLimit(maxMessageSize)
conn.SetReadDeadline(time.Now().Add(pongWait))
conn.SetPongHandler(func(string) error {
conn.SetReadDeadline(time.Now().Add(pongWait))
return nil
})
for {
_, message, err := conn.ReadMessage()
if err != nil {
if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway, websocket.CloseAbnormalClosure) {
log.Error().Err(err).Msg("read failed")
}
break
}
go c.HandleMessage(message)
}
}
func (conn *wsConn) writePump() {
pingTicker := time.NewTicker(pingInterval)
defer func() {
pingTicker.Stop()
conn.Close()
}()
for {
select {
case msg, ok := <-conn.out:
conn.SetWriteDeadline(time.Now().Add(writeWait))
if !ok {
// nexus closed
conn.WriteMessage(websocket.CloseMessage, []byte{})
return
}
w, err := conn.NextWriter(websocket.BinaryMessage)
if err != nil {
return
}
conn.writeMessage(w, msg)
if err := w.Close(); err != nil {
return
}
case <-pingTicker.C:
conn.SetWriteDeadline(time.Now().Add(writeWait))
if err := conn.WriteMessage(websocket.PingMessage, nil); err != nil {
return
}
}
}
}
func (conn *wsConn) writeMessage(w io.WriteCloser, msg *pb.Message) {
packWrite := func(msg *pb.Message) {
packed, err := proto.Marshal(msg)
if err != nil {
log.Error().Err(err).Msg("pack message")
return
}
w.Write(packed)
}
packWrite(msg)
// add queued messages to current payload
nQ := len(conn.out)
for i := 0; i < nQ; i++ {
packWrite(<-conn.out)
}
}
func (n *wsManager) InstallPrivateRoutes(r chi.Router) {
r.HandleFunc("/ws", n.serveWS)
}

View file

@ -18,6 +18,7 @@ func (s *Server) setupRoutes() {
r.Group(func(r chi.Router) { r.Group(func(r chi.Router) {
// authenticated routes // authenticated routes
r.Use(s.auth.AuthMiddleware(), s.auth.VerifyMiddleware()) r.Use(s.auth.AuthMiddleware(), s.auth.VerifyMiddleware())
s.nex.InstallPrivateRoutes(r)
}) })
r.Group(func(r chi.Router) { r.Group(func(r chi.Router) {

View file

@ -6,6 +6,7 @@ import (
"dynatron.me/x/stillbox/pkg/gordio/auth" "dynatron.me/x/stillbox/pkg/gordio/auth"
"dynatron.me/x/stillbox/pkg/gordio/config" "dynatron.me/x/stillbox/pkg/gordio/config"
"dynatron.me/x/stillbox/pkg/gordio/database" "dynatron.me/x/stillbox/pkg/gordio/database"
"dynatron.me/x/stillbox/pkg/gordio/nexus"
"dynatron.me/x/stillbox/pkg/gordio/sinks" "dynatron.me/x/stillbox/pkg/gordio/sinks"
"dynatron.me/x/stillbox/pkg/gordio/sources" "dynatron.me/x/stillbox/pkg/gordio/sources"
"github.com/go-chi/chi/middleware" "github.com/go-chi/chi/middleware"
@ -19,6 +20,7 @@ type Server struct {
r *chi.Mux r *chi.Mux
sources sources.Sources sources sources.Sources
sinks sinks.Sinks sinks sinks.Sinks
nex *nexus.Nexus
} }
func New(cfg *config.Config) (*Server, error) { func New(cfg *config.Config) (*Server, error) {
@ -34,6 +36,7 @@ func New(cfg *config.Config) (*Server, error) {
conf: cfg, conf: cfg,
db: db, db: db,
r: r, r: r,
nex: nexus.New(),
} }
srv.sinks.Register("database", sinks.NewDatabaseSink(db)) srv.sinks.Register("database", sinks.NewDatabaseSink(db))

View file

@ -1,13 +0,0 @@
package ws
import (
"github.com/go-chi/chi/v5"
// "github.com/gorilla/websocket"
)
type SessionManager struct {
}
func (s *SessionManager) InstallPrivateRoutes(r chi.Router) {
}

View file

@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// versions: // versions:
// protoc-gen-go v1.34.2 // protoc-gen-go v1.34.2
// protoc v5.27.2 // protoc v5.27.1
// source: stillbox.proto // source: stillbox.proto
package pb package pb
@ -21,14 +21,158 @@ const (
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
) )
type LiveState int32
const (
LiveState_LS_STOPPED LiveState = 0
LiveState_LS_LIVE LiveState = 1
LiveState_LS_PAUSED LiveState = 2
)
// Enum value maps for LiveState.
var (
LiveState_name = map[int32]string{
0: "LS_STOPPED",
1: "LS_LIVE",
2: "LS_PAUSED",
}
LiveState_value = map[string]int32{
"LS_STOPPED": 0,
"LS_LIVE": 1,
"LS_PAUSED": 2,
}
)
func (x LiveState) Enum() *LiveState {
p := new(LiveState)
*p = x
return p
}
func (x LiveState) String() string {
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
}
func (LiveState) Descriptor() protoreflect.EnumDescriptor {
return file_stillbox_proto_enumTypes[0].Descriptor()
}
func (LiveState) Type() protoreflect.EnumType {
return &file_stillbox_proto_enumTypes[0]
}
func (x LiveState) Number() protoreflect.EnumNumber {
return protoreflect.EnumNumber(x)
}
// Deprecated: Use LiveState.Descriptor instead.
func (LiveState) EnumDescriptor() ([]byte, []int) {
return file_stillbox_proto_rawDescGZIP(), []int{0}
}
type Message struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// Types that are assignable to ToClientMessage:
//
// *Message_Call
// *Message_Notification
// *Message_Popup
ToClientMessage isMessage_ToClientMessage `protobuf_oneof:"toClient_message"`
}
func (x *Message) Reset() {
*x = Message{}
if protoimpl.UnsafeEnabled {
mi := &file_stillbox_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Message) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Message) ProtoMessage() {}
func (x *Message) ProtoReflect() protoreflect.Message {
mi := &file_stillbox_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 Message.ProtoReflect.Descriptor instead.
func (*Message) Descriptor() ([]byte, []int) {
return file_stillbox_proto_rawDescGZIP(), []int{0}
}
func (m *Message) GetToClientMessage() isMessage_ToClientMessage {
if m != nil {
return m.ToClientMessage
}
return nil
}
func (x *Message) GetCall() *Call {
if x, ok := x.GetToClientMessage().(*Message_Call); ok {
return x.Call
}
return nil
}
func (x *Message) GetNotification() *Notification {
if x, ok := x.GetToClientMessage().(*Message_Notification); ok {
return x.Notification
}
return nil
}
func (x *Message) GetPopup() *UserPopup {
if x, ok := x.GetToClientMessage().(*Message_Popup); ok {
return x.Popup
}
return nil
}
type isMessage_ToClientMessage interface {
isMessage_ToClientMessage()
}
type Message_Call struct {
Call *Call `protobuf:"bytes,1,opt,name=call,proto3,oneof"`
}
type Message_Notification struct {
Notification *Notification `protobuf:"bytes,2,opt,name=notification,proto3,oneof"`
}
type Message_Popup struct {
Popup *UserPopup `protobuf:"bytes,3,opt,name=popup,proto3,oneof"`
}
func (*Message_Call) isMessage_ToClientMessage() {}
func (*Message_Notification) isMessage_ToClientMessage() {}
func (*Message_Popup) isMessage_ToClientMessage() {}
type Call struct { type Call struct {
state protoimpl.MessageState state protoimpl.MessageState
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields unknownFields protoimpl.UnknownFields
AudioName string `protobuf:"bytes,1,opt,name=audio_name,json=audioName,proto3" json:"audio_name,omitempty"` AudioName string `protobuf:"bytes,1,opt,name=audioName,proto3" json:"audioName,omitempty"`
AudioType string `protobuf:"bytes,2,opt,name=audio_type,json=audioType,proto3" json:"audio_type,omitempty"` AudioType string `protobuf:"bytes,2,opt,name=audioType,proto3" json:"audioType,omitempty"`
DateTime *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=date_time,json=dateTime,proto3" json:"date_time,omitempty"` DateTime *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=dateTime,proto3" json:"dateTime,omitempty"`
System int32 `protobuf:"varint,4,opt,name=system,proto3" json:"system,omitempty"` System int32 `protobuf:"varint,4,opt,name=system,proto3" json:"system,omitempty"`
Talkgroup int32 `protobuf:"varint,5,opt,name=talkgroup,proto3" json:"talkgroup,omitempty"` Talkgroup int32 `protobuf:"varint,5,opt,name=talkgroup,proto3" json:"talkgroup,omitempty"`
Source int32 `protobuf:"varint,6,opt,name=source,proto3" json:"source,omitempty"` Source int32 `protobuf:"varint,6,opt,name=source,proto3" json:"source,omitempty"`
@ -42,7 +186,7 @@ type Call struct {
func (x *Call) Reset() { func (x *Call) Reset() {
*x = Call{} *x = Call{}
if protoimpl.UnsafeEnabled { if protoimpl.UnsafeEnabled {
mi := &file_stillbox_proto_msgTypes[0] mi := &file_stillbox_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@ -55,7 +199,7 @@ func (x *Call) String() string {
func (*Call) ProtoMessage() {} func (*Call) ProtoMessage() {}
func (x *Call) ProtoReflect() protoreflect.Message { func (x *Call) ProtoReflect() protoreflect.Message {
mi := &file_stillbox_proto_msgTypes[0] mi := &file_stillbox_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@ -68,7 +212,7 @@ func (x *Call) ProtoReflect() protoreflect.Message {
// Deprecated: Use Call.ProtoReflect.Descriptor instead. // Deprecated: Use Call.ProtoReflect.Descriptor instead.
func (*Call) Descriptor() ([]byte, []int) { func (*Call) Descriptor() ([]byte, []int) {
return file_stillbox_proto_rawDescGZIP(), []int{0} return file_stillbox_proto_rawDescGZIP(), []int{1}
} }
func (x *Call) GetAudioName() string { func (x *Call) GetAudioName() string {
@ -148,35 +292,347 @@ func (x *Call) GetAudio() []byte {
return nil return nil
} }
type UserPopup struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Msg string `protobuf:"bytes,1,opt,name=msg,proto3" json:"msg,omitempty"`
}
func (x *UserPopup) Reset() {
*x = UserPopup{}
if protoimpl.UnsafeEnabled {
mi := &file_stillbox_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *UserPopup) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*UserPopup) ProtoMessage() {}
func (x *UserPopup) ProtoReflect() protoreflect.Message {
mi := &file_stillbox_proto_msgTypes[2]
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 UserPopup.ProtoReflect.Descriptor instead.
func (*UserPopup) Descriptor() ([]byte, []int) {
return file_stillbox_proto_rawDescGZIP(), []int{2}
}
func (x *UserPopup) GetMsg() string {
if x != nil {
return x.Msg
}
return ""
}
type Notification struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
DateTime *timestamppb.Timestamp `protobuf:"bytes,1,opt,name=dateTime,proto3" json:"dateTime,omitempty"`
Msg string `protobuf:"bytes,2,opt,name=msg,proto3" json:"msg,omitempty"`
ActionUrl string `protobuf:"bytes,3,opt,name=actionUrl,proto3" json:"actionUrl,omitempty"`
}
func (x *Notification) Reset() {
*x = Notification{}
if protoimpl.UnsafeEnabled {
mi := &file_stillbox_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Notification) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Notification) ProtoMessage() {}
func (x *Notification) ProtoReflect() protoreflect.Message {
mi := &file_stillbox_proto_msgTypes[3]
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 Notification.ProtoReflect.Descriptor instead.
func (*Notification) Descriptor() ([]byte, []int) {
return file_stillbox_proto_rawDescGZIP(), []int{3}
}
func (x *Notification) GetDateTime() *timestamppb.Timestamp {
if x != nil {
return x.DateTime
}
return nil
}
func (x *Notification) GetMsg() string {
if x != nil {
return x.Msg
}
return ""
}
func (x *Notification) GetActionUrl() string {
if x != nil {
return x.ActionUrl
}
return ""
}
type Command struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// Types that are assignable to Command:
//
// *Command_LiveCommand
// *Command_SearchCommand
Command isCommand_Command `protobuf_oneof:"command"`
}
func (x *Command) Reset() {
*x = Command{}
if protoimpl.UnsafeEnabled {
mi := &file_stillbox_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Command) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Command) ProtoMessage() {}
func (x *Command) ProtoReflect() protoreflect.Message {
mi := &file_stillbox_proto_msgTypes[4]
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 Command.ProtoReflect.Descriptor instead.
func (*Command) Descriptor() ([]byte, []int) {
return file_stillbox_proto_rawDescGZIP(), []int{4}
}
func (m *Command) GetCommand() isCommand_Command {
if m != nil {
return m.Command
}
return nil
}
func (x *Command) GetLiveCommand() *Live {
if x, ok := x.GetCommand().(*Command_LiveCommand); ok {
return x.LiveCommand
}
return nil
}
func (x *Command) GetSearchCommand() *Search {
if x, ok := x.GetCommand().(*Command_SearchCommand); ok {
return x.SearchCommand
}
return nil
}
type isCommand_Command interface {
isCommand_Command()
}
type Command_LiveCommand struct {
LiveCommand *Live `protobuf:"bytes,1,opt,name=liveCommand,proto3,oneof"`
}
type Command_SearchCommand struct {
SearchCommand *Search `protobuf:"bytes,2,opt,name=searchCommand,proto3,oneof"`
}
func (*Command_LiveCommand) isCommand_Command() {}
func (*Command_SearchCommand) isCommand_Command() {}
type Live struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
State LiveState `protobuf:"varint,1,opt,name=state,proto3,enum=stillbox.LiveState" json:"state,omitempty"`
}
func (x *Live) Reset() {
*x = Live{}
if protoimpl.UnsafeEnabled {
mi := &file_stillbox_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Live) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Live) ProtoMessage() {}
func (x *Live) ProtoReflect() protoreflect.Message {
mi := &file_stillbox_proto_msgTypes[5]
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 Live.ProtoReflect.Descriptor instead.
func (*Live) Descriptor() ([]byte, []int) {
return file_stillbox_proto_rawDescGZIP(), []int{5}
}
func (x *Live) GetState() LiveState {
if x != nil {
return x.State
}
return LiveState_LS_STOPPED
}
type Search struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
}
func (x *Search) Reset() {
*x = Search{}
if protoimpl.UnsafeEnabled {
mi := &file_stillbox_proto_msgTypes[6]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Search) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Search) ProtoMessage() {}
func (x *Search) ProtoReflect() protoreflect.Message {
mi := &file_stillbox_proto_msgTypes[6]
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 Search.ProtoReflect.Descriptor instead.
func (*Search) Descriptor() ([]byte, []int) {
return file_stillbox_proto_rawDescGZIP(), []int{6}
}
var File_stillbox_proto protoreflect.FileDescriptor var File_stillbox_proto protoreflect.FileDescriptor
var file_stillbox_proto_rawDesc = []byte{ var file_stillbox_proto_rawDesc = []byte{
0x0a, 0x0e, 0x73, 0x74, 0x69, 0x6c, 0x6c, 0x62, 0x6f, 0x78, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x0a, 0x0e, 0x73, 0x74, 0x69, 0x6c, 0x6c, 0x62, 0x6f, 0x78, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x12, 0x08, 0x73, 0x74, 0x69, 0x6c, 0x6c, 0x62, 0x6f, 0x78, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x12, 0x08, 0x73, 0x74, 0x69, 0x6c, 0x6c, 0x62, 0x6f, 0x78, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67,
0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65,
0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xd5, 0x02, 0x0a, 0x04, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xae, 0x01, 0x0a, 0x07,
0x43, 0x61, 0x6c, 0x6c, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x5f, 0x6e, 0x61, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x24, 0x0a, 0x04, 0x63, 0x61, 0x6c, 0x6c, 0x18,
0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x73, 0x74, 0x69, 0x6c, 0x6c, 0x62, 0x6f, 0x78,
0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x48, 0x00, 0x52, 0x04, 0x63, 0x61, 0x6c, 0x6c, 0x12, 0x3c, 0x0a,
0x0c, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20,
0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x73, 0x74, 0x69, 0x6c, 0x6c, 0x62, 0x6f, 0x78, 0x2e, 0x4e,
0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x0c, 0x6e,
0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2b, 0x0a, 0x05, 0x70,
0x6f, 0x70, 0x75, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x73, 0x74, 0x69,
0x6c, 0x6c, 0x62, 0x6f, 0x78, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x50, 0x6f, 0x70, 0x75, 0x70, 0x48,
0x00, 0x52, 0x05, 0x70, 0x6f, 0x70, 0x75, 0x70, 0x42, 0x12, 0x0a, 0x10, 0x74, 0x6f, 0x43, 0x6c,
0x69, 0x65, 0x6e, 0x74, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0xd2, 0x02, 0x0a,
0x04, 0x43, 0x61, 0x6c, 0x6c, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x4e, 0x61,
0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x4e, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x4e,
0x61, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x5f, 0x74, 0x79, 0x70, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x54, 0x79, 0x70, 0x65,
0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x54, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x54, 0x79, 0x70,
0x70, 0x65, 0x12, 0x37, 0x0a, 0x09, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x65, 0x12, 0x36, 0x0a, 0x08, 0x64, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20,
0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f,
0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52,
0x70, 0x52, 0x08, 0x64, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x08, 0x64, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x79, 0x73,
0x79, 0x73, 0x74, 0x65, 0x6d, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x73, 0x79, 0x73, 0x74, 0x65,
0x74, 0x65, 0x6d, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x61, 0x6c, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x6d, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x61, 0x6c, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x05,
0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x74, 0x61, 0x6c, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x74, 0x61, 0x6c, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x12,
0x70, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x16, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52,
0x05, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x66, 0x72, 0x65, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x66, 0x72, 0x65, 0x71, 0x75,
0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x66, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x66, 0x72, 0x65, 0x71,
0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x20, 0x0a, 0x0b, 0x66, 0x72, 0x65, 0x71, 0x75, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x20, 0x0a, 0x0b, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e,
0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x03, 0x52, 0x0b, 0x66, 0x72, 0x63, 0x69, 0x65, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x03, 0x52, 0x0b, 0x66, 0x72, 0x65, 0x71,
0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x74, 0x75, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x74, 0x63, 0x68,
0x63, 0x68, 0x65, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x05, 0x52, 0x07, 0x70, 0x61, 0x74, 0x63, 0x65, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x05, 0x52, 0x07, 0x70, 0x61, 0x74, 0x63, 0x68, 0x65,
0x68, 0x65, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x0a, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x0a, 0x20, 0x03,
0x20, 0x03, 0x28, 0x05, 0x52, 0x07, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x28, 0x05, 0x52, 0x07, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x61,
0x05, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x61, 0x75, 0x75, 0x64, 0x69, 0x6f, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x61, 0x75, 0x64, 0x69,
0x64, 0x69, 0x6f, 0x42, 0x06, 0x5a, 0x04, 0x2e, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x6f, 0x22, 0x1d, 0x0a, 0x09, 0x55, 0x73, 0x65, 0x72, 0x50, 0x6f, 0x70, 0x75, 0x70, 0x12, 0x10,
0x0a, 0x03, 0x6d, 0x73, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6d, 0x73, 0x67,
0x22, 0x76, 0x0a, 0x0c, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
0x12, 0x36, 0x0a, 0x08, 0x64, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01,
0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x08,
0x64, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x73, 0x67, 0x18,
0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6d, 0x73, 0x67, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x63,
0x74, 0x69, 0x6f, 0x6e, 0x55, 0x72, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61,
0x63, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x72, 0x6c, 0x22, 0x82, 0x01, 0x0a, 0x07, 0x43, 0x6f, 0x6d,
0x6d, 0x61, 0x6e, 0x64, 0x12, 0x32, 0x0a, 0x0b, 0x6c, 0x69, 0x76, 0x65, 0x43, 0x6f, 0x6d, 0x6d,
0x61, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x73, 0x74, 0x69, 0x6c,
0x6c, 0x62, 0x6f, 0x78, 0x2e, 0x4c, 0x69, 0x76, 0x65, 0x48, 0x00, 0x52, 0x0b, 0x6c, 0x69, 0x76,
0x65, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x38, 0x0a, 0x0d, 0x73, 0x65, 0x61, 0x72,
0x63, 0x68, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32,
0x10, 0x2e, 0x73, 0x74, 0x69, 0x6c, 0x6c, 0x62, 0x6f, 0x78, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63,
0x68, 0x48, 0x00, 0x52, 0x0d, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x43, 0x6f, 0x6d, 0x6d, 0x61,
0x6e, 0x64, 0x42, 0x09, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x22, 0x31, 0x0a,
0x04, 0x4c, 0x69, 0x76, 0x65, 0x12, 0x29, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01,
0x20, 0x01, 0x28, 0x0e, 0x32, 0x13, 0x2e, 0x73, 0x74, 0x69, 0x6c, 0x6c, 0x62, 0x6f, 0x78, 0x2e,
0x4c, 0x69, 0x76, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65,
0x22, 0x08, 0x0a, 0x06, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2a, 0x37, 0x0a, 0x09, 0x4c, 0x69,
0x76, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0e, 0x0a, 0x0a, 0x4c, 0x53, 0x5f, 0x53, 0x54,
0x4f, 0x50, 0x50, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x4c, 0x53, 0x5f, 0x4c, 0x49,
0x56, 0x45, 0x10, 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x4c, 0x53, 0x5f, 0x50, 0x41, 0x55, 0x53, 0x45,
0x44, 0x10, 0x02, 0x42, 0x06, 0x5a, 0x04, 0x2e, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x33, 0x74, 0x6f, 0x33,
} }
@ -192,18 +648,33 @@ func file_stillbox_proto_rawDescGZIP() []byte {
return file_stillbox_proto_rawDescData return file_stillbox_proto_rawDescData
} }
var file_stillbox_proto_msgTypes = make([]protoimpl.MessageInfo, 1) var file_stillbox_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
var file_stillbox_proto_msgTypes = make([]protoimpl.MessageInfo, 7)
var file_stillbox_proto_goTypes = []any{ var file_stillbox_proto_goTypes = []any{
(*Call)(nil), // 0: stillbox.Call (LiveState)(0), // 0: stillbox.LiveState
(*timestamppb.Timestamp)(nil), // 1: google.protobuf.Timestamp (*Message)(nil), // 1: stillbox.Message
(*Call)(nil), // 2: stillbox.Call
(*UserPopup)(nil), // 3: stillbox.UserPopup
(*Notification)(nil), // 4: stillbox.Notification
(*Command)(nil), // 5: stillbox.Command
(*Live)(nil), // 6: stillbox.Live
(*Search)(nil), // 7: stillbox.Search
(*timestamppb.Timestamp)(nil), // 8: google.protobuf.Timestamp
} }
var file_stillbox_proto_depIdxs = []int32{ var file_stillbox_proto_depIdxs = []int32{
1, // 0: stillbox.Call.date_time:type_name -> google.protobuf.Timestamp 2, // 0: stillbox.Message.call:type_name -> stillbox.Call
1, // [1:1] is the sub-list for method output_type 4, // 1: stillbox.Message.notification:type_name -> stillbox.Notification
1, // [1:1] is the sub-list for method input_type 3, // 2: stillbox.Message.popup:type_name -> stillbox.UserPopup
1, // [1:1] is the sub-list for extension type_name 8, // 3: stillbox.Call.dateTime:type_name -> google.protobuf.Timestamp
1, // [1:1] is the sub-list for extension extendee 8, // 4: stillbox.Notification.dateTime:type_name -> google.protobuf.Timestamp
0, // [0:1] is the sub-list for field type_name 6, // 5: stillbox.Command.liveCommand:type_name -> stillbox.Live
7, // 6: stillbox.Command.searchCommand:type_name -> stillbox.Search
0, // 7: stillbox.Live.state:type_name -> stillbox.LiveState
8, // [8:8] is the sub-list for method output_type
8, // [8:8] is the sub-list for method input_type
8, // [8:8] is the sub-list for extension type_name
8, // [8:8] is the sub-list for extension extendee
0, // [0:8] is the sub-list for field type_name
} }
func init() { file_stillbox_proto_init() } func init() { file_stillbox_proto_init() }
@ -213,6 +684,18 @@ func file_stillbox_proto_init() {
} }
if !protoimpl.UnsafeEnabled { if !protoimpl.UnsafeEnabled {
file_stillbox_proto_msgTypes[0].Exporter = func(v any, i int) any { file_stillbox_proto_msgTypes[0].Exporter = func(v any, i int) any {
switch v := v.(*Message); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_stillbox_proto_msgTypes[1].Exporter = func(v any, i int) any {
switch v := v.(*Call); i { switch v := v.(*Call); i {
case 0: case 0:
return &v.state return &v.state
@ -224,19 +707,89 @@ func file_stillbox_proto_init() {
return nil return nil
} }
} }
file_stillbox_proto_msgTypes[2].Exporter = func(v any, i int) any {
switch v := v.(*UserPopup); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_stillbox_proto_msgTypes[3].Exporter = func(v any, i int) any {
switch v := v.(*Notification); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_stillbox_proto_msgTypes[4].Exporter = func(v any, i int) any {
switch v := v.(*Command); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_stillbox_proto_msgTypes[5].Exporter = func(v any, i int) any {
switch v := v.(*Live); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_stillbox_proto_msgTypes[6].Exporter = func(v any, i int) any {
switch v := v.(*Search); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
file_stillbox_proto_msgTypes[0].OneofWrappers = []any{
(*Message_Call)(nil),
(*Message_Notification)(nil),
(*Message_Popup)(nil),
}
file_stillbox_proto_msgTypes[4].OneofWrappers = []any{
(*Command_LiveCommand)(nil),
(*Command_SearchCommand)(nil),
} }
type x struct{} type x struct{}
out := protoimpl.TypeBuilder{ out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{ File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(), GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_stillbox_proto_rawDesc, RawDescriptor: file_stillbox_proto_rawDesc,
NumEnums: 0, NumEnums: 1,
NumMessages: 1, NumMessages: 7,
NumExtensions: 0, NumExtensions: 0,
NumServices: 0, NumServices: 0,
}, },
GoTypes: file_stillbox_proto_goTypes, GoTypes: file_stillbox_proto_goTypes,
DependencyIndexes: file_stillbox_proto_depIdxs, DependencyIndexes: file_stillbox_proto_depIdxs,
EnumInfos: file_stillbox_proto_enumTypes,
MessageInfos: file_stillbox_proto_msgTypes, MessageInfos: file_stillbox_proto_msgTypes,
}.Build() }.Build()
File_stillbox_proto = out.File File_stillbox_proto = out.File

View file

@ -4,10 +4,18 @@ option go_package = "./pb";
import "google/protobuf/timestamp.proto"; import "google/protobuf/timestamp.proto";
message Message {
oneof toClient_message {
Call call = 1;
Notification notification = 2;
UserPopup popup = 3;
}
}
message Call { message Call {
string audio_name = 1; string audioName = 1;
string audio_type = 2; string audioType = 2;
google.protobuf.Timestamp date_time = 3; google.protobuf.Timestamp dateTime = 3;
int32 system = 4; int32 system = 4;
int32 talkgroup = 5; int32 talkgroup = 5;
int32 source = 6; int32 source = 6;
@ -17,3 +25,33 @@ message Call {
repeated int32 sources = 10; repeated int32 sources = 10;
bytes audio = 11; bytes audio = 11;
} }
message UserPopup {
string msg = 1;
}
message Notification {
google.protobuf.Timestamp dateTime = 1;
string msg = 2;
string actionUrl = 3;
}
message Command {
oneof command {
Live liveCommand = 1;
Search searchCommand = 2;
}
}
enum LiveState {
LS_STOPPED = 0;
LS_LIVE = 1;
LS_PAUSED = 2;
}
message Live {
LiveState state = 1;
}
message Search {
}