Beispiel #1
0
// 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
}
Beispiel #3
0
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)
}
Beispiel #4
0
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
}
Beispiel #5
0
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
}
Beispiel #6
0
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
}
Beispiel #7
0
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
}
Beispiel #8
0
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 {}

}
Beispiel #9
0
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 {}
}