|
@@ -1,6 +1,13 @@
|
|
|
package hdsv2
|
|
|
|
|
|
import (
|
|
|
+ "encoding/json"
|
|
|
+ "errors"
|
|
|
+ "io/ioutil"
|
|
|
+ "net/http"
|
|
|
+ "strconv"
|
|
|
+ "strings"
|
|
|
+
|
|
|
"imuslab.com/arozos/mod/iot"
|
|
|
"imuslab.com/arozos/mod/network/mdns"
|
|
|
)
|
|
@@ -15,7 +22,7 @@ import (
|
|
|
|
|
|
type Handler struct {
|
|
|
scanner *mdns.MDNSHost
|
|
|
- historyList []iot.Device
|
|
|
+ historyList []*iot.Device
|
|
|
lastScanTime int64
|
|
|
}
|
|
|
|
|
@@ -24,11 +31,138 @@ func NewProtocolHandler(scanner *mdns.MDNSHost) *Handler {
|
|
|
//Create a new MDNS Host
|
|
|
return &Handler{
|
|
|
scanner,
|
|
|
- []iot.Device{},
|
|
|
+ []*iot.Device{},
|
|
|
0,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+//Scan the devices within the LAN
|
|
|
func (h *Handler) Scan() ([]*iot.Device, error) {
|
|
|
+ foundDevices := []*iot.Device{}
|
|
|
+ hosts := h.scanner.Scan(3, "hds.arozos.com")
|
|
|
+ for _, host := range hosts {
|
|
|
+ thisDevice := iot.Device{
|
|
|
+ Name: host.HostName,
|
|
|
+ Port: host.Port,
|
|
|
+ Model: host.Model,
|
|
|
+ Version: host.BuildVersion + "-" + host.MinorVersion,
|
|
|
+ Manufacturer: host.Vendor,
|
|
|
+ DeviceUUID: host.UUID,
|
|
|
+
|
|
|
+ IPAddr: host.IPv4[0].String(),
|
|
|
+ RequireAuth: false,
|
|
|
+ RequireConnect: false,
|
|
|
+ Status: map[string]interface{}{},
|
|
|
+ }
|
|
|
+ //Try to get the device status
|
|
|
+ status, err := getStatusForDevice(&thisDevice)
|
|
|
+ if err != nil {
|
|
|
+ //This might be not a valid HDSv2 device. Skip this
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ thisDevice.Status = status
|
|
|
+
|
|
|
+ //Get the device content endpoints
|
|
|
+ eps, err := getEndpoints(&thisDevice)
|
|
|
+ if err != nil {
|
|
|
+ //This might be not a valid HDSv2 device. Skip this
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ thisDevice.ControlEndpoints = eps
|
|
|
+
|
|
|
+ //Push this host into found device list
|
|
|
+ foundDevices = append(foundDevices, &thisDevice)
|
|
|
+ }
|
|
|
+
|
|
|
+ h.historyList = foundDevices
|
|
|
+
|
|
|
+ return foundDevices, nil
|
|
|
+}
|
|
|
+
|
|
|
+//Return the history scan list from the handler
|
|
|
+func (h *Handler) List() ([]*iot.Device, error) {
|
|
|
+ return h.historyList, nil
|
|
|
+}
|
|
|
+
|
|
|
+//Home Dynamic system's devices no need to established conenction before executing anything
|
|
|
+func (h *Handler) Connect(device *iot.Device) error {
|
|
|
+ return nil
|
|
|
+}
|
|
|
+
|
|
|
+//Same rules also apply to disconnect
|
|
|
+func Disconnect(device *iot.Device) error {
|
|
|
+ return nil
|
|
|
+}
|
|
|
+
|
|
|
+//Get the status of the device
|
|
|
+func (h *Handler) Status(device *iot.Device) (map[string]interface{}, error) {
|
|
|
+ return getStatusForDevice(device)
|
|
|
+}
|
|
|
+
|
|
|
+//Get the status of the device
|
|
|
+func (h *Handler) Execute(device *iot.Device, endpoint *iot.Endpoint, payload interface{}) (interface{}, error) {
|
|
|
+ var result interface{}
|
|
|
+ return result, nil
|
|
|
+}
|
|
|
+
|
|
|
+//Get endpoint of the given device object
|
|
|
+func getEndpoints(device *iot.Device) ([]*iot.Endpoint, error) {
|
|
|
+ //Parse the URL of the endpoint apis location (eps)
|
|
|
+ requestURL := "http://" + device.IPAddr + ":" + strconv.Itoa(device.Port) + "/eps"
|
|
|
+ resp, err := http.Get(requestURL)
|
|
|
+ if err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+
|
|
|
+ //Get the body content
|
|
|
+ content, err := ioutil.ReadAll(resp.Body)
|
|
|
+ if err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+
|
|
|
+ //Check if the resp is json
|
|
|
+ if !isJSON(strings.TrimSpace(string(content))) {
|
|
|
+ return nil, errors.New("Invalid HDSv2 protocol")
|
|
|
+ }
|
|
|
+
|
|
|
+ //Convert the results to Endpoints
|
|
|
+ endpoints := []*iot.Endpoint{}
|
|
|
+ err = json.Unmarshal(content, &endpoints)
|
|
|
+ if err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+
|
|
|
+ return endpoints, nil
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+//Get status given the device object.
|
|
|
+func getStatusForDevice(device *iot.Device) (map[string]interface{}, error) {
|
|
|
+ //Parse the URL for its status api endpoint
|
|
|
+ requestURL := "http://" + device.IPAddr + ":" + strconv.Itoa(device.Port) + "/status"
|
|
|
+ resp, err := http.Get(requestURL)
|
|
|
+ if err != nil {
|
|
|
+ return map[string]interface{}{}, err
|
|
|
+ }
|
|
|
+
|
|
|
+ //Get the body content
|
|
|
+ content, err := ioutil.ReadAll(resp.Body)
|
|
|
+ if err != nil {
|
|
|
+ return map[string]interface{}{}, err
|
|
|
+ }
|
|
|
+
|
|
|
+ //Check if the resp is json
|
|
|
+ if !isJSON(strings.TrimSpace(string(content))) {
|
|
|
+ return map[string]interface{}{}, errors.New("Invalid HDSv2 protocol")
|
|
|
+ }
|
|
|
+
|
|
|
+ //Ok. Parse it
|
|
|
+ status := map[string]interface{}{}
|
|
|
+ err = json.Unmarshal(content, &status)
|
|
|
+ if err != nil {
|
|
|
+ return map[string]interface{}{}, err
|
|
|
+ }
|
|
|
+
|
|
|
+ return status, nil
|
|
|
|
|
|
}
|