We are trying to code GPS device listener on Javascript.
While doing this, we are unable to develop the right script for the CRC-ITU error check. The explanation for
The ~
in the original code only worked because it was a 16-bit type. You should use crcX = crcX ^ 0xffff
instead of crcX = ~crcX
.
Also your buf.substring(i,i+4)
and i = i + 4
is wrong. You need to process one byte at a time, which is two hexadecimal digits. Those should both be i+2
.
This is my code
var net = require('net');
var HOST = '192.168.1.151';
var PORT = 5023;
function protocall_decorder(data,sbit,plength,protono,ebit){
// Login data
if(plength.toString('hex') == '0d') {
var ret = crc16Ccitt(data.slice(2,14));
var err_code = ret;
console.log(err_code.toString(16));
plength = new Buffer('05','hex');
var res = sbit + plength + protono + data.slice(12,14) + err_code.toString(16) + ebit;
data = "device_imei: " + parseInt(data.slice(4,12).toString('hex'));
console.log(data);
res = new Buffer(res)
var dataArr = {response:res, type:"login", data:data};
}
/*
// Location data
else if(plength == '1F') {
var res = '787805' + ***** + data.slice(60,64) + data.slice(24,28) +'D9DC' + '0D0A';
dataArr = data.substring(2);
}
// Alarm data
else if(plength == '25') {
dataArr = data.substring(2);
}
// Heart Beat
else if(plength == '08') {
dataArr = data.substring(2);
}
// Undefined data length
*/
else {
var dataArr = {response:"error", data:plength};
}
return dataArr;
}
// The sock object the callback function receives UNIQUE for each connection
net.createServer(function(sock) {
// We have a connection - a socket object is assigned to the connection automatically
console.log('CONNECTED: ' + sock.remoteAddress +':'+ sock.remotePort);
// Add a 'data' event handler to this instance of socket
sock.on('data', function(data) {
console.log('DATA ' + sock.remoteAddress + ': ' + data);
// Write the data back to the socket, the client will receive it as data from the server
//////////////// MySQL | Begin ////////////////////
var mysql = require('mysql');
var con = mysql.createConnection({
host : 'localhost',
user : 'root',
password : 'lahirutm',
database : 'gt06n'
});
con.connect();
var sbit = data.slice(0,2);
var plength = data.slice(2,3);
var protono = data.slice(3,4);
var ebit = data.slice(-2)
if(sbit.toString('hex') == '7878') {
var res = protocall_decorder(data,sbit,plength,protono,ebit);
if(res['response'] != 'error') {
sock.write(res['response']);
var response = res['response'];
}
}
else {
console.log('Undefined protocol data');
}
console.log(response); // Write data to socket
var message = {start_bit: sbit, packet_length: plength, proto_no: protono, serial:'*', end_bit: ebit};
var query = con.query('INSERT INTO incoming_data SET ?', message,
//var message = {data: data}
//var query = con.query('INSERT INTO row_data SET ?', message,
function(err, result) {
// Neat!
});
console.log(query.sql);
var message = {data: data}
var query = con.query('INSERT INTO row_data SET ?', message,
function(err, result) {
// Neat!
});
console.log(query.sql);
con.end();
/////////////// MySQL | Begin ////////////////
});
// Add a 'close' event handler to this instance of socket
sock.on('close', function(data) {
console.log('CLOSED: ' + sock.remoteAddress +' '+ sock.remotePort);
});
}).listen(PORT, HOST);
console.log('Server listening on ' + HOST +':'+ PORT);
/**
* CRC functions
*/
var crc16CcittTableReverse = [
0x0000, 0x1189, 0x2312, 0x329B, 0x4624, 0x57AD, 0x6536, 0x74BF,
0x8C48, 0x9DC1, 0xAF5A, 0xBED3, 0xCA6C, 0xDBE5, 0xE97E, 0xF8F7,
0x1081, 0x0108, 0x3393, 0x221A, 0x56A5, 0x472C, 0x75B7, 0x643E,
0x9CC9, 0x8D40, 0xBFDB, 0xAE52, 0xDAED, 0xCB64, 0xF9FF, 0xE876,
0x2102, 0x308B, 0x0210, 0x1399, 0x6726, 0x76AF, 0x4434, 0x55BD,
0xAD4A, 0xBCC3, 0x8E58, 0x9FD1, 0xEB6E, 0xFAE7, 0xC87C, 0xD9F5,
0x3183, 0x200A, 0x1291, 0x0318, 0x77A7, 0x662E, 0x54B5, 0x453C,
0xBDCB, 0xAC42, 0x9ED9, 0x8F50, 0xFBEF, 0xEA66, 0xD8FD, 0xC974,
0x4204, 0x538D, 0x6116, 0x709F, 0x0420, 0x15A9, 0x2732, 0x36BB,
0xCE4C, 0xDFC5, 0xED5E, 0xFCD7, 0x8868, 0x99E1, 0xAB7A, 0xBAF3,
0x5285, 0x430C, 0x7197, 0x601E, 0x14A1, 0x0528, 0x37B3, 0x263A,
0xDECD, 0xCF44, 0xFDDF, 0xEC56, 0x98E9, 0x8960, 0xBBFB, 0xAA72,
0x6306, 0x728F, 0x4014, 0x519D, 0x2522, 0x34AB, 0x0630, 0x17B9,
0xEF4E, 0xFEC7, 0xCC5C, 0xDDD5, 0xA96A, 0xB8E3, 0x8A78, 0x9BF1,
0x7387, 0x620E, 0x5095, 0x411C, 0x35A3, 0x242A, 0x16B1, 0x0738,
0xFFCF, 0xEE46, 0xDCDD, 0xCD54, 0xB9EB, 0xA862, 0x9AF9, 0x8B70,
0x8408, 0x9581, 0xA71A, 0xB693, 0xC22C, 0xD3A5, 0xE13E, 0xF0B7,
0x0840, 0x19C9, 0x2B52, 0x3ADB, 0x4E64, 0x5FED, 0x6D76, 0x7CFF,
0x9489, 0x8500, 0xB79B, 0xA612, 0xD2AD, 0xC324, 0xF1BF, 0xE036,
0x18C1, 0x0948, 0x3BD3, 0x2A5A, 0x5EE5, 0x4F6C, 0x7DF7, 0x6C7E,
0xA50A, 0xB483, 0x8618, 0x9791, 0xE32E, 0xF2A7, 0xC03C, 0xD1B5,
0x2942, 0x38CB, 0x0A50, 0x1BD9, 0x6F66, 0x7EEF, 0x4C74, 0x5DFD,
0xB58B, 0xA402, 0x9699, 0x8710, 0xF3AF, 0xE226, 0xD0BD, 0xC134,
0x39C3, 0x284A, 0x1AD1, 0x0B58, 0x7FE7, 0x6E6E, 0x5CF5, 0x4D7C,
0xC60C, 0xD785, 0xE51E, 0xF497, 0x8028, 0x91A1, 0xA33A, 0xB2B3,
0x4A44, 0x5BCD, 0x6956, 0x78DF, 0x0C60, 0x1DE9, 0x2F72, 0x3EFB,
0xD68D, 0xC704, 0xF59F, 0xE416, 0x90A9, 0x8120, 0xB3BB, 0xA232,
0x5AC5, 0x4B4C, 0x79D7, 0x685E, 0x1CE1, 0x0D68, 0x3FF3, 0x2E7A,
0xE70E, 0xF687, 0xC41C, 0xD595, 0xA12A, 0xB0A3, 0x8238, 0x93B1,
0x6B46, 0x7ACF, 0x4854, 0x59DD, 0x2D62, 0x3CEB, 0x0E70, 0x1FF9,
0xF78F, 0xE606, 0xD49D, 0xC514, 0xB1AB, 0xA022, 0x92B9, 0x8330,
0x7BC7, 0x6A4E, 0x58D5, 0x495C, 0x3DE3, 0x2C6A, 0x1EF1, 0x0F78
];
var crc16CcittStart = 0xFFFF;
var crc16CcittXorout = 0xFFFF;
function crc16Reflected(buf, crc_in, table) {
var crc16 = crc_in;
for (i = 0; i < buf.length; i++) {
crc16 = table[(crc16 ^ buf[i]) & 0xff] ^ (crc16 >> 8);
}
return crc16 & 0xFFFF;
}
function crc16Ccitt(buf) {
return crc16Reflected(buf, crc16CcittStart, crc16CcittTableReverse) ^ crc16CcittXorout;
}
Found very few links on CRC 16 calculation but found the current answer in javascript helpful.
In case anyone is looking for the same CRC 16 calculation using python, have created the public gist along with working python fiddle example:
https://gist.github.com/mrudang-vora/6a0767be085a275c0df3
Hope it helps someone.
In case of using java
public static void main(String[] args) {
String sample_string ="78 78 0D 01 01 23 45 67 89 01 23 45 00 01 8C DD 0D
0A";
String[] data_packet = packet.split(" ");
String[] pdata = Arrays.copyOfRange(data_packet, 2, data_packet.length - 4);
//pdata will be from "packet-length" to "Information Serial Nummber"
//discarding "start-bit" from start and "Error-check" and "Stop Bit" from end
//actual pdata[]={0D,01,01,23,45,67,89,01,23,45,00,01};
String error_code = crc16(pdata);
System.out.println("================>Error_code:" + error_code);
}
public String crc16(String[] pdata) {
int[] crcTable
= {
0X0000, 0X1189, 0X2312, 0X329B, 0X4624, 0X57AD, 0X6536, 0X74BF, 0X8C48, 0X9DC1, 0XAF5A,
0XBED3, 0XCA6C, 0XDBE5, 0XE97E, 0XF8F7, 0X1081, 0X0108, 0X3393, 0X221A, 0X56A5, 0X472C,
0X75B7, 0X643E, 0X9CC9, 0X8D40, 0XBFDB, 0XAE52, 0XDAED, 0XCB64, 0XF9FF, 0XE876, 0X2102,
0X308B, 0X0210, 0X1399, 0X6726, 0X76AF, 0X4434, 0X55BD, 0XAD4A, 0XBCC3, 0X8E58, 0X9FD1,
0XEB6E, 0XFAE7, 0XC87C, 0XD9F5, 0X3183, 0X200A, 0X1291, 0X0318, 0X77A7, 0X662E, 0X54B5,
0X453C, 0XBDCB, 0XAC42, 0X9ED9, 0X8F50, 0XFBEF, 0XEA66, 0XD8FD, 0XC974, 0X4204, 0X538D,
0X6116, 0X709F, 0X0420, 0X15A9, 0X2732, 0X36BB, 0XCE4C, 0XDFC5, 0XED5E, 0XFCD7, 0X8868,
0X99E1, 0XAB7A, 0XBAF3, 0X5285, 0X430C, 0X7197, 0X601E, 0X14A1, 0X0528, 0X37B3, 0X263A,
0XDECD, 0XCF44, 0XFDDF, 0XEC56, 0X98E9, 0X8960, 0XBBFB, 0XAA72, 0X6306, 0X728F, 0X4014,
0X519D, 0X2522, 0X34AB, 0X0630, 0X17B9, 0XEF4E, 0XFEC7, 0XCC5C, 0XDDD5, 0XA96A, 0XB8E3,
0X8A78, 0X9BF1, 0X7387, 0X620E, 0X5095, 0X411C, 0X35A3, 0X242A, 0X16B1, 0X0738, 0XFFCF,
0XEE46, 0XDCDD, 0XCD54, 0XB9EB, 0XA862, 0X9AF9, 0X8B70, 0X8408, 0X9581, 0XA71A, 0XB693,
0XC22C, 0XD3A5, 0XE13E, 0XF0B7, 0X0840, 0X19C9, 0X2B52, 0X3ADB, 0X4E64, 0X5FED, 0X6D76,
0X7CFF, 0X9489, 0X8500, 0XB79B, 0XA612, 0XD2AD, 0XC324, 0XF1BF, 0XE036, 0X18C1, 0X0948,
0X3BD3, 0X2A5A, 0X5EE5, 0X4F6C, 0X7DF7, 0X6C7E, 0XA50A, 0XB483, 0X8618, 0X9791, 0XE32E,
0XF2A7, 0XC03C, 0XD1B5, 0X2942, 0X38CB, 0X0A50, 0X1BD9, 0X6F66, 0X7EEF, 0X4C74, 0X5DFD,
0XB58B, 0XA402, 0X9699, 0X8710, 0XF3AF, 0XE226, 0XD0BD, 0XC134, 0X39C3, 0X284A, 0X1AD1,
0X0B58, 0X7FE7, 0X6E6E, 0X5CF5, 0X4D7C, 0XC60C, 0XD785, 0XE51E, 0XF497, 0X8028, 0X91A1,
0XA33A, 0XB2B3, 0X4A44, 0X5BCD, 0X6956, 0X78DF, 0X0C60, 0X1DE9, 0X2F72, 0X3EFB, 0XD68D,
0XC704, 0XF59F, 0XE416, 0X90A9, 0X8120, 0XB3BB, 0XA232, 0X5AC5, 0X4B4C, 0X79D7, 0X685E,
0X1CE1, 0X0D68, 0X3FF3, 0X2E7A, 0XE70E, 0XF687, 0XC41C, 0XD595, 0XA12A, 0XB0A3, 0X8238,
0X93B1, 0X6B46, 0X7ACF, 0X4854, 0X59DD, 0X2D62, 0X3CEB, 0X0E70, 0X1FF9, 0XF78F, 0XE606,
0XD49D, 0XC514, 0XB1AB, 0XA022, 0X92B9, 0X8330, 0X7BC7, 0X6A4E, 0X58D5, 0X495C, 0X3DE3,
0X2C6A, 0X1EF1, 0X0F78
};
int crcX = 0xFFFF;
int cr1 = 0xFF;
int cr2 = 0xFFFF;
int i = 0;
int j;
while (i < pdata.length) {
String str = pdata[i];
int str_hex = Integer.parseInt(str, 16);
j = (crcX ^ str_hex) & cr1;
crcX = (crcX >> 8) ^ crcTable[j];
i++;
}
There are some crc
packages on npm
, but they may not work for you, I create a new one that is just a copy of c
code from your link to document.
Install crc-itu
from terminal:
npm install crc-itu
app.js
var crc16 = require('crc-itu').crc16;
var crcInHex = crc16('0d0103588990501766460026', 'hex').toString(16);
console.log(crcInHex); // will print 7bf9
you can also try with these values, note: crc16(data).toString(16) => crc
start data crc end
-------------------------------------------
7878 0d0103588990501766460026 7bf9 0d0a
7878 0d010358899050176646002a b195 0d0a
7878 0d010358899050176646002b a01c 0d0a