-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgit2Control.go
239 lines (223 loc) · 6.41 KB
/
git2Control.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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
package main
/*
|------------------------------------------------------------------------
| This program is free software: you can redistribute it and/or modify |
| it under the terms of the GNU General Public License as published by |
| the Free Software Foundation, version 3 of the License. |
| |
| 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 General Public License for more details. |
| |
| You should have received a copy of the GNU General Public License |
| along with this program. If not, see <http://www.gnu.org/licenses/>. |
|------------------------------------------------------------------------
Written by Richard Masci.
*/
import (
"encoding/xml"
"fmt"
"github.com/spf13/pflag"
"io/ioutil"
"log"
"net"
"net/http"
"os"
"strconv"
"strings"
"time"
)
var searchIP string
var verb, help bool
type xmlParse struct {
Function xml.Name `xml:"Function"`
Status string `xml:"Status"`
}
func main() {
var camFunc string
var connIp, camPar, cmd string
pflag.StringVarP(&camFunc, "cam", "c", "", "Send commands to the camera. Default is to start")
pflag.StringVarP(&cmd, "cmd", "C", "2001", "Send camera command. (2001, 20017 etc... see Novatek API.")
pflag.StringVarP(&camPar, "par", "x", "1", "Parameter to send with command")
pflag.StringVarP(&searchIP, "searchSub", "i", "10.1.1", "First three octets of subnet to search for.")
pflag.BoolVarP(&verb, "verbose", "v", false, "Verbose")
pflag.BoolVarP(&help, "help", "h", false, "Help")
pflag.Parse()
if help {
fmt.Printf("Git2Control written by Richard Masci. https://github.com/rmasci/git2Control\n\n")
fmt.Printf("Commands:startCam\n\tstopCam\n\ttakePic\n\trecStatus\n\n")
pflag.PrintDefaults()
os.Exit(0)
}
myip := myIpIs()
cidrIp, fresh := readConf()
// if no file exists -- the scan starts with the solo's address Camera should be
// above this address
if cidrIp == "" {
cidrIp = myip
}
// if the config file is 'fresh' or less than 25 min old -- run with it.
// most flights last for less than 25 min.
if fresh {
connIp = strings.Split(cidrIp, "/")[0]
} else {
connIp = findIp(cidrIp)
if connIp == "" {
if myip == cidrIp {
fmt.Println("I can't find the camera")
os.Exit(1)
} else {
connIp = findIp(myip)
if connIp == "" {
fmt.Println("I can't find the camera")
os.Exit(1)
}
}
}
writeConf(connIp)
}
switch camFunc {
case "startCam":
fmt.Printf("Starting Camera\n")
bod, hstat := ctlCamera(connIp, "2001", "par=1")
log.Printf("Status: %s, %s\n", bod, hstat)
case "stopCam":
fmt.Printf("Stopping Camera\n")
bod, hstat := ctlCamera(connIp, "2001", "par=0")
log.Printf("Status: %s, %s\n", bod, hstat)
case "recStatus":
bod, hstat := ctlCamera(connIp, "2001", "")
fmt.Printf("Camera Rec Status:%s,%s\n", bod, hstat)
case "takePic":
fmt.Printf("Take picture.\n")
bod, hstat := ctlCamera(connIp, "2017", "")
log.Printf("Status: %s, %s\n", bod, hstat)
default:
var bod, hstat string
if cmd != "" {
if camPar != "" {
fmt.Printf("Running Command: %s with parameter: %s\n")
bod, hstat = ctlCamera(connIp, cmd, "par="+camPar)
} else {
fmt.Printf("Running Command: %s\n")
bod, hstat = ctlCamera(connIp, cmd, "")
}
log.Printf("Status: %s, %s\n", bod, hstat)
}
}
}
func errorHandle(err error, str string) {
if err != nil {
log.Printf("%s Error: %v\n", str, err)
os.Exit(1)
}
}
func myIpIs() string {
myIps, err := net.InterfaceAddrs()
errorHandle(err, "Get interface addresses")
for _, i := range myIps {
if strings.Contains(i.String(), searchIP) {
return i.String()
os.Exit(0)
}
}
return ""
}
func findIp(cidrIp string) string {
if verb {
fmt.Printf("CidrIP: %v\n", cidrIp)
}
toIp := 254
tmOut := 100 * time.Millisecond
myIp := strings.Split(cidrIp, ".")
lastOct, err := strconv.Atoi(strings.Split(myIp[3], "/")[0])
errorHandle(err, "Convert octet to int")
mask := strings.Split(myIp[3], "/")[1]
if verb {
fmt.Printf("Last: %v, Mask: %v\n", lastOct, mask)
}
if mask == "32" {
toIp = lastOct
} else {
lastOct++
}
firstThree := strings.Join(myIp[:3], ".")
if verb {
fmt.Println(cidrIp)
fmt.Println(lastOct)
fmt.Println(firstThree)
}
for i := lastOct; i <= toIp; i++ {
ipAddr := fmt.Sprintf("%s.%v", firstThree, i)
tcpAddr := fmt.Sprintf("%v:3333", ipAddr)
conn, err := net.DialTimeout("tcp4", tcpAddr, tmOut)
if err == nil {
fmt.Printf("Found Camera on: %v, sending command.\n", ipAddr)
conn.Close()
return ipAddr
} else {
if verb {
fmt.Printf("Not on %v -- %v\n", tcpAddr, err)
}
}
}
return ""
}
func ctlCamera(connIp, cmd, par string) (cmdStat, hStat string) {
var xOut xmlParse
var hGet string
if par != "" {
hGet = fmt.Sprintf("http://%v/?custom=1&cmd=%s&%v", connIp, cmd, par)
} else {
hGet = fmt.Sprintf("http://%v/?custom=1&cmd=%s", connIp, cmd)
}
fmt.Println(hGet)
res, err := http.Get(hGet)
errorHandle(err, "HTTP Get")
o, err := ioutil.ReadAll(res.Body)
errorHandle(err, "HTTP Read")
err = xml.Unmarshal(o, xOut)
cmdStat = xOut.Status
hStat = res.Status
res.Body.Close()
return cmdStat, hStat
}
func readConf() (cidrIp string, fresh bool) {
fresh = false
curDir, err := os.Getwd()
errorHandle(err, "Get Current Dir to write file")
fileName := fmt.Sprintf("%v/git2IP.txt", curDir)
if verb {
fmt.Printf("Reading File: %v\n", fileName)
}
retStr, err := ioutil.ReadFile(fileName)
if err != nil {
return "", fresh
}
if verb {
fmt.Printf("Conn Ip: %v\n", string(retStr))
}
// find out if the conf file is fresh
// Test time.. If < 25 min return w/o scan
nowTime := time.Now().Unix()
fileInfo, err := os.Stat("git2IP.txt")
errorHandle(err, "os.Stat -- couldn't stat file")
fileTime := fileInfo.ModTime().Unix()
if nowTime-fileTime < 1500 {
fresh = true
}
return string(retStr), fresh
}
func writeConf(camIp string) {
curDir, err := os.Getwd()
camIp = camIp + "/32"
errorHandle(err, "Get Current Dire to write file")
fileName := fmt.Sprintf("%v/git2IP.txt", curDir)
if verb {
fmt.Printf("Writing file...\n")
}
camIpByte := []byte(camIp)
err = ioutil.WriteFile(fileName, camIpByte, 0644)
errorHandle(err, "write conf file")
}