summaryrefslogtreecommitdiff
path: root/src/helsinki.at/rhrdtime/rhrdtime.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/helsinki.at/rhrdtime/rhrdtime.go')
-rw-r--r--src/helsinki.at/rhrdtime/rhrdtime.go84
1 files changed, 72 insertions, 12 deletions
diff --git a/src/helsinki.at/rhrdtime/rhrdtime.go b/src/helsinki.at/rhrdtime/rhrdtime.go
index 58ba896..806e64e 100644
--- a/src/helsinki.at/rhrdtime/rhrdtime.go
+++ b/src/helsinki.at/rhrdtime/rhrdtime.go
@@ -37,13 +37,7 @@ import (
"github.com/tuxychandru/pubsub"
)
-type timeUpdate struct {
- Timestamp int64 `json:"timestamp"`
- TZOffset int `json:"tz_offset"`
- Week uint8 `json:"week"`
-}
-
-func getTimeUpdate() []byte {
+func getRDWeekAndOffset(t time.Time) (uint8, int) {
//
// This computes the current Rivendell Week based on the number
// of weeks since epoch.
@@ -64,15 +58,25 @@ func getTimeUpdate() []byte {
loc, err := time.LoadLocation("Europe/Vienna")
if err != nil {
fmt.Println(err)
- return []byte{'{', '}'}
+ return 0, 0
}
- now := time.Now().In(loc)
- _, offset := now.Zone()
+ t = t.In(loc)
+ _, offset := t.Zone()
+
+ sEpoch := t.Unix() + int64(offset)
+ return uint8(math.Floor(math.Mod((((float64(sEpoch)+259200)/604800)+2), 4)) + 1), offset
+}
- sEpoch := now.Unix() + int64(offset)
- week := uint8(math.Floor(math.Mod((((float64(sEpoch)+259200)/604800)+2), 4)) + 1)
+type timeUpdate struct {
+ Timestamp int64 `json:"timestamp"`
+ TZOffset int `json:"tz_offset"`
+ Week uint8 `json:"week"`
+}
+func getTimeUpdate() []byte {
+ now := time.Now()
+ week, offset := getRDWeekAndOffset(now)
update := timeUpdate{(now.Unix() * 1000) + int64(now.Nanosecond()/1000000), offset, week}
update_json, err := json.Marshal(update)
if err != nil {
@@ -118,11 +122,67 @@ func handleTimeUpdateClient(w http.ResponseWriter, r *http.Request, ps *pubsub.P
}
}
+type ntpMessage struct {
+ T1 int64 `json:"t1"`
+ T2 int64 `json:"t2"`
+ T3 int64 `json:"t3"`
+ T4 int64 `json:"t4"`
+ TZOffset int `json:"tz_offset"`
+ Week uint8 `json:"week"`
+}
+
+func handleNTPClient(w http.ResponseWriter, r *http.Request, ps *pubsub.PubSub) {
+ ws, err := websocket.Upgrade(w, r, nil, 1024, 1024)
+ if _, ok := err.(websocket.HandshakeError); ok {
+ http.Error(w, "Not a websocket handshake", 400)
+ return
+ } else if err != nil {
+ fmt.Println(err)
+ return
+ }
+ fmt.Println("Client connected", ws.RemoteAddr())
+
+ for {
+ msgtype, msg, err := ws.ReadMessage()
+ if err != nil {
+ fmt.Println("Client connected", ws.RemoteAddr())
+ return
+ }
+ now_t2 := time.Now()
+ if msgtype == websocket.TextMessage {
+
+ var n ntpMessage
+ if err := json.Unmarshal(msg, &n); err != nil {
+ fmt.Println("mallformed NTP message", err)
+ continue
+ }
+
+ n.T2 = (now_t2.Unix() * 1000) + int64(now_t2.Nanosecond()/1000000)
+ n.Week, n.TZOffset = getRDWeekAndOffset(now_t2)
+
+ now_t3 := time.Now()
+ n.T3 = (now_t3.Unix() * 1000) + int64(now_t3.Nanosecond()/1000000)
+
+ ntp_json, err := json.Marshal(n)
+ if err != nil {
+ fmt.Println(err)
+ continue
+ }
+ if err := ws.WriteMessage(websocket.TextMessage, ntp_json); err != nil {
+ return
+ }
+ }
+ }
+}
+
func RunMartini(ps *pubsub.PubSub, addr string) {
m := martini.Classic()
m.Get("/time", func(w http.ResponseWriter, r *http.Request) {
handleTimeUpdateClient(w, r, ps)
})
+ // m.Get("/ntp", func(w http.ResponseWriter, r *http.Request) {
+ // handleTimeUpdateClient(w, r, ps)
+ // })
m.RunOnAddr(addr)
}