forked from zhaojh329/rttys
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcommand.go
128 lines (111 loc) · 3.29 KB
/
command.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
/*
* Copyright (C) 2017 Jianhui Zhao <[email protected]>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
package main
import (
"time"
"net/http"
"io/ioutil"
"encoding/json"
"github.com/gorilla/websocket"
)
const (
COMMAND_ERR_NONE = iota
COMMAND_ERR_TIMEOUT
COMMAND_ERR_NOTFOUND
COMMAND_ERR_READ
COMMAND_ERR_LOGIN
COMMAND_ERR_SYS
COMMAND_ERR_PARAMETER
COMMAND_ERR_DEVOFFLINE
)
type CommandReq struct {
ID uint32 `json:"id"`
Username string `json:"username"`
Password string `json:"password"`
Devid string `json:"devid"`
Cmd string `json:"cmd"`
Params []string `json:"params"`
Env []string `json:"env"`
}
type CommandResult struct {
ID uint32 `json:"id,omitempty"`
Err int `json:err`
Msg string `json:"msg"`
Code int `json:"code"`
Stdout string `json:"stdout"`
Stderr string `json:"stderr"`
}
var errStr = map[int]string {
COMMAND_ERR_NONE: "",
COMMAND_ERR_TIMEOUT: "timeout",
COMMAND_ERR_NOTFOUND: "not found",
COMMAND_ERR_READ: "read error",
COMMAND_ERR_LOGIN: "login failed",
COMMAND_ERR_SYS: "system error",
COMMAND_ERR_PARAMETER: "devid and cmd required",
COMMAND_ERR_DEVOFFLINE: "device offline",
}
func serveCmd(br *Bridge, w http.ResponseWriter, r *http.Request) {
ticker := time.NewTicker(time.Second * 5)
defer func() {
ticker.Stop()
}()
err := COMMAND_ERR_NONE
body, _ := ioutil.ReadAll(r.Body)
r.Body.Close()
req := CommandReq{}
json.Unmarshal(body, &req)
if req.Devid == "" || req.Cmd == "" {
err = COMMAND_ERR_PARAMETER
} else if dev, ok := br.devices[req.Devid]; !ok {
err = COMMAND_ERR_DEVOFFLINE
} else {
dev.mutex.Lock()
req.ID = dev.cmdid
dev.cmd[req.ID] = make(chan *wsMessage)
dev.cmdid = dev.cmdid + 1
if dev.cmdid == 1024 {
dev.cmdid = 0
}
cmd := dev.cmd[req.ID]
dev.mutex.Unlock()
js, _ := json.Marshal(req)
dev.wsWrite(websocket.TextMessage, js)
select {
case wsMsg := <- cmd:
res := CommandResult{}
json.Unmarshal(wsMsg.data, &res)
dev.mutex.Lock()
delete(dev.cmd, res.ID)
dev.mutex.Unlock()
res.ID = 0
res.Msg = errStr[res.Err]
js, _ = json.Marshal(res)
w.Write(js)
return
case <- ticker.C:
err = COMMAND_ERR_TIMEOUT
goto Err
}
}
Err:
res := CommandResult{Err: err, Msg: errStr[err]}
js, _ := json.Marshal(res)
w.Write(js)
}