|
@@ -5,7 +5,9 @@ import (
|
|
"encoding/json"
|
|
"encoding/json"
|
|
"fmt"
|
|
"fmt"
|
|
"log"
|
|
"log"
|
|
|
|
+ "net"
|
|
"os"
|
|
"os"
|
|
|
|
+ "sparrow/pkg/coap"
|
|
"sparrow/pkg/protocol"
|
|
"sparrow/pkg/protocol"
|
|
"sparrow/pkg/tlv"
|
|
"sparrow/pkg/tlv"
|
|
"time"
|
|
"time"
|
|
@@ -17,27 +19,27 @@ const (
|
|
commonCmdGetStatus = uint16(65528)
|
|
commonCmdGetStatus = uint16(65528)
|
|
)
|
|
)
|
|
|
|
|
|
-// device register args
|
|
|
|
|
|
+// DeviceRegisterArgs device register args
|
|
type DeviceRegisterArgs struct {
|
|
type DeviceRegisterArgs struct {
|
|
ProductKey string `json:"product_key" binding:"required"`
|
|
ProductKey string `json:"product_key" binding:"required"`
|
|
DeviceCode string `json:"device_code" binding:"required"`
|
|
DeviceCode string `json:"device_code" binding:"required"`
|
|
Version string `json:"version" binding:"required"`
|
|
Version string `json:"version" binding:"required"`
|
|
}
|
|
}
|
|
|
|
|
|
-// device authentication args
|
|
|
|
|
|
+// DeviceAuthArgs device authentication args
|
|
type DeviceAuthArgs struct {
|
|
type DeviceAuthArgs struct {
|
|
DeviceId int64 `json:"device_id" binding:"required"`
|
|
DeviceId int64 `json:"device_id" binding:"required"`
|
|
DeviceSecret string `json:"device_secret" binding:"required"`
|
|
DeviceSecret string `json:"device_secret" binding:"required"`
|
|
Protocol string `json:"protocol" binding:"required"`
|
|
Protocol string `json:"protocol" binding:"required"`
|
|
}
|
|
}
|
|
|
|
|
|
-// common response fields
|
|
|
|
|
|
+// Common common response fields
|
|
type Common struct {
|
|
type Common struct {
|
|
Code int `json:"code"`
|
|
Code int `json:"code"`
|
|
Message string `json:"message"`
|
|
Message string `json:"message"`
|
|
}
|
|
}
|
|
|
|
|
|
-// device register response data field
|
|
|
|
|
|
+// DeviceRegisterData device register response data field
|
|
type DeviceRegisterData struct {
|
|
type DeviceRegisterData struct {
|
|
DeviceId int64 `json:"device_id"`
|
|
DeviceId int64 `json:"device_id"`
|
|
DeviceSecret string `json:"device_secret"`
|
|
DeviceSecret string `json:"device_secret"`
|
|
@@ -45,32 +47,34 @@ type DeviceRegisterData struct {
|
|
DeviceIdentifier string `json:"device_identifier"`
|
|
DeviceIdentifier string `json:"device_identifier"`
|
|
}
|
|
}
|
|
|
|
|
|
-// device register response
|
|
|
|
|
|
+// DeviceRegisterResponse device register response
|
|
type DeviceRegisterResponse struct {
|
|
type DeviceRegisterResponse struct {
|
|
Common
|
|
Common
|
|
Data DeviceRegisterData `json:"data"`
|
|
Data DeviceRegisterData `json:"data"`
|
|
}
|
|
}
|
|
|
|
|
|
-// device auth response data field
|
|
|
|
|
|
+// DeviceAuthData device auth response data field
|
|
type DeviceAuthData struct {
|
|
type DeviceAuthData struct {
|
|
AccessToken string `json:"access_token"`
|
|
AccessToken string `json:"access_token"`
|
|
AccessAddr string `json:"access_addr"`
|
|
AccessAddr string `json:"access_addr"`
|
|
}
|
|
}
|
|
|
|
|
|
-// device auth response
|
|
|
|
|
|
+// DeviceAuthResponse device auth response
|
|
type DeviceAuthResponse struct {
|
|
type DeviceAuthResponse struct {
|
|
Common
|
|
Common
|
|
Data DeviceAuthData `json:"data"`
|
|
Data DeviceAuthData `json:"data"`
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// Device a device
|
|
type Device struct {
|
|
type Device struct {
|
|
- // API URL
|
|
|
|
|
|
+ // Url API URL
|
|
Url string
|
|
Url string
|
|
|
|
|
|
// basic info
|
|
// basic info
|
|
ProductKey string
|
|
ProductKey string
|
|
DeviceCode string
|
|
DeviceCode string
|
|
Version string
|
|
Version string
|
|
|
|
+ Proto string
|
|
|
|
|
|
// private things
|
|
// private things
|
|
id int64
|
|
id int64
|
|
@@ -79,28 +83,31 @@ type Device struct {
|
|
access string
|
|
access string
|
|
}
|
|
}
|
|
|
|
|
|
-func NewDevice(url string, productkey string, code string, version string) *Device {
|
|
|
|
|
|
+// NewDevice create a device
|
|
|
|
+func NewDevice(url string, productkey string, code string, version string, proto string) *Device {
|
|
|
|
|
|
return &Device{
|
|
return &Device{
|
|
Url: url,
|
|
Url: url,
|
|
ProductKey: productkey,
|
|
ProductKey: productkey,
|
|
DeviceCode: code,
|
|
DeviceCode: code,
|
|
Version: version,
|
|
Version: version,
|
|
|
|
+ Proto: proto,
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// DoRegister device register
|
|
func (d *Device) DoRegister() error {
|
|
func (d *Device) DoRegister() error {
|
|
args := DeviceRegisterArgs{
|
|
args := DeviceRegisterArgs{
|
|
ProductKey: d.ProductKey,
|
|
ProductKey: d.ProductKey,
|
|
DeviceCode: d.DeviceCode,
|
|
DeviceCode: d.DeviceCode,
|
|
Version: d.Version,
|
|
Version: d.Version,
|
|
}
|
|
}
|
|
- regUrl := fmt.Sprintf("%v%v", d.Url, "/v1/devices/registration")
|
|
|
|
|
|
+ regURL := fmt.Sprintf("%v%v", d.Url, "/v1/devices/registration")
|
|
request, err := json.Marshal(args)
|
|
request, err := json.Marshal(args)
|
|
if err != nil {
|
|
if err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
- jsonresp, err := SendHttpRequest(regUrl, string(request), "POST", nil)
|
|
|
|
|
|
+ jsonresp, err := SendHttpRequest(regURL, string(request), "POST", nil)
|
|
if err != nil {
|
|
if err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
@@ -120,18 +127,19 @@ func (d *Device) DoRegister() error {
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// DoLogin device log in
|
|
func (d *Device) DoLogin() error {
|
|
func (d *Device) DoLogin() error {
|
|
args := DeviceAuthArgs{
|
|
args := DeviceAuthArgs{
|
|
DeviceId: d.id,
|
|
DeviceId: d.id,
|
|
DeviceSecret: d.secrect,
|
|
DeviceSecret: d.secrect,
|
|
- Protocol: "mqtt",
|
|
|
|
|
|
+ Protocol: d.Proto,
|
|
}
|
|
}
|
|
- regUrl := fmt.Sprintf("%v%v", d.Url, "/v1/devices/authentication")
|
|
|
|
|
|
+ regURL := fmt.Sprintf("%v%v", d.Url, "/v1/devices/authentication")
|
|
request, err := json.Marshal(args)
|
|
request, err := json.Marshal(args)
|
|
if err != nil {
|
|
if err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
- jsonresp, err := SendHttpRequest(regUrl, string(request), "POST", nil)
|
|
|
|
|
|
+ jsonresp, err := SendHttpRequest(regURL, string(request), "POST", nil)
|
|
if err != nil {
|
|
if err != nil {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
@@ -163,7 +171,7 @@ func (d *Device) reportStatus(client *MQTT.Client) {
|
|
Flag: 0,
|
|
Flag: 0,
|
|
Timestamp: uint64(time.Now().Unix() * 1000),
|
|
Timestamp: uint64(time.Now().Unix() * 1000),
|
|
}
|
|
}
|
|
- param := []interface{}{"li jian"}
|
|
|
|
|
|
+ param := []interface{}{1}
|
|
params, err := tlv.MakeTLVs(param)
|
|
params, err := tlv.MakeTLVs(param)
|
|
if err != nil {
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
fmt.Println(err)
|
|
@@ -196,6 +204,54 @@ func (d *Device) reportStatus(client *MQTT.Client) {
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+func (d *Device) coapReportStatus(conn *net.UDPConn) {
|
|
|
|
+
|
|
|
|
+ for {
|
|
|
|
+ time.Sleep(10 * time.Second)
|
|
|
|
+ payloadHead := protocol.DataHead{
|
|
|
|
+ Flag: 0,
|
|
|
|
+ Timestamp: uint64(time.Now().Unix() * 1000),
|
|
|
|
+ }
|
|
|
|
+ param := []interface{}{1}
|
|
|
|
+ params, err := tlv.MakeTLVs(param)
|
|
|
|
+ if err != nil {
|
|
|
|
+ fmt.Println(err)
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ sub := protocol.SubData{
|
|
|
|
+ Head: protocol.SubDataHead{
|
|
|
|
+ SubDeviceid: uint16(1),
|
|
|
|
+ PropertyNum: uint16(1),
|
|
|
|
+ ParamsCount: uint16(len(params)),
|
|
|
|
+ },
|
|
|
|
+ Params: params,
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ status := protocol.Data{
|
|
|
|
+ Head: payloadHead,
|
|
|
|
+ SubData: []protocol.SubData{},
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ status.SubData = append(status.SubData, sub)
|
|
|
|
+
|
|
|
|
+ payload, err := status.Marshal()
|
|
|
|
+ if err != nil {
|
|
|
|
+ fmt.Println(err)
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ req := &coap.BaseMessage{
|
|
|
|
+ Code: coap.POST,
|
|
|
|
+ Type: coap.CON,
|
|
|
|
+ Token: d.token,
|
|
|
|
+ Payload: payload,
|
|
|
|
+ }
|
|
|
|
+ req.SetPathString(fmt.Sprintf("%d/s", d.id))
|
|
|
|
+ reqbytes, _ := req.Encode()
|
|
|
|
+ conn.Write(reqbytes)
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
func (d *Device) reportEvent(client *MQTT.Client) {
|
|
func (d *Device) reportEvent(client *MQTT.Client) {
|
|
for {
|
|
for {
|
|
time.Sleep(3 * time.Second)
|
|
time.Sleep(3 * time.Second)
|
|
@@ -275,7 +331,37 @@ func (d *Device) messageHandler(client *MQTT.Client, msg MQTT.Message) {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// DoAccess device access
|
|
func (d *Device) DoAccess() error {
|
|
func (d *Device) DoAccess() error {
|
|
|
|
+ if d.Proto == "mqtt" {
|
|
|
|
+ if err := d.doMQTTAccess(); err != nil {
|
|
|
|
+ fmt.Printf("do mqtt access error:%s", err.Error())
|
|
|
|
+ }
|
|
|
|
+ } else if d.Proto == "coap" {
|
|
|
|
+ if err := d.doCoAPAccess(); err != nil {
|
|
|
|
+ fmt.Printf("do coap access error:%s", err.Error())
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return nil
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func (d *Device) doCoAPAccess() error {
|
|
|
|
+ fmt.Printf("get access addr :%s", d.access)
|
|
|
|
+ addr, err := net.ResolveUDPAddr("udp", d.access)
|
|
|
|
+ if err != nil {
|
|
|
|
+ return err
|
|
|
|
+ }
|
|
|
|
+ conn, err := net.DialUDP("udp", nil, addr)
|
|
|
|
+ if err != nil {
|
|
|
|
+ return err
|
|
|
|
+ }
|
|
|
|
+ defer conn.Close()
|
|
|
|
+ go d.coapReportStatus(conn)
|
|
|
|
+ <-make(chan int)
|
|
|
|
+ return nil
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func (d *Device) doMQTTAccess() error {
|
|
logger := log.New(os.Stdout, "", log.LstdFlags)
|
|
logger := log.New(os.Stdout, "", log.LstdFlags)
|
|
MQTT.ERROR = logger
|
|
MQTT.ERROR = logger
|
|
MQTT.CRITICAL = logger
|
|
MQTT.CRITICAL = logger
|
|
@@ -298,9 +384,6 @@ func (d *Device) DoAccess() error {
|
|
if token := c.Connect(); token.Wait() && token.Error() != nil {
|
|
if token := c.Connect(); token.Wait() && token.Error() != nil {
|
|
return token.Error()
|
|
return token.Error()
|
|
}
|
|
}
|
|
-
|
|
|
|
- // beigin report event test
|
|
|
|
- //go d.reportEvent(c)
|
|
|
|
go d.reportStatus(c)
|
|
go d.reportStatus(c)
|
|
// we just pause here to wait for messages
|
|
// we just pause here to wait for messages
|
|
<-make(chan int)
|
|
<-make(chan int)
|