Е не е истина просто :) . Пиша протоколен стек за протокол, които едва познавам, на език от който пък си нямам грам представа :)

Задачата е да се четат пакети на MAC ниво и да се извлекат данни, които са капсулирани във два вложени един над друг протоколи :) . И тва на JavaScript . Мъкааа , мъка . Абе май вложените протоколи са повечко : Powerline във RS323 във IP . Както се вика три в едно :)

Трябва малко пояснение : Благодарение на ето този пост. започнах работа във една фирма за домашна автоматизация. Всъщност малко е сложно – фирмата тепърва мисли да се занимава с това, като ще продават и внедряват продуктите на една друга фирма . Другата фирма пък иска да интерфейсне системата си към едни дистанционни на Филипс (там всъщност ще се изпълнява JavaScript-a) .

Всъщност, докато преговаряхме, изобщо не стана дума за програмиране ( аз щях да откажа, щото хм…. ) , пък и видях, че търсеха и програмист отделно, но някак си тоя товар с JavaScript-а дойде на мой гръб. Но твърдо смятам това да са последните редове код, които пиша на тоя хм … т.нар.  език.

Та ето какво сътворих дотук . Има още работа, но общи линии кода работи. Добре, че Филипс бяха написали наготово TCP клиент ( на JavaScript , хехе)

System.setDebugMask(9) ;

var testFrame =
“\x55\xC1\xF0\x01\x00\x00\x5A\x00\x00\x10\x0B\x40\x08\xB0\x06\x5A\xA0\x0B\x00\x00\x00\x0B\x00

\x00\x10\x00\x00\x00\xA0\x0D\x00\x00\xC0\x08\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x06

\x00\x00\x40\x07\x00\x00\x10\x0E\x00\x00\xC0\x00\x00\x00\x40\x00\x00\x00\x00\x01\x00\x00\x10

\x04\x00\x00\x30\x03\x00\x00\xD0\x0B\x10\x00\xAA”;

eval(CF.widget(“TCPCLIENT”, “SCRIPTS”).label);
var wSTATE_VALUE1 = widget(“STATE_VALUE1”);
var trace = com.philips.trace;
var traceHex = com.philips.traceHex;

var Delimiter = “\xAA”;
var IP = CF.widget(“IP”, “PARAMETERS”).label;
var Port = CF.widget(“PORT”, “PARAMETERS”).label;
intervalTMP = 500; //parseInt(CF.widget(“UPDATE”, “PARAMETERS”).label, 10);
var updateInterval = intervalTMP > 100 ? intervalTMP:intervalTMP*1000;
var Client = null;
var timeStamp = new Date();
var AWAKENING_SAFETY_TIMEOUT = 5000;

// test na simulatora , da se mahne w krajnija wariant
processPacket(testFrame);

function processPacket(data)
{
var obj ; // za da definiram obekt, trjabwa da se def funkcia, oba4e kakwa ?, zasega karame samo s promenivi
traceHex(data, 500); // tuk polu4avame celiq paket
var interface_code = (data.charCodeAt(2) | data.charCodeAt(3));
System.print(“Iface Code: ” + interface_code.toString(16));
var service_selector = (data.charCodeAt(4) | data.charCodeAt(5));
System.print(“Service_sel: ” + service_selector);
// only if 0xF1 interface AND SERVICE SELECTOR = 0 , else discard packet
if( interface_code == 241 && service_selector == 0 )
{
var index = data.lastIndexOf(‘\x5A’);
index++ ;
var field2 = data.substring(index);
index=16; // first address byte
var Addr = (field2.charCodeAt(index) | field2.charCodeAt(index+1));
System.print(“Address: ” + Addr.toString(16));
index=index+16 ; //HEADER
var header = (field2.charCodeAt(index) | field2.charCodeAt(index+1));
System.print(“Header: ” + header.toString(16));
var suaPresent = header & 3; // HEADER AND 11
var ssua = 0;
switch(suaPresent)
{
case 0 : { index=index+4; ssua = (field2.charCodeAt(index) | field2.charCodeAt(index+1)); index=index+4;break;}
case 1 : {index=index+4; break;}
case 2 : {index=index+4; break;}
}
System.print(“SSUA: ” + ssua.toString(16));
index = index + 12; //SERVICE
var service = (field2.charCodeAt(index) | field2.charCodeAt(index+1));
System.print(“Service: : ” + service.toString(16));
if (service == 64 || service == 32 ) // if service = 0x40 (READ) = 0x20(INF. REPORT), else discard packet
{
index = index+4; // first byte of DATA_LENGHT
var data_lenght = (field2.charCodeAt(index) | field2.charCodeAt(index+1));
System.print(“Data_lenght: ” + data_lenght);
index = index+4; // first byte of DATA

var obj_data=””; //APPLICATION_DATA

//READ APPLICATION_DATA +++++ PROBLEM S STRINGA ++++++ SOLVED ++++
while(data_lenght)
{
//System.print(“iteration: ” + data_lenght);
obj_data += String.fromCharCode(field2.charCodeAt(index) | field2.charCodeAt(index+1));
index=index+4;
data_lenght–;
}

traceHex(obj_data);
System.print(“Data : ” + obj_data);
updateScreen(Addr,obj_data);
}
}
}

function ioError()
{
Diagnostics.log(“io error”);
}

Client = new com.philips.TCPClient(processPacket, ioError, Delimiter, IP, Port);
//enableMAC();
//requestStatus();

function enableMAC()
{
trace(“Request enable MAC”);
Client.execute(“\x55\xE0\xF0\x00\x00\x00\xAA”);
}

function requestStatus()
{

Client.execute(“\x55\xE0\x80\x08\x00\x00\x00\x07\x40\x00\x00\x00\x00\x00\x10\x0E\xC0\x00\x40\x00\x00\x00”);
Client.execute(“”);
Client.execute(“”);
Client.execute(“\x5A\xC0\x08”); // tuk individualen adres
Client.execute(“\x5A\x00\x01\x5A\x00\x00\x5A\xA0\x0B\x00\x0B\x5A\x10\x00\xAA”);

System.delay(140);

// REPEAT FOR ALL ADDRESSES

}

function keepAlive()
{
var tmpTime = new Date();
var interval = tmpTime – timeStamp;
if ( interval > (updateInterval + AWAKENING_SAFETY_TIMEOUT))
{
//In this case the Pronto comes out of sleep and a sync function will have to be called
trace(tmpTime + ” – ” + timeStamp + ” = ” + interval);
trace(“perodic request! ” + interval);
requestStatus();
}
timeStamp = tmpTime;
scheduleAfter(updateInterval, keepAlive);
}

function updateScreen(adr,val)
{

System.print(“Data_len: ” + val.length);
if(val.length == 1) //INDIVIDUAL RESPONSE
{
System.print(“Data 2 : ” + val.charCodeAt(0));
switch(adr)
{
case 200 : { wSTATE_VALUE1.label = val.charCodeAt(0) + ” %” ; return;}
//case adr2: {wSTATE2_VALUE.label = val ; return;}
//case adr3: {wSTATE3_VALUE.label = val ; return;}
//case adr4: {wSTATE4_VALUE.label = val ; return;}
}

} else

{
//group request response – data >1 , ne se znae kakwo

}

}