You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
410 lines
11 KiB
410 lines
11 KiB
6 years ago
|
package parser
|
||
|
|
||
|
import (
|
||
|
"bytes"
|
||
|
"encoding/binary"
|
||
|
"encoding/gob"
|
||
|
"encoding/hex"
|
||
|
"encoding/json"
|
||
|
"fmt"
|
||
|
"net/http"
|
||
|
"testing"
|
||
|
|
||
|
"github.com/ipsusila/opt"
|
||
|
|
||
|
"time"
|
||
|
|
||
|
"../model"
|
||
|
)
|
||
|
|
||
|
func TestCRC2(t *testing.T) {
|
||
|
pesan := ":t2005Custom Message\\: Hello Server$"
|
||
|
n := len(pesan)
|
||
|
npacket := n + 4
|
||
|
data := make([]byte, 8+n)
|
||
|
data[0] = byte(npacket >> 8)
|
||
|
data[1] = byte(npacket)
|
||
|
data[2] = 0x72
|
||
|
data[3] = 0x01 //PORT 'B'
|
||
|
data[4] = 0x00
|
||
|
data[5] = 0x00
|
||
|
|
||
|
payload := []byte(pesan)
|
||
|
p := data[6:]
|
||
|
copy(p, payload)
|
||
|
|
||
|
crc := crc16CCITT(data[2:(n + 6)])
|
||
|
data[n+6] = byte(crc >> 8)
|
||
|
data[n+7] = byte(crc)
|
||
|
|
||
|
fmt.Printf("Data: %X", data)
|
||
|
}
|
||
|
|
||
|
func TestCRC(t *testing.T) {
|
||
|
//data := []byte{0x00, 0x02, 0x64, 0x01, 0x13, 0xBC}
|
||
|
data := []byte{0x00, 0x05, 0x72, 0x01, 0x00, 0x00, 0x66, 0xC5, 0x44}
|
||
|
n1 := len(data)
|
||
|
|
||
|
//ini OK
|
||
|
d1 := data[2 : n1-2]
|
||
|
fmt.Printf("Data: %X\n", d1)
|
||
|
crc1 := crc16CCITT(d1)
|
||
|
|
||
|
//salah
|
||
|
d2 := data[0 : n1-2]
|
||
|
fmt.Printf("Data: %X\n", d2)
|
||
|
crc2 := crc16CCITT(d2)
|
||
|
|
||
|
//salah
|
||
|
d3 := data //[0 : n1-2]
|
||
|
fmt.Printf("Data: %X\n", d3)
|
||
|
crc3 := crc16CCITT(d3)
|
||
|
|
||
|
fmt.Printf("#ACK CRC=%X, %X %X\n", crc1, byte(crc1>>8), byte(crc1))
|
||
|
fmt.Printf("#ACK CRC=%X\n", crc2)
|
||
|
fmt.Printf("#ACK CRC=%X\n", crc3)
|
||
|
}
|
||
|
|
||
|
// func xxTestParser(t *testing.T) {
|
||
|
|
||
|
// //Parse data from DevicePrs manual
|
||
|
// var p model.Parser = NewDevicePrsStringParser(nil, nil,
|
||
|
// "033500000C076B5C208F01011E5268CEF20000196E3A3A0AEF3E934F3E2D780000000007000000005268CEFD0000196E3A3A0AEF3E934F3"+
|
||
|
// "E2D780000000007000000005268CF080000196E3A3A0AEF3E934F3E2D780000000007000000005268CF130000196E3A3A0AEF3E934F3E2D7"+
|
||
|
// "80000000007000000005268CF1E0000196E3A3A0AEF3E934F3E2D780000000007000000005268CF290000196E3A3A0AEF3E934F3E2D78000"+
|
||
|
// "0000007000000005268CF340000196E3A3A0AEF3E934F3E2D780000000007000000005268CF3F0000196E3A3A0AEF3E934F3E2D780000000"+
|
||
|
// "007000000005268CF4A0000196E3A3A0AEF3E934F3E2D780000000007000000005268CF550000196E3A3A0AEF3E934F3E2D7800000000070"+
|
||
|
// "00000005268CF600000196E3A3A0AEF3E934F3E2D780000000007000000005268CF6B0000196E3A3A0AEF3E934F3E2D78000000000700000"+
|
||
|
// "0005268CF730000196E36630AEF42CE4F6D0BF40400022208000000005268CF7E0000196E36B60AEF42BE4F6D0BF400000000070000000052"+
|
||
|
// "68CF890000196E36B60AEF42BE4F6D0BF40000000007000000005268CF940000196E36B60AEF42BE4F6D0BF40000000007000000005268CF"+
|
||
|
// "9F0000196E36B60AEF42BE4F6D0BF40000000007000000005268CFAA0000196E36B60AEF42BE4F6D0BF40000000007000000005268CFB50"+
|
||
|
// "000196E36B60AEF42BE4F6D0BF40000000007000000005268CFC00000196E36B60AEF42BE4F6D0BF40000000007000000005268CFCB00001"+
|
||
|
// "96E36B60AEF42BE4F6D0BF40000000007000000005268CFD60000196E36B60AEF42BE4F6D0BF40000000007000000005268CFD70000196E"+
|
||
|
// "3C710AEF5EFF4F690BF40400011708000000005268CFE20000196E3B980AEF601A4F690BF40000000007000000005268CFED0000196E3B980"+
|
||
|
// "AEF601A4F690BF40000000007000000005268CFF80000196E3B980AEF601A4F690BF40000000007000000005268D0030000196E3B980AEF60"+
|
||
|
// "1A4F690BF40000000007000000005268D00E0000196E3B980AEF601A4F690BF40000000007000000005268D0190000196E3B980AEF601A4F6"+
|
||
|
// "90BF40000000007000000005268D0240000196E3B980AEF601A4F690BF400000000070000000046E2")
|
||
|
|
||
|
// //convert string to binary HEX
|
||
|
// if p.GetError() != nil {
|
||
|
// t.Fatal(p.GetError())
|
||
|
// }
|
||
|
// pkt := p.GetRecords()
|
||
|
|
||
|
// //display packet as JSON
|
||
|
// b, err := json.Marshal(pkt)
|
||
|
// if err != nil {
|
||
|
// t.Fatal(err)
|
||
|
// }
|
||
|
// fmt.Println(string(b))
|
||
|
// // ---------------------------------------------------------
|
||
|
|
||
|
// data2, err2 := hex.DecodeString(
|
||
|
// "007900000b1a2a5585c30100024e9c036900000f101733208ff45e07b31b570a001009090605011b1a020003001c01ad01021d338e1600000" +
|
||
|
// "2960000601a41014bc16d004e9c038400000f104fdf20900d20075103b00a001308090605011b1a020003001c01ad01021d33b11600000296" +
|
||
|
// "0000601a41014bc1ea0028f9")
|
||
|
|
||
|
// //convert string to binary HEX
|
||
|
// if err2 != nil {
|
||
|
// t.Fatal(err2)
|
||
|
// }
|
||
|
// p = NewDevicePrsParser(nil, nil, data2)
|
||
|
// if p.GetError() != nil {
|
||
|
// t.Fatal(p.GetError())
|
||
|
// }
|
||
|
// pkt = p.GetRecords()
|
||
|
|
||
|
// //get response CRC
|
||
|
// rep := p.GetClientResponse()
|
||
|
// crc := crc16CCITT(rep[2 : len(rep)-2])
|
||
|
// fmt.Println("#ACK CRC=", crc)
|
||
|
|
||
|
// //display packet as JSON
|
||
|
// b, err = json.Marshal(pkt)
|
||
|
// if err != nil {
|
||
|
// t.Fatal(err)
|
||
|
// }
|
||
|
// origPkt := string(b)
|
||
|
// fmt.Println(origPkt)
|
||
|
|
||
|
// //test for map
|
||
|
// m := make(map[byte]int)
|
||
|
// m[0] = 10
|
||
|
// m[11] = 20
|
||
|
// m[2] = 30
|
||
|
|
||
|
// fmt.Println(m)
|
||
|
|
||
|
// ioM := new(model.IoMapResponse)
|
||
|
// ioM.Descriptor.IMEI = 10
|
||
|
// ioM.Descriptor.Id = 11
|
||
|
// ioM.Descriptor.Model = "ABC"
|
||
|
// ioM.Descriptor.QoS = 4
|
||
|
// ioM.DevTags = []model.DevTag{0, 1, 2, 3}
|
||
|
// ioM.StdTags = []model.StdTag{10, 11, 2, 4}
|
||
|
|
||
|
// b, err = json.Marshal(ioM)
|
||
|
// if err != nil {
|
||
|
// t.Fatal(err)
|
||
|
// }
|
||
|
// jstr := string(b)
|
||
|
// fmt.Println(jstr)
|
||
|
|
||
|
// var io2 model.IoMapResponse
|
||
|
// err = json.Unmarshal([]byte(jstr), &io2)
|
||
|
// fmt.Println(io2)
|
||
|
|
||
|
// var b1 byte = 200
|
||
|
// x := int8(b1)
|
||
|
// y := byte(x)
|
||
|
// fmt.Printf("%d -> %d -> %d\n", b1, x, y)
|
||
|
|
||
|
// by := data2[len(data2)-2:]
|
||
|
// fmt.Printf("Byte = %+v, %d\n", by, binary.BigEndian.Uint16(by))
|
||
|
|
||
|
// p = NewDevicePrsParser(nil, nil, []byte{})
|
||
|
// fmt.Println("Parser ", p)
|
||
|
|
||
|
// p = NewDevicePrsParser(nil, nil, nil)
|
||
|
// fmt.Println("Parser ", p)
|
||
|
// if p.GetError() != nil {
|
||
|
// fmt.Println(p.GetError())
|
||
|
// }
|
||
|
|
||
|
// rep = p.GetClientResponse()
|
||
|
// crc = crc16CCITT(rep[2 : len(rep)-2])
|
||
|
// fmt.Println("#NACK CRC=", crc)
|
||
|
|
||
|
// imei, cmd, _ := verifyStream(data2, p.GetMinPacketSize(), p.GetMaxPacketSize())
|
||
|
// fmt.Printf("IMEI = %X, cmd = %d\n", imei, cmd)
|
||
|
|
||
|
// //test encoding/decoding
|
||
|
// var network bytes.Buffer // Stand-in for a network connection
|
||
|
// enc := gob.NewEncoder(&network) // Will write to network.
|
||
|
// dec := gob.NewDecoder(&network) // Will read from network.
|
||
|
|
||
|
// // Encode (send) some values.
|
||
|
// err = enc.Encode(pkt)
|
||
|
// if err != nil {
|
||
|
// t.Fatal("encode error:", err)
|
||
|
// }
|
||
|
// //fmt.Printf("Buffer = %+v\n", network)
|
||
|
|
||
|
// // Decode (receive) and print the values.
|
||
|
// var dpkt model.DeviceRecords
|
||
|
// err = dec.Decode(&dpkt)
|
||
|
// if err != nil {
|
||
|
// t.Fatal("decode error 1:", err)
|
||
|
// }
|
||
|
// b, err = json.Marshal(&dpkt)
|
||
|
// decPkt := string(b)
|
||
|
// fmt.Printf("%+v\n", decPkt)
|
||
|
|
||
|
// if origPkt != decPkt {
|
||
|
// t.Fatal("Encode/Decode records doesnot match.")
|
||
|
// }
|
||
|
|
||
|
// //test original converter
|
||
|
// conv := model.RecordsConverter{}
|
||
|
// stream, err := conv.ToStream(pkt)
|
||
|
// if err != nil {
|
||
|
// t.Fatal("To stream error: ", err)
|
||
|
// }
|
||
|
// fmt.Printf("Stream length = %d bytes, orig = %d, json = %d\n",
|
||
|
// len(stream), len(data2), len(origPkt))
|
||
|
// //fmt.Printf("Stream = %+v\n", string(stream))
|
||
|
|
||
|
// pkt2, err := conv.FromStream(stream)
|
||
|
// if err != nil {
|
||
|
// t.Fatal("From stream error: ", err)
|
||
|
// }
|
||
|
|
||
|
// b, err = json.Marshal(&pkt2)
|
||
|
// decPkt2 := string(b)
|
||
|
// if origPkt != decPkt2 {
|
||
|
// t.Fatal("Encode/Decode records doesnot match.")
|
||
|
// }
|
||
|
// fmt.Printf("%+v\n", decPkt2)
|
||
|
|
||
|
// nack := []byte{0x00, 0x02, 0x64, 0x00, 0x02, 0x35}
|
||
|
// crc1 := crc16CCITT(nack[2 : len(nack)-2])
|
||
|
// fmt.Printf("CRC = %x\n", crc1)
|
||
|
|
||
|
// tsch := []byte{0x00, 0x05, 0x72, 0x01, 0x00, 0x00, 0x66, 0x19, 0xF0}
|
||
|
// crc1 = crc16CCITT(tsch[2 : len(tsch)-2])
|
||
|
// fmt.Printf("CRC = %x\n", crc1)
|
||
|
|
||
|
// str := hex.EncodeToString(tsch)
|
||
|
// fmt.Printf("Hex = %+v\n", str)
|
||
|
|
||
|
// data3, _ := hex.DecodeString(
|
||
|
// "0011000315A07F44865A0E01000053EA01DF65AD6D")
|
||
|
// crc1 = crc16CCITT(data3[2 : len(data3)-2])
|
||
|
// fmt.Printf("CRC = %x, %d, %d\n", crc1, len(data3), len(data2))
|
||
|
// }
|
||
|
|
||
|
func TestTch(t *testing.T) {
|
||
|
str := "0011000315A07F44865A0E01000053EA01DF65AD6D"
|
||
|
data, err := hex.DecodeString(str)
|
||
|
|
||
|
crc1 := crc16CCITT(data[2 : len(data)-2])
|
||
|
t.Logf("CRC = %X", crc1)
|
||
|
|
||
|
p := NewDevicePrsParser(nil, nil, data)
|
||
|
if p.Error != nil {
|
||
|
t.Errorf("Parser error: %v", p.Error)
|
||
|
t.FailNow()
|
||
|
}
|
||
|
|
||
|
t.Logf("IMEI=%v, command=%d", p.IMEI, p.Command)
|
||
|
t.Logf("Struct = %+v", p)
|
||
|
|
||
|
tch, err := parseTchStream(p.Data, p.MinPacketSize, p.MaxPacketSize)
|
||
|
if err != nil {
|
||
|
t.Errorf("Parse TCH error: %v", err)
|
||
|
t.FailNow()
|
||
|
}
|
||
|
|
||
|
t.Logf("TCH = %+v\n", tch)
|
||
|
t.Logf("Data = %v", string(tch.Data))
|
||
|
|
||
|
//test
|
||
|
pesan := ""
|
||
|
n := len(pesan)
|
||
|
|
||
|
//construct message
|
||
|
npacket := n + 4
|
||
|
data = make([]byte, 8+n)
|
||
|
data[0] = byte(npacket >> 8)
|
||
|
data[1] = byte(npacket)
|
||
|
data[2] = 0x72
|
||
|
data[3] = 0x01 //PORT 'B' (TODO: configurable)
|
||
|
data[4] = 0x00
|
||
|
data[5] = 0x00
|
||
|
|
||
|
//setup Payload
|
||
|
payload := []byte(pesan)
|
||
|
ptr := data[6:]
|
||
|
copy(ptr, payload)
|
||
|
|
||
|
//calculate CRC
|
||
|
crc := crc16CCITT(data[2:(n + 6)])
|
||
|
data[n+6] = byte(crc >> 8)
|
||
|
data[n+7] = byte(crc)
|
||
|
|
||
|
t.Logf("Data = %v\n", data)
|
||
|
}
|
||
|
|
||
|
func getJSON(url string, target interface{}) error {
|
||
|
restClient := &http.Client{Timeout: 10 * time.Second}
|
||
|
r, err := restClient.Get(url)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
defer r.Body.Close()
|
||
|
|
||
|
return json.NewDecoder(r.Body).Decode(target)
|
||
|
}
|
||
|
|
||
|
func TestJSON(t *testing.T) {
|
||
|
msg := &BroadcastMessage{}
|
||
|
imei := "868324028509698"
|
||
|
url := "http://202.47.70.196/oslog/api/BroadcastPrivate/getbroadcastmessage/" + imei
|
||
|
err := getJSON(url, msg)
|
||
|
if err != nil {
|
||
|
t.Errorf("Error get JSON: %v", err)
|
||
|
t.FailNow()
|
||
|
}
|
||
|
|
||
|
t.Logf("JSON = %+v", msg)
|
||
|
}
|
||
|
|
||
|
func TestOptions(t *testing.T) {
|
||
|
cfgText := `
|
||
|
{
|
||
|
server: {
|
||
|
id: conoco01
|
||
|
listenAddr: ":8081"
|
||
|
acceptTimeout: 10 # timeout (dalam detik)
|
||
|
writeTimeout: 10 # timeout (dalam detik)
|
||
|
maxReceive: 50
|
||
|
maxSend: 50
|
||
|
device: ruptela
|
||
|
}
|
||
|
|
||
|
ruptela: {
|
||
|
message: "http://localhost:8081/api/"
|
||
|
report: "http://localhost:8081/reportAPI"
|
||
|
appendIMEI: false
|
||
|
serviceTimeout: 10 # REST Service timeout (dalam detik)
|
||
|
}
|
||
|
|
||
|
gpsdata: {
|
||
|
storage: sql
|
||
|
sql: {
|
||
|
driver: postgres
|
||
|
connection: "user=isi-user password=isi-password dbname=OSLOGREC_MTRACK host=127.0.0.1 port=5432 connect_timeout=30 sslmode=disable"
|
||
|
maxIdle: 10 #Max jumlah koneksi idle
|
||
|
maxOpen: 10 #Max jumlah koneksi open
|
||
|
maxLifetime: 60 #Maximum lifetime (dalam detik)
|
||
|
insertQuery: INSERT INTO "GPS_DATA"("IMEI", "DATA_LOG", "FLAG", "DATE_INS", "DESC", "GPS_CODE", "DATA_LEN") VALUES($1, $2, $3, $4, $5, $6, $7)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
log: {
|
||
|
#Known types: console, file, sql
|
||
|
type: console, file, sql
|
||
|
console: {
|
||
|
# use default options
|
||
|
}
|
||
|
|
||
|
|
||
|
#for file (uncomment type)
|
||
|
# type: file
|
||
|
file: {
|
||
|
name: ./applog.log
|
||
|
append: true
|
||
|
}
|
||
|
|
||
|
#for sql (uncomment type)
|
||
|
# SQLite -> driver: sqlite3
|
||
|
# PostgreSQL -> driver: postgres
|
||
|
# type: sql
|
||
|
sql: {
|
||
|
driver: sqlite3
|
||
|
connection: ./applog.sqlite
|
||
|
maxIdle: 10 #Max jumlah koneksi idle
|
||
|
maxOpen: 10 #Max jumlah koneksi open
|
||
|
maxLifetime: 60 #Maximum lifetime (dalam detik)
|
||
|
createQuery: CREATE TABLE applog(id INTEGER PRIMARY KEY AUTOINCREMENT, ts DATETIME, app VARCHAR(100), content TEXT)
|
||
|
insertQuery: INSERT INTO applog(ts, app, content) VALUES(?, ?, ?)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
`
|
||
|
|
||
|
options, err := opt.FromText(cfgText, "hjson")
|
||
|
if err != nil {
|
||
|
t.Error(err)
|
||
|
t.FailNow()
|
||
|
}
|
||
|
|
||
|
t.Logf("%+v", options)
|
||
|
|
||
|
now := time.Now().Format(timeLayout)
|
||
|
nowLocal := time.Now().Local().Format(timeLayout)
|
||
|
t.Logf("Now= %v, local= %v\n", now, nowLocal)
|
||
|
|
||
|
//test container
|
||
|
/*
|
||
|
c1, key := options.GetContainer("server")
|
||
|
t.Logf("Key = %s, Server = %+v", key, c1)
|
||
|
|
||
|
c2, key := options.GetContainer("server.id")
|
||
|
t.Logf("Key = %s, Server.id = %+v", key, c2)
|
||
|
|
||
|
c3, key := options.GetContainer("log.sql")
|
||
|
t.Logf("Key = %s, Log.sql = %+v", key, c3)
|
||
|
*/
|
||
|
}
|