qmkenc/qmk-cmd.go

313 lines
6.2 KiB
Go

package qmkenc
import (
"encoding/binary"
"fmt"
)
var magicHeader = []byte{0x03, 0xFF}
type QEncCmd byte
const (
QENC_CMD_RESET QEncCmd = 0x00
QENC_CMD_ENCRYPT QEncCmd = 0x01
QENC_CMD_DECRYPT QEncCmd = 0x02
QENC_CMD_MORE_DATA QEncCmd = 0x03
QENC_CMD_UNLOCK QEncCmd = 0x04
QENC_CMD_LOCK QEncCmd = 0x05
QENC_CMD_SET_CFG QEncCmd = 0x06
QENC_CMD_GET_MODE QEncCmd = 0x07
QENC_CMD_GET_BUFFER QEncCmd = 0x08
QENC_CMD_GET_KEYS QEncCmd = 0x09
QENC_CMD_GET_BUFFSIZE QEncCmd = 0x0A
QENC_CMD_SET_KEYS QEncCmd = 0x0B
QENC_CMD_GET_CFG QEncCmd = 0x0C
QENC_CMD_INITIALIZE QEncCmd = 0x0D
)
type QEncMode byte
const (
QENC_MODE_CLOSED QEncMode = 0x00
QENC_MODE_OPEN QEncMode = 0x01
QENC_MODE_LOAD QEncMode = 0x02
QENC_MODE_INIT QEncMode = 0x03
)
type QEncSubMode byte
const (
QENC_SUB_MODE_NONE QEncSubMode = 0x00
QENC_SUB_MODE_SEED QEncSubMode = 0x01
QENC_SUB_MODE_PASSWORD QEncSubMode = 0x02
QENC_SUB_MODE_VERIFY_PASSWORD QEncSubMode = 0x03
)
type QEncCfg byte
const (
QENC_CFG_PARANOIA QEncCfg = 0x00
QENC_CFG_SECURE QEncCfg = 0x01
QENC_CFG_MAX_ERROR QEncCfg = 0x02
QENC_CFG_TIMEOUT QEncCfg = 0x03
)
type QCfg struct {
val []byte
}
func (q *QCfg) MaxError() int {
return int(q.val[0])
}
func (q *QCfg) ErrorCount() int {
return int(q.val[1])
}
func (q *QCfg) ParanoiaMode() bool {
if q.val[2] == 0 {
return false
}
return true
}
func (q *QCfg) SecureMode() bool {
if q.val[3] == 0 {
return false
}
return true
}
func (q *QCfg) Timeout() int {
return int(q.val[4])
}
func (q *QCfg) Initialized() bool {
if q.val[5] == 0 {
return false
}
return true
}
func QCmdReset(dev *QEncDevice) (err error) {
buf, err := initBuffer(dev, QENC_CMD_RESET)
if err != nil {
return err
}
_, err = dev.SendBuffer(buf)
return err
}
func QCmdUnlock(dev *QEncDevice) (err error) {
buf, err := initBuffer(dev, QENC_CMD_UNLOCK)
if err != nil {
return err
}
_, err = dev.SendBuffer(buf)
return err
}
func QCmdLock(dev *QEncDevice) (err error) {
buf, err := initBuffer(dev, QENC_CMD_LOCK)
if err != nil {
return err
}
_, err = dev.SendBuffer(buf)
return err
}
func QCmdInitialize(dev *QEncDevice) (err error) {
buf, err := initBuffer(dev, QENC_CMD_INITIALIZE)
if err != nil {
return err
}
_, err = dev.SendBuffer(buf)
return err
}
func QCmdEncrypt(dev *QEncDevice, data []byte) (err error) {
return sendData(dev, data, QENC_CMD_ENCRYPT)
}
func QCmdDecrypt(dev *QEncDevice, data []byte) (err error) {
return sendData(dev, data, QENC_CMD_DECRYPT)
}
func QCmdGetMode(dev *QEncDevice) (retm QEncMode, retsm QEncSubMode, err error) {
buf, err := initBuffer(dev, QENC_CMD_GET_MODE)
if err != nil {
return retm, retsm, err
}
rbuf, err := dev.SendBuffer(buf)
if err != nil {
return retm, retsm, err
}
dataLen := binary.LittleEndian.Uint16(rbuf)
if int(dataLen) != 2 {
return retm, retsm, fmt.Errorf("Invalid data")
}
retm = QEncMode(rbuf[3])
retsm = QEncSubMode(rbuf[4])
return retm, retsm, nil
}
func QCmdSetCfgParanoia(dev *QEncDevice) (err error) {
return setCfg(dev, QENC_CFG_PARANOIA, 1)
}
func QCmdSetCfgSecure(dev *QEncDevice, val bool) (err error) {
if val {
return setCfg(dev, QENC_CFG_SECURE, 1)
}
return setCfg(dev, QENC_CFG_SECURE, 0)
}
func QCmdSetCfgMaxError(dev *QEncDevice, val uint8) (err error) {
if val < 0 || val > 15 {
return fmt.Errorf("Invalid value")
}
return setCfg(dev, QENC_CFG_MAX_ERROR, val)
}
func QCmdSetCfgTimeout(dev *QEncDevice, val uint8) (err error) {
if val < 0 || val > 50 {
return fmt.Errorf("Invalid value")
}
return setCfg(dev, QENC_CFG_TIMEOUT, val)
}
func QCmdGetBuffer(dev *QEncDevice) (ret []byte, err error) {
return receiveData(dev, QENC_CMD_GET_BUFFER)
}
func QCmdGetKeys(dev *QEncDevice) (ret []byte, err error) {
return receiveData(dev, QENC_CMD_GET_KEYS)
}
func QCmdSetKeys(dev *QEncDevice, data []byte) (err error) {
return sendData(dev, data, QENC_CMD_SET_KEYS)
}
func QCmdGetCfg(dev *QEncDevice) (ret *QCfg, err error) {
buf, err := initBuffer(dev, QENC_CMD_GET_CFG)
if err != nil {
return ret, err
}
rbuf, err := dev.SendBuffer(buf)
if err != nil {
return ret, err
}
dataLen := binary.LittleEndian.Uint16(rbuf)
if int(dataLen) != 6 {
return ret, fmt.Errorf("Invalid data")
}
ret = &QCfg{}
ret.val = make([]byte, 6)
copy(ret.val, rbuf[3:3+dataLen])
return ret, nil
}
func setCfg(dev *QEncDevice, cfg QEncCfg, val uint8) (err error) {
buf, err := initBuffer(dev, QENC_CMD_SET_CFG)
if err != nil {
return err
}
binary.LittleEndian.PutUint16(buf[3:], uint16(2))
buf[5] = byte(cfg)
buf[6] = val
if _, err = dev.SendBuffer(buf); err != nil {
return err
}
return nil
}
func sendData(dev *QEncDevice, data []byte, cmd QEncCmd) (err error) {
buf, err := initBuffer(dev, cmd)
if err != nil {
return err
}
dataLen := len(data)
binary.LittleEndian.PutUint16(buf[3:], uint16(dataLen))
if dataLen <= (int(dev.GetBufSize()) - 5) {
copy(buf[5:], data)
if _, err = dev.SendBuffer(buf); err != nil {
return err
}
return nil
}
dataPos := 0
copy(buf[5:], data[:dev.GetBufSize()-5])
if _, err := dev.SendBuffer(buf); err != nil {
return err
}
dataPos += int(dev.GetBufSize()) - 5
buf[2] = byte(QENC_CMD_MORE_DATA)
for {
copy(buf[3:], data[dataPos:])
if _, err := dev.SendBuffer(buf); err != nil {
return nil
}
if (dataLen - dataPos) <= (int(dev.GetBufSize()) - 3) {
return nil
}
dataPos += int(dev.GetBufSize()) - 3
}
}
func receiveData(dev *QEncDevice, cmd QEncCmd) (ret []byte, err error) {
buf, err := initBuffer(dev, cmd)
if err != nil {
return ret, err
}
for {
rbuf, err := dev.SendBuffer(buf)
if err != nil {
return ret, err
}
if rbuf[0] == 1 {
dataLen := binary.LittleEndian.Uint16(rbuf[1:3])
if int(dataLen) > int(dev.GetBufSize())-3 {
return ret, fmt.Errorf("Invalid data")
}
b := make([]byte, dataLen)
copy(b, rbuf[3:])
ret = append(ret, b...)
return ret, nil
}
ret = append(ret, rbuf[1:]...)
}
}
func initBuffer(dev *QEncDevice, cmd QEncCmd) (ret []byte, err error) {
ret = make([]byte, dev.GetBufSize())
if copy(ret, magicHeader) != 2 {
return ret, fmt.Errorf("Invalid magic Header")
}
ret[2] = byte(cmd)
return ret, nil
}