av/input/gvctrl/request.go

211 lines
6.7 KiB
Go
Raw Normal View History

/*
DESCRIPTION
request.go provides unexported functionality for creating and sending requests
required to configure settings of the GeoVision camera.
AUTHORS
Saxon A. Nelson-Milton <saxon@ausocean.org>
LICENSE
Copyright (C) 2019 the Australian Ocean Lab (AusOcean)
It is free software: you can redistribute it and/or modify them
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
It 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
in gpl.txt. If not, see http://www.gnu.org/licenses.
*/
package gvctrl
import (
"bytes"
"fmt"
"io/ioutil"
"net/http"
"net/url"
"regexp"
"strconv"
)
const (
baseURL = "http://192.168.1.50"
loginPageURL = baseURL + "/ssi.cgi/login.htm"
loggedInURL = baseURL + "/LoginPC.cgi"
settingsURL = baseURL + "/VideoSetting.cgi"
)
const (
user = "admin"
pass = "admin"
)
func genLogIn(c *http.Client, id, host string) (string, error) {
req, err := http.NewRequest("GET", loginPageURL, nil)
if err != nil {
return "", fmt.Errorf("can't create GET request for log in page: %v", err)
}
req.Header.Set("Connection", "keep-alive")
req.Header.Set("Cache-Control", "max-age=0")
req.Header.Set("Upgrade-Insecure-Requests", "1")
req.Header.Set("User-Agent", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36")
req.Header.Set("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3")
req.Header.Set("Accept-Encoding", "gzip, deflate")
req.Header.Set("Accept-Language", "en-GB,en-US;q=0.9,en;q=0.8")
req.Header.Set("Cookie", "CLIENT_ID="+id)
resp, err := c.Do(req)
if err != nil {
return "", fmt.Errorf("could not do GET request for log in page: %v", err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return "", fmt.Errorf("could not read response of GET request for log in page: %v", err)
}
// Find the CC values in the source of the response.
// These are used in calculation of the md5 hashes for the form submitted at
// log in.
var cc [2]string
for i := range cc {
regStr := "cc" + strconv.Itoa(i+1) + "=\".{4}\""
exp := regexp.MustCompile(regStr).FindString(string(body))
cc[i] = exp[5 : len(exp)-1]
}
var data url.Values
data.Set("grp", "-1")
data.Set("username", "")
data.Set("password", "")
data.Set("Apply", "Apply")
data.Set("umd5", md5Hex(cc[0]+user+cc[1]))
data.Set("pmd5", md5Hex(cc[1]+pass+cc[0]))
data.Set("browser", "1")
data.Set("is_check_OCX_OK", "0")
return data.Encode(), nil
}
func logIn(c *http.Client, id, host, b string) error {
req, err := http.NewRequest("POST", loggedInURL, bytes.NewBuffer([]byte(b)))
if err != nil {
return fmt.Errorf("could not create log in request: %v", err)
}
req.Header.Set("Connection", "keep-alive")
req.Header.Set("Content-Length", "142")
req.Header.Set("Cache-Control", "max-age=0")
req.Header.Set("Origin", "http://192.168.1.50")
req.Header.Set("Upgrade-Insecure-Requests", "1")
req.Header.Set("User-Agent", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36")
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
req.Header.Set("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3")
req.Header.Set("Referer", "http://192.168.1.50/ssi.cgi/Login.htm")
req.Header.Set("Accept-Encoding", "gzip, deflate")
req.Header.Set("Accept-Language", "en-GB,en-US;q=0.9,en;q=0.8")
req.Header.Set("Cookie", "CLIENT_ID="+id+"; CLIENT_ID="+id)
_, err = c.Do(req)
if err != nil {
return fmt.Errorf("could not do log in request: %v", err)
}
return nil
}
func submitSettings(c *http.Client, id, host string, s settings) error {
var f url.Values
f.Set("dwConnType", "5")
f.Set("mpeg_type", "10")
f.Set("dwflicker_hz", "0")
f.Set("szResolution", s.res)
f.Set("dwFrameRate", s.frameRate)
if s.codec == codecMJPEG {
f.Set("vbr_enable", "1")
f.Set("dwVbrQuality", s.vbr)
f.Set("vbrmaxbitrate", "750000")
} else {
switch s.vbr {
case "0":
f.Set("vbr_enable", "0")
f.Set("max_bit_rate", s.bitRate)
case "1":
f.Set("vbr_enable", "1")
f.Set("dwVbrQuality", s.vbr)
f.Set("vbrmaxbitrate", s.bitRate)
default:
panic("invalid vbrEnable parameter")
}
f.Set("custom_rate_control_type", "0")
f.Set("custom_bitrate", "512000")
f.Set("custom_qp_init", "25")
f.Set("custom_qp_min", "10")
f.Set("custom_qp_max", "40")
}
f.Set("gop_N", s.refresh)
if s.codec == codecH264 || s.codec == codecH265 {
f.Set("dwEncProfile", "3")
f.Set("dwEncLevel", "31")
f.Set("dwEntropy", "0")
}
f.Set("u8PreAlarmBuf", "1")
f.Set("u32PostAlarmBuf2Disk", "1")
f.Set("u8SplitInterval", "5")
f.Set("bEnableIO", "1")
f.Set("bEbIoIn", "1")
f.Set("bEbIoIn1", "1")
f.Set("bOSDFontSize", "0")
f.Set("bEnableOSDCameraName", "1")
f.Set("bCamNamePos", "2")
f.Set("bEnableOSDDate", "1")
f.Set("bDatePos", "2")
f.Set("bEnableOSDTime", "1")
f.Set("bTimePos", "2")
f.Set("szOsdCamName", "Camera")
f.Set("u16PostAlarmBuf", "1")
f.Set("dwCameraId", "1") // Channel=1 => cameraID=0 and chanel=2 => cameraID=1
f.Set("LangCode", "undefined")
f.Set("Recflag", "0")
f.Set("submit", "Apply")
fBytes := []byte(f.Encode())
req, err := http.NewRequest("POST", settingsURL, bytes.NewReader(fBytes))
if err != nil {
return fmt.Errorf("could not create settings submit request: %v", err)
}
req.Header.Set("Connection", "keep-alive")
req.Header.Set("Content-Length", strconv.Itoa(len(fBytes)))
req.Header.Set("Cache-Control", "max-age=0")
req.Header.Set("Origin", "http://192.168.1.50")
req.Header.Set("Upgrade-Insecure-Requests", "1")
req.Header.Set("User-Agent", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36")
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
req.Header.Set("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3")
req.Header.Set("Referer", "http://192.168.1.50/ssi.cgi/VideoSettingSub.htm?cam=2")
req.Header.Set("Accept-Encoding", "gzip, deflate")
req.Header.Set("Accept-Language", "en-GB,en-US;q=0.9,en;q=0.8")
req.Header.Set("Cookie", "CLIENT_ID="+id)
// NB: not capturing error, as we always get one here for some reason.
// TODO: figure out why. Does not affect submission.
c.Do(req)
return nil
}