JavaLikeCalc.JavaScript
//Protocol NIK 2303
io.setAttr("err", "0");

SN = io.attr("SN").toInt();
cli = 0x21;
trm1 = (SN>>20)&0xFE;
trm2 = (SN>>13)&0xFE;
dnum1 = (SN>>6)&0xFE;;
dnum2 = ((SN&0x3FFF)<<1)-(dnum1<<7)+1;
//Message creation
if(!io.text().length) request = SYS.strFromCharCode(0xA0, 10, trm1, trm2, dnum1, dnum2, cli, io.attr("cntr"));
else {
	title = SYS.strFromCharCode(0xA0, io.text().length +12, trm1, trm2, dnum1, dnum2, cli, io.attr("cntr"));
	// Check for HCS
	for(HCS = 0xFFFF, i = 0; i < title.length; i++) {
		b = 0;
		for (j = 0; j<8; j++){				//byte reversion
			bit = (title.charCodeAt(i)&(1<<j))>>j;
			b = b |( bit << (8 - j - 1));
		} 
		for(j = 0; j < 8; j++, b = b << 1)		//HCS calculation
			HCS = ((b^(HCS>>8)&0x80)?(HCS<<1)^0x1021:HCS<<1) & 0xFFFF;
	}
	HCS = HCS ^ 0xFFFF; // HCS*HOR
	rev = 0;					// HCS reversion
	for (i = 0; i<16; i++){
		bit = (HCS&(1<<i))>>i;
		rev = rev |( bit << (16 - i - 1));
	} 
	HCS = rev;
	request = title + SYS.strFromCharCode(HCS&0xFF, (HCS>>8)&0xFF)+ io.text();
}
// Check for FCS
for(FCS = 0xFFFF, i = 0; i < request.length; i++) {
	b = 0;
	for (j = 0; j<8; j++){				//byte reversion
		bit = (request.charCodeAt(i)&(1<<j))>>j;
		b = b |( bit << (8 - j - 1));
	} 
	for(j = 0; j < 8; j++, b = b << 1)		//CRC calculation
		FCS = ((b^(FCS>>8)&0x80)?(FCS<<1)^0x1021:FCS<<1) & 0xFFFF;
}
FCS = FCS ^ 0xFFFF; // FCS*HOR
rev = 0;			// FCS reversion
for (i = 0; i<16; i++){
	bit = (FCS&(1<<i))>>i;
	rev = rev |( bit << (16 - i - 1));
} 
FCS = rev;
request = SYS.strFromCharCode(0x7E) + request + SYS.strFromCharCode(FCS&0xFF, (FCS>>8)&0xFF, 0x7E);
//SYS.messDebug("/NIK2303I/PRT", "Request: "+SYS.strDecode(request, "Bin","|"));


//message sending
resp = tr.messIO(request);
while(resp.length && resp.charCodeAt(resp.length-1) != 0x7E)
	if((tresp=tr.messIO("")).length) resp += tresp;
	else break;
if(resp.length == 0) {io.setText(""); io.setAttr("err","1:"+tr("No a respond")); return; }
//SYS.messDebug("/NIK2303I/PRT", "Respond: "+SYS.strDecode(resp, "Bin","|"));
if(resp.length <= 3 || resp.charCodeAt(2) != resp.length-2)
{ io.setAttr("err","3:"+tr("Respond too short or wrong")); return; }
// Remove markers
resp = resp.slice(1, resp.length-1);
// Check for FCS
for(FCS = 0xFFFF, i = 0; i < resp.length-2; i++) {
	b = 0;
	for (j = 0; j<8; j++){				//byte reversion
		bit = (resp.charCodeAt(i)&(1<<j))>>j;
		b = b |( bit << (8 - j - 1));
	} 
	for(j = 0; j < 8; j++, b = b << 1)		//FCS calculation
		FCS = ((b^(FCS>>8)&0x80)?(FCS<<1)^0x1021:FCS<<1) & 0xFFFF;
}

FCS = FCS ^ 0xFFFF; // FCS*HOR
rev = 0;			// FCS reversion
for (i = 0; i<16; i++){
	bit = (FCS&(1<<i))>>i;
	rev = rev |( bit << (16 - i - 1));
} 
FCS = rev;
if(FCS != ((resp.charCodeAt(resp.length-1)<<8)+ resp.charCodeAt(resp.length-2))) {
	io.setAttr("err", "11:"+tr("Error FCS."));
	return;
}
io.setText(resp.slice(10,resp.length-2));
io.setAttr("cntr", resp[7]);
io.setAttr("err", "0");