Code to perform SLIP Protocol

Posted on
  • Slip1.js 26 Aug 2016
    A program to send and receive data packets in SLIP format.
    Written for a PICO
    https://en.wikipedia.org/wiki/Serial_Lin­e_Internet_Protocol

    //slip1.js
    //26 Aug 2016
    //Written on a PICO
    //For testing connect Tx to RX for loopback, pins B6 and B7 Serial1
    
    //SLIP protocol
    // https://en.wikipedia.org/wiki/Serial_Lin­e_Internet_Protocol
    var END=0xC0;
    var ESC=0xdb;
    var ESC_END=0xdc;
    var ESC_ESC=0xdd;
    
    // END+Packet+END
    //if the END byte occurs in the data to be sent, the two byte sequence
    // ESC, ESC_END is sent instead,
    //if the ESC byte occurs in the data, the two byte sequence ESC, ESC_ESC // is sent.
    
    var baudrate=115200;
    var Port=Serial1;
    //Port.setup(baudrate);
    
    function Packet(){
     this.A="";
    }
    
    var P=new Packet();
    
    P.on('data',function(data){
     console.log("P.on= "+data);
    });
    
    //var sss="";
    var State=0;
    
    Port.on('data', function (data){
     var i;
     console.log("Port.on= "+data);
     for(i=0;i<data.length;i++){
      switch(State){
       case 0://looking for END to start packet
    //console.log("0");
        if(data.charCodeAt(i)===END){
         State=10;
         i++;
        }
       return;
       case 10://get the packet
    //console.log("10");
        if(data.charCodeAt(i)===END){
         State=0;
         P.emit('data',P.A);
         i++;
         return;
        }
        State=20;
       return;
       case 20://look for ESC
    //console.log("20");
       if(data.charCodeAt(i)===ESC){State=30;i+­+;return;}
        P.A+=data.charAt(i);
        State=10;
       return;
       case 30://ESC was seen
    //console.log("30");
        if(data.charCodeAt(i)===ESC_END){
         P.A+=String.fromCharCode(END);
         State=10;
         return;
        }
        if(data.charCodeAt(i)===ESC_ESC){
         P.A+=String.fromCharCode(ESC);
         State=10;
         return;
        }
       return;
       default:
        console.log("default error");
       break;
      }//end switch
     }//next i
    });
    
    
    function sendEND(){
     Port.write(String.fromCharCode(END));
    }
    
    function sendESC(){
     Port.write(String.fromCharCode(ESC));
    }
    
    function sendESC_END(){
     Port.write(String.fromCharCode(ESC_END))­;
    }
    
    function sendESC_ESC(){
     Port.write(String.fromCharCode(ESC_ESC))­;
    }
    
    function sendPacket(A){
     var i;
     sendEND();
      for(i=0;i<A.length;i++){
       switch(A.charCodeAt(i)){
        case END:
         sendESC();
         sendESC_END();
        break;
        case ESC:
         sendESC();
         sendESC_ESC();
        break;
        default:
         Port.write(A.charAt(i));
        break;
       }//end switch
      }//next i
     sendEND();
    }
    
    function test(){
     var text=
      "Hello"+String.fromCharCode(ESC)+"World"­+String.fromCharCode(END)+
       "Eagles";
     Port.setup(baudrate);
     console.log("Text= "+text);
     sendPacket(text);
      
    }//end test
    test();
    

    The output:

    >echo(0);
    Text= HelloÛWorldÀEagles
    =undefined
    Port.on= ÀHelloÛÝWorldÛÜEaglesÀ
    P.on= HelloÛWorldÀEagles
    

    1 Attachment

  • Slip3.js 27 Aug 2016
    The previous code is reworked into an object named Slip.
    The Serial.on('data') can then invoke the parsing of data in the Slip object.
    As characters are parsed in the Slip object, the emit() function is used to forward data to a new Slip.on('data') function. Try the example at different baud rates. The code follows:

    //slip3.js
    //26 Aug 2016
    //Written on a PICO
    //For testing connect Tx to RX for loopback, pins B6 and B7 Serial1
    
    
    //SLIP protocol
    // https://en.wikipedia.org/wiki/Serial_Lin­e_Internet_Protocol
    var END="\xC0";
    var ESC="\xdb";
    var ESC_END="\xdc";
    var ESC_ESC="\xdd";
    
    // END+Packet+END
    //if the END byte occurs in the data to be sent, the two byte sequence
    // ESC, ESC_END is sent instead,
    //if the ESC byte occurs in the data, the two byte sequence ESC, ESC_ESC // is sent.
    
    
    function Slip(port){
    // this.sss="";
     this.State=0;
     this.Port=port;
     this.sendEND=function(){this.Port.write(­END);};
     this.sendESC=function(){this.Port.write(­ESC);};
     this.sendESC_END=function(){this.Port.wr­ite(ESC_END);};
     this.sendESC_ESC=function(){this.Port.wr­ite(ESC_ESC);};
    
    }
    
    Slip.prototype.sendPacket=function(A){
     var i;
     this.sendEND();
      for(i=0;i<A.length;i++){
       switch(A.charAt(i)){
        case END:
         this.sendESC();
         this.sendESC_END();
        break;
        case ESC:
         this.sendESC();
         this.sendESC_ESC();
        break;
        default:
         this.Port.write(A.charAt(i));
        break;
       }//end switch
      }//next i
     this.sendEND();
    };
    
    
    Slip.prototype.parsnip=function(data){
     var i;
     console.log("Port.on= "+data);console.log(" ");
     for(i=0;i<data.length;i++){
      switch(this.State){
       case 0://looking for END to start packet
    //console.log("0");
        if(data.charAt(i)===END){
         //this.sss="";
         this.State=10;
         i++;
        }
       return;
       case 10://get the packet
    //console.log("10");
        if(data.charAt(i)===END){
         this.State=0;
         return;
        }
        this.State=20;
       return;
       case 20://look for ESC
    //console.log("20");
       if(data.charAt(i)===ESC){this.State=30;r­eturn;}
        this.emit('data',data.charAt(i));
        this.State=10;
       return;
       case 30://ESC was seen
    //console.log("30");
        if(data.charAt(i)===ESC_END){
         this.emit('data',END);
         this.State=10;
         return;
        }
        if(data.charAt(i)===ESC_ESC){
         this.emit('data',ESC);
         this.State=10;
         return;
        }
       return;
       default:
        console.log("default error");
       break;
      }//end switch
     }//next i
    };
    
    ///////////////////////////
    function test(){
     var Port=Serial1;
    //var Port=Serial2;
    //try different baud rates 300, 1200,9600,19200,115200
     var Baudrate=115200;
    ///////////////////
     var P=new Slip(Port);
     Port.setup(Baudrate);
    
     Port.on('data', function (data){
      P.parsnip(data);
     });
    
    //add sss and i properties to the P instance of Slip
     P.sss="";
     P.i=0;
     P.on('data',function(data){
      P.sss+=data;
       for(P.i=0;P.i<data.length;P.i++){
        if(data.charAt(P.i)==='\r'){
         print(P.sss);P.sss="";
        }
       }
     });
    
     var text="Hello"+ESC+"World"+END+"Eagles\n\r­";
     var text1="Sally\n\r";
     var text2="Mary Lamb\n\r";
     console.log("Text= "+text);
     P.sendPacket(text);
     console.log("Text1= "+text1);
     P.sendPacket(text1);
     console.log("Text2 "+text2);
     P.sendPacket(text2);
    }//end test
    
    test();
    

    The output:

    >echo(0);
    Text= HelloÛWorldÀEagles
    Text1= Sally
    Text2 Mary Lamb
    =undefined
    Port.on= ÀHelloÛÝWorldÛÜEagles
    ÀÀSally
    ÀÀMary Lamb
    À
     
    HelloÛWorldÀEagles
    Sally
    Mary Lamb
    
  • Great! So what actually are these packets? Are they actually at the socket level (so TCP/IP is already done) or are they below, so you'd have to implement a TCP/IP library?

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

Code to perform SLIP Protocol

Posted by Avatar for ClearMemory041063 @ClearMemory041063

Actions