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.
409 lines
11 KiB
409 lines
11 KiB
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) |
|
*/ |
|
}
|
|
|