class: title, smokescreen, shelf, bottom, no-footer background-image: url(https://www.geeksforgeeks.org/wp-content/uploads/2-14.png) # 181U Spring 2020 ## Framing Protocols <style> h1 { border-bottom: 8px solid rgb(32,67,143); border-radius: 2px; width: 90%; } .smokescreen h1 { border-bottom: none; } .small {font-size: 80%} .smaller {font-size: 70%} .small-code.remark-slide-content.compact code {font-size:1.0rem} .very-small-code.remark-slide-content.compact code {font-size:0.9rem} .line-numbers{ /* Set "line-numbers-counter" to 0 */ counter-reset: line-numbers-counter; } .line-numbers .remark-code-line::before { /* Increment "line-numbers-counter" by 1 */ counter-increment: line-numbers-counter; content: counter(line-numbers-counter); text-align: right; width: 20px; border-right: 1px solid #aaa; display: inline-block; margin-right: 10px; padding: 0 5px; } </style> --- layout: true .footer[ - 181U - See acknowledgements ] --- class: compact # Agenda * Point-to-point encoding * clock recovery * Framing * Character Count * Byte stuffing * Bit stuffing * SLIP * Efficient byte stuffing --- class: compact # Direct Links * We need to understand how "reliable" transmission can be implemented * Issues to consider * Encoding -- how data are transmitted across a link * Framing -- how to send blocks of data across point-to-point link * Error detection -- how to determine if an error has occurred --- class: compact # Encoding  * Signals travel between signalling components * Bits flow between adaptors   * Problems with NRZ * Long strings of 1's cause DC offset of signal * Clock recovery -- how do we know where the bits are ? --- class: compact # Low-level Hardware protocols have separate clock * SPI   * I2C   --- class: compact # Clock Recovery * Protocols such as UART assume "synchronized" clocks at sender/receiver * At high data rates this is a technical challenge * There is per-byte overhead of 2.5/8 percent   --- class: compact # High Speed Protocols Encode the Clock in the Data  * Manchester Encoding guarantees at least one edge per bit -- but it doubles the datat rate - notice that 0 is encoded as a low-high transition, 1 is encoded as a high-low transition * Clock is recovered with a phase locked-loop   --- class: compact # 4B/5B: Encode clock in data with smaller overhead  * 4B/5B Solves inefficiency of Manchester Encoding while remaining (more) balanced. Every 5 bits encode 4 bits of data. Every *legal* code has no more than one leading 0 and no more than two trailing 0's * Some reserved codes * 00000 -- line is dead * 11111 -- line is idle * 00100 -- halt * 8B/10B is a similar id. Used in DAT digital audio recorder, Fibre Channel * 64B/66B used in 10Gbit Ethernet --- class: compact # Framing  We'll consider two different approaches: 1. Byte-oriented protocols (PPP) - framing is handled by inserting distinguished bytes in sequence to identify start/end of a frame - only suitable for encodings that are byte-oriented 2. Bit-oriented protocols (HDLC) - distinguished bit patterns inserted in data to identify start/end frame Fibre standards use yet another approach. 3. Clock-based Framing (SONET) Typically framing protocols also include basic error detection --- class: compact # Byte-Oriented Framing There are three approaches: 1. Add a length field (character count) 1. Use special characters to mark the beginning and end of frame 2. Use a byte count at beginning of frame (this is more error prone) IBM Binary Synchronous Communication (BISYNC) * Mark beginning of frame with SYN character * "Escape" SYN characters by preceding them with DLE character * "Escape" DLE character with another DLS character. --- class: compact # Character Count * Field in header gives number of characters in frame   * (b) illustrates the problem -- if a transmission error changes the count, all the frames are out of sync https://www.computing.dcu.ie/~humphrys/Notes/Networks/data.framing.html --- class: compact # Byte-Oriented Framing (PPP)  * The start-of-text character (FLAG) is 01111110. * Protocol used for demultiplexing link (IP is distinguished) * Checksum (really a CRC code) used to validate frame * Payload is 1500 bytes by default. --- class: compact # Byte Stuffing   https://www.computing.dcu.ie/~humphrys/Notes/Networks/data.framing.html * What if the flag is in the data ? Insert a special escape byte (ESC) before each flag. * What if the ESC is in the data ? Insert another ESC before it --- class: compact # SLIP * SLIP is a "non-standard" standard that uses byte-stuffing for frames and is easily implementd * [RFC 1055](https://tools.ietf.org/html/rfc1055) ```plaintext SLIP has its origins in the 3COM UNET TCP/IP implementation from the early 1980's. It is merely a packet framing protocol: SLIP defines a sequence of characters that frame IP packets on a serial line, and nothing more. It provides no addressing, packet type identification, error detection/correction or compression mechanisms. Because the protocol does so little, though, it is usually very easy to implement. ``` --- class: very-small-code,compact,hljs-tomorrow-night-eighties,line-numbers # SLIP Transmitter ```C #define END 0300 /* indicates end of packet */ #define ESC 0333 /* indicates byte stuffing */ #define ESC_END 0334 /* ESC ESC_END means END data byte */ #define ESC_ESC 0335 /* ESC ESC_ESC means ESC data byte */ void send_packet(p, len) { char *p; int len; send_char(END); // clear channel while(len--) { switch(*p) case END: // END must be escaped send_char(ESC); send_char(ESC_END); break; case ESC: // ESC must be Escaped send_char(ESC); send_char(ESC_ESC); break; default: send_char(*p); } p++; } send_char(END); } ``` --- class: very-small-code,compact,hljs-tomorrow-night-eighties,line-numbers # SLIP Receiver ```C int recv_packet(p, len) { char *p; int len; { char c; int received = 0; while(1) { c = recv_char(); switch(c) { case END: return received; case ESC: c = recv_char(); switch(c) { case ESC_END: c = END; break; case ESC_ESC: c = ESC; break; } default: if(received < len) p[received++] = c; } } } ``` --- class: compact # Efficient Byte Stuffing * In the worst case, byte stuffing has 100% overhead * Consistent overhead byte stuffing addresses this issue [paper](http://www.stuartcheshire.org/papers/COBSforToN.pdf) * COBS guarantees at most one extra byte of overhead per 254 bytes. * Like normal byte stuffing, COBS performs a reversible tranformation on a data packet to eliminate a single value from the packet - in the following, 0 is chosen as the distinguished byte. --- class: compact # COBS algorithm * COBS appends a single 0 byte to the data * COBS finds all the 0 bytes and divides the packet at these boundaries -- every chunk has a single 0 byte at the end. (some chunks only have one byte -- 0) * COBS encodes each chunk (breaking chunks longer than 254 bytes) and prepends the chunk with a one-byte code | Code | Followed by | Meaning | |------|-------------|---------| | 0x00 | N/A | Not allowed | | 0x01 | no data bytes | a single zero byte | | n | (n-1) data bytes | (n-1) data bytes followed by a 0 | | 0xFF | 254 data bytes | 254 data bytes not followd by a zero --- class: compact # COBS Example     --- class: compact # COBS Performance   --- class: compact # COBS Three Day Data Trace   --- class: compact # Bit-oriented framing (HDLC)  * Not concerned with byte boundaries * Distinguished sequence 01111110 * Uses "bit-stuffing" to break up sequences of 6 1's --- class: compact # Bit Stuffing   * Each frame begins with 01111110 (6 ones) * Anytime there are 5 ones in a row -- stuff an extra 0 after the fifth one https://www.computing.dcu.ie/~humphrys/Notes/Networks/data.framing.html --- class: compact # Error Detection There are many techniques. Two common ones are * Checksum * add up the words being transmitted and transmit the sum * relatively weak protection * Cyclic redundancy code (CRC) * Uses a polynomial to generate error code * 32-bit CRC gives reasonably strong protection for common bit errors --- class: compact # Checksum Calculation * Internet checksum uses 1's complement arithmetic (bitwise not) ```C u_short cksum(u_short *buf, int count){ register u_long sum = 0; while (count--){ sum += *buf++; if (sum & 0xFFFF0000){ /* carry occurred, so wrap around */ sum &= 0xFFFF; sum++; } } return ~(sum & 0xFFFF); } ``` --- class: compact # CRC  * Computes a code by "dividing" data with a fixed polynomial * Well chosen polynomials protect against long strings of bit errors (the most common type) * Example Polynomial: 1101 (1^3 + 1^2 + 1^0) * Message: 1001101 * Extended Message: 10011010000 * Transmitted message : 10011010101 (Extended message ^ remainder) * Received message is correct if remainder from division is zero * CRC is easy to calculate in hardware ! --- class: compact # Summary * Framing * Error Detection * Acknowledgements * Content and images from http://book.systemsapproach.org * Cover image https://www.geeksforgeeks.org/wp-content/uploads/2-14.png * PLL diagram By <a href="//commons.wikimedia.org/wiki/User:Krishnavedala" title="User:Krishnavedala">Krishnavedala</a> - <span class="int-own-work" lang="en">Own work</span>, <a href="http://creativecommons.org/publicdomain/zero/1.0/deed.en" title="Creative Commons Zero, Public Domain Dedication">CC0</a>, <a href="https://commons.wikimedia.org/w/index.php?curid=64092961">Link</a>