// readPump pumps messages from the websocket connection to the hub. func (c *Conn) readPump() error { defer func() { c.ws.Close() }() c.ws.SetReadLimit(maxMessageSize) c.ws.SetReadDeadline(time.Now().Add(pongWait)) c.ws.SetPongHandler(func(string) error { c.ws.SetReadDeadline(time.Now().Add(pongWait)) return nil }) for { _, r, err := c.ws.NextReader() if err != nil { say.Verbosef("readPump: could not receive c.ws.NextReader() with error: %s", err.Error()) return err } buf := make([]byte, maxMessageSize) _, err = r.Read(buf) if err != nil { say.Verbosef("readPump: could not read c.ws.NextReader() to the buffer (%d bytes) with error: %s", maxMessageSize, err.Error()) return err } c.receive <- buf } }
func DeviceNotificationPoll( deviceHiveURL, deviceGuid, accessKey string, params []param.I, //maybe nil client *http.Client, //maybe nil requestOut chan *http.Request, //maybe nil ) (dnrs []DeviceNotificationResource, err error) { url := fmt.Sprintf("%s/device/%s/notification/poll", deviceHiveURL, deviceGuid) if client == nil { client = http.DefaultClient } url = param.IntegrateWithUrl(url, params) request, err := http.NewRequest("GET", url, nil) if err != nil { return } request.Header.Set("Authorization", "Bearer "+accessKey) if requestOut != nil { select { case requestOut <- request: default: say.Verbosef("You use requestout chan, but this chan is full.") } } say.Verbosef("Starting request %+v", say.RequestStr(request)) response, err := client.Do(request) if err != nil { return } defer response.Body.Close() body, err := ioutil.ReadAll(response.Body) if err != nil { return } if body != nil && len(body) > 0 { say.Verbosef("Request %s received response body: %s", say.RequestStr(request), string(body)) } else { say.Verbosef("Request %s received zero body", say.RequestStr(request)) } err = json.Unmarshal(body, &dnrs) if err != nil { if e := SrverrFromJson(body); IsSrverr(e) { err = e } return } return }
func (c *Conn) handleMessage(m []byte) { c.queueLock.Lock() defer c.queueLock.Unlock() var dat map[string]interface{} m = bytes.Trim(m, "\x00") err := json.Unmarshal(m, &dat) if err != nil { say.Verbosef("handleMessage: could not parse JSON in (%s) with error %s", string(m), err.Error()) } a := dat["action"] requestId := dat["requestId"] var r int if requestId != nil { r = int(requestId.(float64)) } callBack, ok := c.queue[r] if !ok && (a != "command/insert") { say.Verbosef("handleMessage: unhandled request with id=%d", r) return } switch a { case "device/save": go callBack(dat) case "notification/insert": go callBack(dat) case "command/subscribe": go callBack(dat) case "authenticate": go callBack(dat) case "command/update": go callBack(dat) case "command/insert": command := dat["command"] go c.CommandReceived()(command.(map[string]interface{})) default: say.Verbosef("handleMessage: Unknown notification: %s", a) } delete(c.queue, r) }
func (w *DbusObjectWrapper) SendNotification(name, parameters string, priority uint64) *dbus.Error { say.Verbosef("SendNotification(name='%s',params='%s',priority=%d)\n", name, parameters, priority) dat, err := parseJSON(parameters) if err != nil { return newDHError(err.Error()) } w.c.SendNotification(name, dat, priority) return nil }
func (w *DbusRestWrapper) SendNotification(name, parameters string, priority uint64) *dbus.Error { say.Verbosef("SendNotification(name='%s',params='%s',priority=%d)\n", name, parameters, priority) dat, err := parseJSON(parameters) if err != nil { return newDHError(err.Error()) } rest.DeviceNotificationInsert(w.URL, w.DeviceID, w.AccessKey, name, dat) return nil }
func (c *Conn) runInternal(accessKey string, init func()) error { origin := "http://localhost/" url := c.WebSocketURL() + "/device" say.Verbosef("Connecting using WS to %s", url) ws, _, err := websocket.DefaultDialer.Dial(url, http.Header{"Origin": []string{origin}, "Authorization": []string{"Bearer " + accessKey}}) if err != nil { say.Infof("Dial error: %s", err.Error()) return err } c.ws = ws go func() { for m := range c.senderQ.Out() { say.Verbosef("THROTTLING: Message has been received from priotiorized chan: %+v", m) c.SendCommand(m) } }() go c.writePump() go func() { for { m := <-c.receive go c.handleMessage(m) } }() go init() c.readPump() return nil }
func IntegrateWithUrl(baseUrl string, params []I) (resultUrl string) { resultUrl = baseUrl if params == nil || len(params) < 1 { return } u, err := url.Parse(baseUrl) if err != nil { say.Verbosef("params: IntegrateWithUrl error: %s", err.Error()) return } q := u.Query() for _, p := range params { q.Add(p.Name(), p.String()) } u.RawQuery = q.Encode() resultUrl = u.String() return }
func wsImplementation(bus *dbus.Conn, config conf.Conf) { var conn *ws.Conn for { info, err := rest.GetApiInfo(config.URL) if err == nil { say.Verbosef("API info: %+v", info) c := ws.New(info.WebSocketServerUrl, config.DeviceID, config.SendNotificationQueueCapacity, func(m map[string]interface{}) { p := m["parameters"] params := "" if p != nil { b, err := json.Marshal(p) if err != nil { say.Fatalf("Could not generete JSON from command %+v\nWith error %s", m, err.Error()) } params = string(b) } say.Verbosef("COMMAND %s -> %s(%v)", info.WebSocketServerUrl, m["command"].(string), params) bus.Emit("/com/devicehive/cloud", "com.devicehive.cloud.CommandReceived", uint32(m["id"].(float64)), m["command"].(string), params) }) conn = &c if err == nil { break } } say.Infof("API info error: %s", err.Error()) time.Sleep(5 * time.Second) } w := NewDbusObjectWrapper(conn) go conn.Run(config.AccessKey, func() { conn.RegisterDevice(config.DeviceID, config.DeviceName, config.DeviceKey, config.NetworkName, config.NetworkKey, config.NetworkDesc) conn.Authenticate(config.DeviceID, config.DeviceKey) conn.SubscribeCommands() }) bus.Export(w, "/com/devicehive/cloud", DBusConnName) // Introspectable n := &introspect.Node{ Name: "/com/devicehive/cloud", Interfaces: []introspect.Interface{ introspect.IntrospectData, prop.IntrospectData, { Name: "com.devicehive.cloud", Methods: introspect.Methods(w), }, }, } bus.Export(introspect.NewIntrospectable(n), "/com/devicehive/cloud", "org.freedesktop.DBus.Introspectable") root := &introspect.Node{ Children: []introspect.Node{ { Name: "com/devicehive/cloud", }, }, } bus.Export(introspect.NewIntrospectable(root), "/", "org.freedesktop.DBus.Introspectable") select {} }
func restImplementation(bus *dbus.Conn, config conf.Conf) { err := rest.DeviceRegisterEasy(config.URL, config.DeviceID, config.AccessKey, config.DeviceName, config.DeviceKey, config.NetworkName, config.NetworkKey, config.NetworkDesc) if err != nil { say.Infof("DeviceRegisterEasy error: %s", err.Error()) return } go func() { nControl := rest.NewPollAsync() cControl := rest.NewPollAsync() nOut := make(chan rest.DeviceNotificationResource, 16) cOut := make(chan rest.DeviceCmdResource, 16) go rest.DeviceNotificationPollAsync(config.URL, config.DeviceID, config.AccessKey, nOut, nControl) go rest.DeviceCmdPollAsync(config.URL, config.DeviceID, config.AccessKey, cOut, cControl) for { select { case n := <-nOut: parameters := "" if n.Parameters != nil { b, err := json.Marshal(n.Parameters) if err != nil { say.Infof("Could not generate JSON from parameters of notification %+v\nWith error %s", n, err.Error()) continue } parameters = string(b) } say.Verbosef("NOTIFICATION %s -> %s(%v)", config.URL, n.Notification, parameters) bus.Emit(restObjectPath, restCommandName, uint32(n.Id), n.Notification, parameters) case c := <-cOut: parameters := "" if c.Parameters != nil { b, err := json.Marshal(c.Parameters) if err != nil { say.Infof("Could not generate JSON from parameters of command %+v\nWith error %s", c, err.Error()) continue } parameters = string(b) } say.Verbosef("COMMAND %s -> %s(%v)", config.URL, c.Command, parameters) bus.Emit(restObjectPath, restCommandName, uint32(c.Id), c.Command, parameters) } } }() w := NewDbusRestWrapper(config) bus.Export(w, "/com/devicehive/cloud", DBusConnName) // Introspectable n := &introspect.Node{ Name: "/com/devicehive/cloud", Interfaces: []introspect.Interface{ introspect.IntrospectData, prop.IntrospectData, { Name: "com.devicehive.cloud", Methods: introspect.Methods(w), }, }, } bus.Export(introspect.NewIntrospectable(n), "/com/devicehive/cloud", "org.freedesktop.DBus.Introspectable") root := &introspect.Node{ Children: []introspect.Node{ { Name: "com/devicehive/cloud", }, }, } bus.Export(introspect.NewIntrospectable(root), "/", "org.freedesktop.DBus.Introspectable") select {} }