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