]> code.octet-stream.net Git - broadcaster/blob - internal/protocol/protocol.go
User management
[broadcaster] / internal / protocol / protocol.go
1 package protocol
2
3 import (
4 "encoding/json"
5 "errors"
6 "fmt"
7 )
8
9 const (
10 StartTimeFormat = "2006-01-02T15:04"
11 LocalTimeFormat = "Mon _2 Jan 2006 15:04:05"
12
13 // Radio to server
14
15 AuthenticateType = "authenticate"
16 StatusType = "status"
17
18 // Server to radio
19
20 FilesType = "files"
21 PlaylistsType = "playlists"
22 StopType = "stop"
23
24 // Status values
25
26 StatusIdle = "idle"
27 StatusDelay = "delay"
28 StatusChannelInUse = "channel_in_use"
29 StatusPlaying = "playing"
30 )
31
32 // Base message type to determine what type of payload is expected.
33 type Message struct {
34 T string
35 }
36
37 // Initial message from Radio to authenticate itself with a token string.
38 type AuthenticateMessage struct {
39 T string
40 Token string
41 }
42
43 // Server updates the radio with the list of files that currently exist.
44 // This will be provided on connect and when there are any changes.
45 // The radio is expected to obtain all these files and cache them locally.
46 type FilesMessage struct {
47 T string
48 Files []FileSpec
49 }
50
51 type PlaylistsMessage struct {
52 T string
53 Playlists []PlaylistSpec
54 }
55
56 // Any playlist currently being played should be stopped and PTT disengaged.
57 type StopMessage struct {
58 T string
59 }
60
61 type StatusMessage struct {
62 T string
63
64 // Status w.r.t. playing a playlist
65 Status string
66
67 // File being played or about to be played - empty string in idle status
68 Filename string
69
70 // Name of playlist being played - empty string in idle status
71 Playlist string
72
73 // Seconds until playback begins - never mind latency
74 DelaySecondsRemaining int
75
76 // Number of seconds file has been actually playing
77 PlaybackSecondsElapsed int
78
79 // Number of seconds waiting for channel to clear
80 WaitingForChannelSeconds int
81
82 PTT bool
83 COS bool
84 FilesInSync bool
85
86 // Timestamp of the current time on this radio, using LocalTimeFormat
87 LocalTime string
88
89 // Time zone in use, e.g. "Australia/Hobart"
90 TimeZone string
91 }
92
93 // Description of an individual file available in the broadcasting system.
94 type FileSpec struct {
95 // Filename, e.g. "broadcast.wav"
96 Name string
97 // SHA-256 hash of the file's contents
98 Hash string
99 }
100
101 type PlaylistSpec struct {
102 Id int
103 Name string
104 StartTime string
105 Entries []EntrySpec
106 }
107
108 type EntrySpec struct {
109 Filename string
110 DelaySeconds int
111 IsRelative bool
112 }
113
114 func ParseMessage(data []byte) (string, interface{}, error) {
115 var t Message
116 err := json.Unmarshal(data, &t)
117 if err != nil {
118 return "", nil, err
119 }
120
121 if t.T == AuthenticateType {
122 var auth AuthenticateMessage
123 err = json.Unmarshal(data, &auth)
124 if err != nil {
125 return "", nil, err
126 }
127 return t.T, auth, nil
128 }
129
130 if t.T == FilesType {
131 var files FilesMessage
132 err = json.Unmarshal(data, &files)
133 if err != nil {
134 return "", nil, err
135 }
136 return t.T, files, nil
137 }
138
139 if t.T == PlaylistsType {
140 var playlists PlaylistsMessage
141 err = json.Unmarshal(data, &playlists)
142 if err != nil {
143 return "", nil, err
144 }
145 return t.T, playlists, nil
146 }
147
148 if t.T == StatusType {
149 var status StatusMessage
150 err = json.Unmarshal(data, &status)
151 if err != nil {
152 return "", nil, err
153 }
154 return t.T, status, nil
155 }
156
157 if t.T == StopType {
158 var stop StopMessage
159 err = json.Unmarshal(data, &stop)
160 if err != nil {
161 return "", nil, err
162 }
163 return t.T, stop, nil
164 }
165
166 return "", nil, errors.New(fmt.Sprintf("unknown message type %v", t.T))
167 }