UNPKG

packet_device

Version:

`packet_device` is a Node.js library for secure, packetized communication with microcontrollers (Arduino, ESP32, etc.) running the [Packet Device Arduino library](https://github.com/Pallob-Gain/packet_device).

135 lines (109 loc) 5.15 kB
//Packet Details header: <[]-[]*[]-[]> const PACKET_SIGNETURE_DATA_LEN = 4; const PACKET_SIGNETURE_LEN = 9; const packet_maker=Buffer.from('<-*->'); const packet_info = Buffer.from([packet_maker[0], 0x0F,packet_maker[1], 0x0F, packet_maker[2], 0x0F, packet_maker[3], 0x0F, packet_maker[4]]); //packet length signeture module.exports = class DataEndPusherExtractor { delimiter; packet_length = 0; packet_timeout_at = null; store_buff; constructor(delimiter = '\r\n') { this.delimiter = delimiter; this.store_buff = Buffer.from(''); } clear() { this.store_buff = Buffer.from(''); } getPacketLength(transfer_buff) { if (transfer_buff[0] != packet_info[0] || transfer_buff[PACKET_SIGNETURE_LEN - 1] != packet_info[PACKET_SIGNETURE_LEN - 1]) return 0; let packet_size = 0; for (let i = 1; i < (PACKET_SIGNETURE_LEN - 1); i++) { if (packet_info[i] == 0x0F) { //data if (transfer_buff[i] > 0x0F) { //if segment is invalid return 0; } packet_size = (packet_size << 4) | transfer_buff[i]; } else if (packet_info[i] != transfer_buff[i]) { //format is not matching return 0; } } return packet_size; } updatePacketLength(packet_size) { let header=Buffer.alloc(PACKET_SIGNETURE_LEN); packet_info.copy(header); //console.log(packet_size); // //{ (packet_size & 0xF000) >> 12, (packet_size & 0x0F00) >> 8, (packet_size & 0x00F0) >> 4, packet_size & 0x000F } for (let i = 0; i < PACKET_SIGNETURE_DATA_LEN; i++) { header[(i * 2) + 1] = (packet_size >> (12 - (i * 4))) & 0x0F; //console.log((i * 2) + 1,header[(i * 2) + 1],(12 - (i * 4))); } return header; } searchPacketMatch(transfer_buffer){ let search_offset=0; while(transfer_buffer.length>search_offset){ let sfind = transfer_buffer.indexOf(packet_info[0], search_offset); if(sfind==-1 || (sfind+PACKET_SIGNETURE_LEN)>transfer_buffer.length)return null; search_offset=sfind+PACKET_SIGNETURE_LEN; let packet_size=this.getPacketLength(transfer_buffer.subarray(sfind,search_offset)); if(packet_size!==0){ return [search_offset,packet_size]; } } return null; } readData() { let packets = []; if (this.packet_timeout_at !== null && this.packet_length !== 0 && Date.now() > this.packet_timeout_at) { this.packet_length = 0; this.packet_timeout_at = null; } let offset = 0; // let checker=0; while (this.store_buff.length > offset) { if (this.packet_length !== 0) { if ((this.store_buff.length - offset) >= this.packet_length) { packets.push(Buffer.from(this.store_buff.subarray(offset, offset + this.packet_length))); //taking a new copy offset = offset + this.packet_length; this.packet_length = 0; //reset this.packet_timeout_at = null; //reset timeout } else break; ///there has no enough data, and need to wait for next data update } else { if ((this.store_buff.length - offset) >= PACKET_SIGNETURE_LEN) { let search_result=this.searchPacketMatch(this.store_buff.subarray(offset,this.store_buff.length)); if(search_result!==null){ let [packet_end,packet_size]=search_result; offset = offset + packet_end; //increasing offset this.packet_length = packet_size; this.packet_timeout_at = Date.now() + (packet_size * 2) + 100; //minimum baud rate could 4800bps that mean 600bytes for second, considering 2ms for each of byte, and some extra delay (100ms) continue; } } let find = this.store_buff.indexOf(this.delimiter, offset); if (find == -1) break; //there has no enough data packets.push(Buffer.from(this.store_buff.subarray(offset, find))); //taking a new copy offset = find + this.delimiter.length; } } if (offset !== 0) { //remove unnessary buffer this.store_buff = Buffer.from(this.store_buff.subarray(offset, this.store_buff.length)); //creating a new copy and destoring old one } return packets; } pushOut(data) { //console.log('push out'); this.store_buff = Buffer.concat([this.store_buff, data]); let packets = this.readData(); //console.log('push end'); if (packets.length == 0) return null; return packets; } }