示例#1
0
// TX thread
func (service *Service) doTX() {
	for {
		select {
		case task, ok := <-service.tx:
			if !ok || task == nil {
				log.Infof("WS: TX thread stopped")
				service.conn.Close() // TODO: send Close frame?
				return
			}

			body, err := task.Format()
			if err != nil {
				log.Warnf("WS: failed to format message (error: %s)", err)
				continue // TODO: return?
			}

			log.Tracef("WS: sending message: %s", string(body))
			err = service.conn.WriteMessage(websocket.TextMessage, body)
			if err != nil {
				log.Warnf("WS: failed to send message (error: %s)", err)
				continue // TODO: return?
			}

			//			case <-service.pingTimer.C:
			//			if err := c.write(websocket.PingMessage, []byte{}); err != nil {
			//				log.Warnf("WS: could not write ping message (error: %s)", err)
			//				return
			//			}
		}
	}
}
示例#2
0
func main() {
	configFile, config, err := conf.FromArgs()
	switch {
	case err != nil:
		log.Fatalf("Failed to read %q configuration (%s)", configFile, err)
	case configFile == "":
		log.Warnf("No configuration file provided!")
		log.Infof("Test configuration is used: %+v", config)
	default:
		log.Infof("Starting DeviceHive with %q configuration: %+v", configFile, config)
	}

	log.SetLevelByName(config.LoggingLevel)

	bus, err := dbus.SystemBus()
	if err != nil {
		log.Warnf("Cannot get system bus (error: %s)", err)
		log.Infof("Trying to use session bus for testing purposes...")
		if bus, err = dbus.SessionBus(); err != nil {
			log.Fatalf("Cannot get session bus (error: %s)", err)
			return
		}
	}

	reply, err := bus.RequestName(DBusConnName, dbus.NameFlagDoNotQueue)
	switch {
	case err != nil:
		log.Fatalf("Cannot request name %q (error: %s)", DBusConnName, err)
	case reply != dbus.RequestNameReplyPrimaryOwner:
		log.Fatalf("The name %q already taken", DBusConnName)
	}

	s, err := devicehive.NewService(config.URL, config.AccessKey)
	if err != nil {
		log.Fatalf("Failed to create DeviceHive service (error: %s)", err)
	}

	log.Infof("Starting %v", s)
	mainLoop(bus, s, config)
}
示例#3
0
// main loop
func mainLoop(bus *dbus.Conn, service devicehive.Service, config conf.Conf) {
	// getting server info
	info, err := service.GetServerInfo(waitTimeout)
	if err != nil {
		log.Warnf("Cannot get service info (error: %s)", err)
		return
	}

	// registering device
	device := devicehive.NewDevice(config.DeviceID, config.DeviceName,
		devicehive.NewDeviceClass("go-gateway-class", "0.1"))
	device.Key = config.DeviceKey
	if len(config.NetworkName) != 0 || len(config.NetworkKey) != 0 {
		device.Network = devicehive.NewNetwork(config.NetworkName, config.NetworkKey)
		device.Network.Description = config.NetworkDesc
	}
	err = service.RegisterDevice(device, waitTimeout)
	if err != nil {
		log.Warnf("Cannot register device (error: %s)", err)
		return
	}

	// start polling commands
	listener, err := service.SubscribeCommands(device, info.Timestamp, waitTimeout)
	if err != nil {
		log.Warnf("Cannot subscribe commands (error: %s)")
		return
	}

	wrapper := DBusWrapper{service: service, device: device}
	exportDBusObject(bus, &wrapper)

	for {
		select {
		case cmd := <-listener.C:
			params := ""
			if cmd.Parameters != nil {
				buf, err := json.Marshal(cmd.Parameters)
				if err != nil {
					log.Warnf("Cannot generate JSON from parameters of command %+v (error: %s)", cmd, err)
					continue
				}
				params = string(buf)
			}
			log.Infof("COMMAND %s -> %s(%v)", config.URL, cmd.Name, params)
			bus.Emit(ComDevicehiveCloudPath, ComDevicehiveCloudIface+".CommandReceived", cmd.Id, cmd.Name, params)
		}

		//time.Sleep(5 * time.Second)
	}
}
示例#4
0
// update command result
func (w *DBusWrapper) UpdateCommand(id uint64, status, result string) *dbus.Error {
	log.Infof("updating command(id:%d, status=%q, result:%q", id, status, result)
	dat, err := parseJSON(result)
	if err != nil {
		log.Warnf("failed to convert command result to JSON (error: %s)", err)
		return newDHError(err.Error())
	}

	command := devicehive.NewCommandResult(id, status, dat)
	err = w.service.UpdateCommand(w.device, command, waitTimeout)
	if err != nil {
		log.Warnf("failed to update command (error: %s)", err)
		return newDHError(err.Error())
	}

	return nil // OK
}
示例#5
0
// send notification
// priority is ignored
func (w *DBusWrapper) SendNotification(name, parameters string, priority uint64) *dbus.Error {
	log.Infof("sending notification(name=%q, params=%q, priority=%d)", name, parameters, priority)
	dat, err := parseJSON(parameters)
	if err != nil {
		log.Warnf("failed to convert notification parameters to JSON (error: %s)", err)
		return newDHError(err.Error())
	}

	notification := devicehive.NewNotification(name, dat)
	err = w.service.InsertNotification(w.device, notification, waitTimeout)
	if err != nil {
		log.Warnf("failed to send notification (error: %s)", err)
		return newDHError(err.Error())
	}

	return nil // OK
}
示例#6
0
func TestBatchNotificationInsert(t *testing.T) {
	device := testNewDevice()
	device.Network = testNewNetwork()

	s := testNewRest(t)
	s2 := s //testNewWs(t)

	device.Id += "-batch-ntf"
	testCheckRegisterDevice1(t, s, *device, true)

	count := testBatchLen
	gap := time.Duration(testGapMs) * time.Millisecond

	tx_ntfs := make([]*core.Notification, 0, count)
	rx_ntfs := make([]*core.Notification, 0, count)

	type Stat struct {
		tx_beg time.Time
		tx_end time.Time
		rx_end time.Time
	}
	stat := make(map[string]*Stat)

	// transmitter
	go func() {
		time.Sleep(2 * time.Second) // small delay before start
		log.Infof("TEST/TX: started")
		for i := 0; i < count; i++ {
			p := fmt.Sprintf("%d", i)
			ntf := core.NewNotification("batch-notification", p)
			stat[p] = &Stat{}
			stat[p].tx_beg = time.Now()
			err := s.InsertNotification(device, ntf, testWaitTimeout)
			stat[p].tx_end = time.Now()
			if err != nil {
				t.Errorf("failed to insert batch notification: %s", err)
				break
			}
			log.Infof("TEST/TX: %s", ntf)
			tx_ntfs = append(tx_ntfs, ntf)
			time.Sleep(gap)
		}
		log.Infof("TEST/TX: stopped")
	}()

	// receiver
	listener, err := s2.SubscribeNotifications(device, "", testWaitTimeout)
	if err != nil {
		t.Errorf("failed to subscribe notifications: %s", err)
		return
	}

	log.Infof("TEST/RX: started")
	for len(rx_ntfs) < count && !t.Failed() {
		select {
		case ntf := <-listener.C:
			if ntf.Name != "batch-notification" {
				// notification ignored
				continue
			}
			p := ntf.Parameters.(string)
			stat[p].rx_end = time.Now()
			log.Infof("TEST/RX: %s", ntf)
			rx_ntfs = append(rx_ntfs, ntf)
		case <-time.After(30 * time.Second):
			t.Errorf("failed to wait notification: %s", "timed out")
			break
		}
	}
	log.Infof("TEST/RX: stopped")

	err = s2.UnsubscribeNotifications(device, testWaitTimeout)
	if err != nil {
		t.Errorf("failed to unsubscribe notifications: %s", err)
		return
	}

	// compare tx_ntfs == rx_ntfs
	if len(tx_ntfs) != count || len(rx_ntfs) != count {
		t.Errorf("TX:%d != RX:%d notifications length mismatch", len(tx_ntfs), len(rx_ntfs))
		return
	}

	// time statistics:
	// ins - insertion time (tx_end - tx_beg)
	// rtt - round trip (rx_end - tx_beg)
	var ins, rtt TimeStat
	for i, tx := range tx_ntfs {
		rx := rx_ntfs[i]
		//		log.Infof("%d:\tTX:%q at %q\t\tRX:%q at %q", i,
		//				tx.Parameters, tx.Timestamp,
		//				rx.Parameters, rx.Timestamp)
		//		if tx.Name != rx.Name {
		//			t.Errorf("TX:%q != RX:%q notification name mismatch", tx.Name, rx.Name)
		//			continue
		//		}
		tx_p := tx.Parameters.(string)
		rx_p := rx.Parameters.(string)
		if tx_p != rx_p {
			t.Errorf("TX:%q != RX:%q notification parameter mismatch", tx_p, rx_p)
			continue
		}

		t := stat[tx_p]
		ins.Add(t.tx_end.Sub(t.tx_beg))
		rtt.Add(t.rx_end.Sub(t.tx_beg))
	}

	log.Infof("insert time: %s", ins)
	log.Infof(" round trip: %s", rtt)
}