├── CRC16_CCITT.cpp ├── CRC16_CCITT.h ├── CRC32.cpp ├── CRC32.h ├── HDLC.h ├── HDLC_TL1B.h ├── HDLC_TL3B_TOKEN.h ├── README.md └── doc ├── LICENSE └── rfc1662.txt /CRC16_CCITT.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 Djones A. Boni 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include "CRC16_CCITT.h" 18 | 19 | PROGMEM const CRC16_CCITT::CRC_t CRC16_CCITT::CRC_TAB[256U] = { 20 | 0x0000UL, 0x1189UL, 0x2312UL, 0x329BUL, 0x4624UL, 0x57ADUL, 0x6536UL, 0x74BFUL, 21 | 0x8C48UL, 0x9DC1UL, 0xAF5AUL, 0xBED3UL, 0xCA6CUL, 0xDBE5UL, 0xE97EUL, 0xF8F7UL, 22 | 0x1081UL, 0x0108UL, 0x3393UL, 0x221AUL, 0x56A5UL, 0x472CUL, 0x75B7UL, 0x643EUL, 23 | 0x9CC9UL, 0x8D40UL, 0xBFDBUL, 0xAE52UL, 0xDAEDUL, 0xCB64UL, 0xF9FFUL, 0xE876UL, 24 | 0x2102UL, 0x308BUL, 0x0210UL, 0x1399UL, 0x6726UL, 0x76AFUL, 0x4434UL, 0x55BDUL, 25 | 0xAD4AUL, 0xBCC3UL, 0x8E58UL, 0x9FD1UL, 0xEB6EUL, 0xFAE7UL, 0xC87CUL, 0xD9F5UL, 26 | 0x3183UL, 0x200AUL, 0x1291UL, 0x0318UL, 0x77A7UL, 0x662EUL, 0x54B5UL, 0x453CUL, 27 | 0xBDCBUL, 0xAC42UL, 0x9ED9UL, 0x8F50UL, 0xFBEFUL, 0xEA66UL, 0xD8FDUL, 0xC974UL, 28 | 0x4204UL, 0x538DUL, 0x6116UL, 0x709FUL, 0x0420UL, 0x15A9UL, 0x2732UL, 0x36BBUL, 29 | 0xCE4CUL, 0xDFC5UL, 0xED5EUL, 0xFCD7UL, 0x8868UL, 0x99E1UL, 0xAB7AUL, 0xBAF3UL, 30 | 0x5285UL, 0x430CUL, 0x7197UL, 0x601EUL, 0x14A1UL, 0x0528UL, 0x37B3UL, 0x263AUL, 31 | 0xDECDUL, 0xCF44UL, 0xFDDFUL, 0xEC56UL, 0x98E9UL, 0x8960UL, 0xBBFBUL, 0xAA72UL, 32 | 0x6306UL, 0x728FUL, 0x4014UL, 0x519DUL, 0x2522UL, 0x34ABUL, 0x0630UL, 0x17B9UL, 33 | 0xEF4EUL, 0xFEC7UL, 0xCC5CUL, 0xDDD5UL, 0xA96AUL, 0xB8E3UL, 0x8A78UL, 0x9BF1UL, 34 | 0x7387UL, 0x620EUL, 0x5095UL, 0x411CUL, 0x35A3UL, 0x242AUL, 0x16B1UL, 0x0738UL, 35 | 0xFFCFUL, 0xEE46UL, 0xDCDDUL, 0xCD54UL, 0xB9EBUL, 0xA862UL, 0x9AF9UL, 0x8B70UL, 36 | 0x8408UL, 0x9581UL, 0xA71AUL, 0xB693UL, 0xC22CUL, 0xD3A5UL, 0xE13EUL, 0xF0B7UL, 37 | 0x0840UL, 0x19C9UL, 0x2B52UL, 0x3ADBUL, 0x4E64UL, 0x5FEDUL, 0x6D76UL, 0x7CFFUL, 38 | 0x9489UL, 0x8500UL, 0xB79BUL, 0xA612UL, 0xD2ADUL, 0xC324UL, 0xF1BFUL, 0xE036UL, 39 | 0x18C1UL, 0x0948UL, 0x3BD3UL, 0x2A5AUL, 0x5EE5UL, 0x4F6CUL, 0x7DF7UL, 0x6C7EUL, 40 | 0xA50AUL, 0xB483UL, 0x8618UL, 0x9791UL, 0xE32EUL, 0xF2A7UL, 0xC03CUL, 0xD1B5UL, 41 | 0x2942UL, 0x38CBUL, 0x0A50UL, 0x1BD9UL, 0x6F66UL, 0x7EEFUL, 0x4C74UL, 0x5DFDUL, 42 | 0xB58BUL, 0xA402UL, 0x9699UL, 0x8710UL, 0xF3AFUL, 0xE226UL, 0xD0BDUL, 0xC134UL, 43 | 0x39C3UL, 0x284AUL, 0x1AD1UL, 0x0B58UL, 0x7FE7UL, 0x6E6EUL, 0x5CF5UL, 0x4D7CUL, 44 | 0xC60CUL, 0xD785UL, 0xE51EUL, 0xF497UL, 0x8028UL, 0x91A1UL, 0xA33AUL, 0xB2B3UL, 45 | 0x4A44UL, 0x5BCDUL, 0x6956UL, 0x78DFUL, 0x0C60UL, 0x1DE9UL, 0x2F72UL, 0x3EFBUL, 46 | 0xD68DUL, 0xC704UL, 0xF59FUL, 0xE416UL, 0x90A9UL, 0x8120UL, 0xB3BBUL, 0xA232UL, 47 | 0x5AC5UL, 0x4B4CUL, 0x79D7UL, 0x685EUL, 0x1CE1UL, 0x0D68UL, 0x3FF3UL, 0x2E7AUL, 48 | 0xE70EUL, 0xF687UL, 0xC41CUL, 0xD595UL, 0xA12AUL, 0xB0A3UL, 0x8238UL, 0x93B1UL, 49 | 0x6B46UL, 0x7ACFUL, 0x4854UL, 0x59DDUL, 0x2D62UL, 0x3CEBUL, 0x0E70UL, 0x1FF9UL, 50 | 0xF78FUL, 0xE606UL, 0xD49DUL, 0xC514UL, 0xB1ABUL, 0xA022UL, 0x92B9UL, 0x8330UL, 51 | 0x7BC7UL, 0x6A4EUL, 0x58D5UL, 0x495CUL, 0x3DE3UL, 0x2C6AUL, 0x1EF1UL, 0x0F78UL 52 | }; 53 | -------------------------------------------------------------------------------- /CRC16_CCITT.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 Djones A. Boni 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #ifndef CRC16_CCITT_H_ 18 | #define CRC16_CCITT_H_ 19 | 20 | #include 21 | #include 22 | 23 | struct CRC16_CCITT { 24 | typedef uint16_t CRC_t; 25 | static const int8_t size = 2; 26 | static const CRC_t CRC_INIT = 0xFFFFU; 27 | static const CRC_t CRC_FINALXOR = 0xFFFFU; 28 | static const CRC_t CRC_GOOD = 0xF0B8U; 29 | 30 | PROGMEM static const CRC_t CRC_TAB[256U]; 31 | 32 | void init() { crc = CRC_INIT; } 33 | void update(uint8_t data) { 34 | /* crc = (crc >> 8U) ^ CRC_TAB[(crc ^ data) & 0xFFU]; */ 35 | crc = (crc >> 8U) ^ pgm_read_word(&CRC_TAB[(crc ^ data) & 0xFFU]); 36 | } 37 | 38 | bool good() { return crc == CRC_GOOD; } 39 | 40 | void final() { crc ^= CRC_FINALXOR; } 41 | uint8_t operator[](int8_t pos) { 42 | switch(pos) { 43 | case 0: return crc; 44 | default: return crc >> 8U; 45 | } 46 | } 47 | 48 | CRC_t crc; 49 | }; 50 | 51 | #endif /* CRC16_CCITT_H_ */ 52 | -------------------------------------------------------------------------------- /CRC32.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 Djones A. Boni 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include "CRC32.h" 18 | 19 | PROGMEM const CRC32::CRC_t CRC32::CRC_TAB[256U] = { 20 | 0x00000000UL, 0x77073096UL, 0xEE0E612CUL, 0x990951BAUL, 21 | 0x076DC419UL, 0x706AF48FUL, 0xE963A535UL, 0x9E6495A3UL, 22 | 0x0EDB8832UL, 0x79DCB8A4UL, 0xE0D5E91EUL, 0x97D2D988UL, 23 | 0x09B64C2BUL, 0x7EB17CBDUL, 0xE7B82D07UL, 0x90BF1D91UL, 24 | 0x1DB71064UL, 0x6AB020F2UL, 0xF3B97148UL, 0x84BE41DEUL, 25 | 0x1ADAD47DUL, 0x6DDDE4EBUL, 0xF4D4B551UL, 0x83D385C7UL, 26 | 0x136C9856UL, 0x646BA8C0UL, 0xFD62F97AUL, 0x8A65C9ECUL, 27 | 0x14015C4FUL, 0x63066CD9UL, 0xFA0F3D63UL, 0x8D080DF5UL, 28 | 0x3B6E20C8UL, 0x4C69105EUL, 0xD56041E4UL, 0xA2677172UL, 29 | 0x3C03E4D1UL, 0x4B04D447UL, 0xD20D85FDUL, 0xA50AB56BUL, 30 | 0x35B5A8FAUL, 0x42B2986CUL, 0xDBBBC9D6UL, 0xACBCF940UL, 31 | 0x32D86CE3UL, 0x45DF5C75UL, 0xDCD60DCFUL, 0xABD13D59UL, 32 | 0x26D930ACUL, 0x51DE003AUL, 0xC8D75180UL, 0xBFD06116UL, 33 | 0x21B4F4B5UL, 0x56B3C423UL, 0xCFBA9599UL, 0xB8BDA50FUL, 34 | 0x2802B89EUL, 0x5F058808UL, 0xC60CD9B2UL, 0xB10BE924UL, 35 | 0x2F6F7C87UL, 0x58684C11UL, 0xC1611DABUL, 0xB6662D3DUL, 36 | 0x76DC4190UL, 0x01DB7106UL, 0x98D220BCUL, 0xEFD5102AUL, 37 | 0x71B18589UL, 0x06B6B51FUL, 0x9FBFE4A5UL, 0xE8B8D433UL, 38 | 0x7807C9A2UL, 0x0F00F934UL, 0x9609A88EUL, 0xE10E9818UL, 39 | 0x7F6A0DBBUL, 0x086D3D2DUL, 0x91646C97UL, 0xE6635C01UL, 40 | 0x6B6B51F4UL, 0x1C6C6162UL, 0x856530D8UL, 0xF262004EUL, 41 | 0x6C0695EDUL, 0x1B01A57BUL, 0x8208F4C1UL, 0xF50FC457UL, 42 | 0x65B0D9C6UL, 0x12B7E950UL, 0x8BBEB8EAUL, 0xFCB9887CUL, 43 | 0x62DD1DDFUL, 0x15DA2D49UL, 0x8CD37CF3UL, 0xFBD44C65UL, 44 | 0x4DB26158UL, 0x3AB551CEUL, 0xA3BC0074UL, 0xD4BB30E2UL, 45 | 0x4ADFA541UL, 0x3DD895D7UL, 0xA4D1C46DUL, 0xD3D6F4FBUL, 46 | 0x4369E96AUL, 0x346ED9FCUL, 0xAD678846UL, 0xDA60B8D0UL, 47 | 0x44042D73UL, 0x33031DE5UL, 0xAA0A4C5FUL, 0xDD0D7CC9UL, 48 | 0x5005713CUL, 0x270241AAUL, 0xBE0B1010UL, 0xC90C2086UL, 49 | 0x5768B525UL, 0x206F85B3UL, 0xB966D409UL, 0xCE61E49FUL, 50 | 0x5EDEF90EUL, 0x29D9C998UL, 0xB0D09822UL, 0xC7D7A8B4UL, 51 | 0x59B33D17UL, 0x2EB40D81UL, 0xB7BD5C3BUL, 0xC0BA6CADUL, 52 | 0xEDB88320UL, 0x9ABFB3B6UL, 0x03B6E20CUL, 0x74B1D29AUL, 53 | 0xEAD54739UL, 0x9DD277AFUL, 0x04DB2615UL, 0x73DC1683UL, 54 | 0xE3630B12UL, 0x94643B84UL, 0x0D6D6A3EUL, 0x7A6A5AA8UL, 55 | 0xE40ECF0BUL, 0x9309FF9DUL, 0x0A00AE27UL, 0x7D079EB1UL, 56 | 0xF00F9344UL, 0x8708A3D2UL, 0x1E01F268UL, 0x6906C2FEUL, 57 | 0xF762575DUL, 0x806567CBUL, 0x196C3671UL, 0x6E6B06E7UL, 58 | 0xFED41B76UL, 0x89D32BE0UL, 0x10DA7A5AUL, 0x67DD4ACCUL, 59 | 0xF9B9DF6FUL, 0x8EBEEFF9UL, 0x17B7BE43UL, 0x60B08ED5UL, 60 | 0xD6D6A3E8UL, 0xA1D1937EUL, 0x38D8C2C4UL, 0x4FDFF252UL, 61 | 0xD1BB67F1UL, 0xA6BC5767UL, 0x3FB506DDUL, 0x48B2364BUL, 62 | 0xD80D2BDAUL, 0xAF0A1B4CUL, 0x36034AF6UL, 0x41047A60UL, 63 | 0xDF60EFC3UL, 0xA867DF55UL, 0x316E8EEFUL, 0x4669BE79UL, 64 | 0xCB61B38CUL, 0xBC66831AUL, 0x256FD2A0UL, 0x5268E236UL, 65 | 0xCC0C7795UL, 0xBB0B4703UL, 0x220216B9UL, 0x5505262FUL, 66 | 0xC5BA3BBEUL, 0xB2BD0B28UL, 0x2BB45A92UL, 0x5CB36A04UL, 67 | 0xC2D7FFA7UL, 0xB5D0CF31UL, 0x2CD99E8BUL, 0x5BDEAE1DUL, 68 | 0x9B64C2B0UL, 0xEC63F226UL, 0x756AA39CUL, 0x026D930AUL, 69 | 0x9C0906A9UL, 0xEB0E363FUL, 0x72076785UL, 0x05005713UL, 70 | 0x95BF4A82UL, 0xE2B87A14UL, 0x7BB12BAEUL, 0x0CB61B38UL, 71 | 0x92D28E9BUL, 0xE5D5BE0DUL, 0x7CDCEFB7UL, 0x0BDBDF21UL, 72 | 0x86D3D2D4UL, 0xF1D4E242UL, 0x68DDB3F8UL, 0x1FDA836EUL, 73 | 0x81BE16CDUL, 0xF6B9265BUL, 0x6FB077E1UL, 0x18B74777UL, 74 | 0x88085AE6UL, 0xFF0F6A70UL, 0x66063BCAUL, 0x11010B5CUL, 75 | 0x8F659EFFUL, 0xF862AE69UL, 0x616BFFD3UL, 0x166CCF45UL, 76 | 0xA00AE278UL, 0xD70DD2EEUL, 0x4E048354UL, 0x3903B3C2UL, 77 | 0xA7672661UL, 0xD06016F7UL, 0x4969474DUL, 0x3E6E77DBUL, 78 | 0xAED16A4AUL, 0xD9D65ADCUL, 0x40DF0B66UL, 0x37D83BF0UL, 79 | 0xA9BCAE53UL, 0xDEBB9EC5UL, 0x47B2CF7FUL, 0x30B5FFE9UL, 80 | 0xBDBDF21CUL, 0xCABAC28AUL, 0x53B39330UL, 0x24B4A3A6UL, 81 | 0xBAD03605UL, 0xCDD70693UL, 0x54DE5729UL, 0x23D967BFUL, 82 | 0xB3667A2EUL, 0xC4614AB8UL, 0x5D681B02UL, 0x2A6F2B94UL, 83 | 0xB40BBE37UL, 0xC30C8EA1UL, 0x5A05DF1BUL, 0x2D02EF8DUL 84 | }; 85 | -------------------------------------------------------------------------------- /CRC32.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 Djones A. Boni 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #ifndef CRC32_H_ 18 | #define CRC32_H_ 19 | 20 | #include 21 | #include 22 | 23 | struct CRC32 { 24 | typedef uint32_t CRC_t; 25 | static const int8_t size = 4; 26 | static const CRC_t CRC_INIT = 0xFFFFFFFFUL; 27 | static const CRC_t CRC_FINALXOR = 0xFFFFFFFFUL; 28 | static const CRC_t CRC_GOOD = 0xDEBB20E3UL; 29 | 30 | PROGMEM static const CRC_t CRC_TAB[256U]; 31 | 32 | void init() { crc = CRC_INIT; } 33 | void update(uint8_t data) { 34 | /* crc = (crc >> 8U) ^ CRC_TAB[(crc ^ data) & 0xFFU]; */ 35 | crc = (crc >> 8U) ^ pgm_read_dword(&CRC_TAB[(crc ^ data) & 0xFFU]); 36 | } 37 | 38 | bool good() { return crc == CRC_GOOD; } 39 | 40 | void final() { crc ^= CRC_FINALXOR; } 41 | uint8_t operator[](int8_t pos) { 42 | switch(pos) { 43 | case 0: return crc; 44 | case 1: return crc >> 8U; 45 | case 2: return crc >> 16U; 46 | default: return crc >> 24U; 47 | } 48 | } 49 | 50 | CRC_t crc; 51 | }; 52 | 53 | #endif /* CRC32_H_ */ 54 | -------------------------------------------------------------------------------- /HDLC.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 Djones A. Boni 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #ifndef HDLC_H_ 18 | #define HDLC_H_ 19 | 20 | #include 21 | #include 22 | 23 | #define HDLC_TEMPLATE \ 24 | int16_t (&readByte)(void), \ 25 | void (&writeByte)(uint8_t data), \ 26 | uint16_t rxBuffLen, \ 27 | class CRC 28 | 29 | #define HDLC_TEMPLATETYPE \ 30 | readByte, \ 31 | writeByte, \ 32 | rxBuffLen, \ 33 | CRC 34 | 35 | template 36 | class HDLC 37 | { 38 | private: 39 | static const uint8_t DATAINVBIT; 40 | static const uint8_t DATASTART; 41 | static const uint8_t DATAESCAPE; 42 | static const uint8_t DATAESCAPELIST[]; 43 | 44 | public: 45 | static const uint16_t RXBFLEN = rxBuffLen; 46 | 47 | HDLC(); 48 | void init(); 49 | 50 | void transmitBlock(const void* vdata, uint16_t len); 51 | 52 | void transmitStart(); 53 | void transmitByte(uint8_t data); 54 | void transmitBytes(const void* vdata, uint16_t len); 55 | void transmitEnd(); 56 | 57 | uint16_t receive(); 58 | 59 | uint16_t copyReceivedMessage(uint8_t (&buff)[RXBFLEN]) const; 60 | uint16_t copyReceivedMessage(uint8_t *buff, uint16_t pos, uint16_t num) const; 61 | 62 | private: 63 | static void escapeAndWriteByte(uint8_t data) { 64 | const uint8_t n = sizeof(DATAESCAPELIST)/sizeof(DATAESCAPELIST[0]); 65 | for(int8_t i = 0; i < n; ++i) 66 | { 67 | if(data == DATAESCAPELIST[i]) 68 | { 69 | writeByte(DATAESCAPE); 70 | data ^= DATAINVBIT; 71 | break; 72 | } 73 | } 74 | writeByte(data); 75 | } 76 | 77 | enum { 78 | ESCAPED = -1, 79 | RECEIVING = 0, 80 | OK = 1, 81 | CRCERR = 2 82 | }; 83 | 84 | CRC txcrc; 85 | 86 | int8_t status; 87 | uint16_t len; 88 | CRC crc; 89 | uint8_t data[RXBFLEN]; 90 | }; 91 | 92 | 93 | 94 | template 95 | const uint8_t HDLC::DATAINVBIT = 0x20U; 96 | 97 | template 98 | const uint8_t HDLC::DATASTART = '~'; 99 | 100 | template 101 | const uint8_t HDLC::DATAESCAPE = '}'; 102 | 103 | template 104 | const uint8_t HDLC::DATAESCAPELIST[] = 105 | { DATASTART, DATAESCAPE }; 106 | 107 | 108 | 109 | template 110 | HDLC::HDLC() 111 | { 112 | init(); 113 | } 114 | 115 | template 116 | void HDLC::init() 117 | { 118 | len = 0U; 119 | status = RECEIVING; 120 | crc.init(); 121 | } 122 | 123 | template 124 | void HDLC:: 125 | transmitBlock(const void* vdata, uint16_t len) 126 | { 127 | transmitStart(); 128 | transmitBytes(vdata, len); 129 | transmitEnd(); 130 | } 131 | 132 | template 133 | void HDLC::transmitStart() 134 | { 135 | writeByte(DATASTART); 136 | txcrc.init(); 137 | } 138 | 139 | template 140 | void HDLC::transmitByte(uint8_t data) 141 | { 142 | escapeAndWriteByte(data); 143 | txcrc.update(data); 144 | } 145 | 146 | template 147 | void HDLC:: 148 | transmitBytes(const void* vdata, uint16_t len) 149 | { 150 | const uint8_t* data = (const uint8_t*)vdata; 151 | while(len) 152 | { 153 | transmitByte(*data); 154 | ++data; 155 | --len; 156 | } 157 | } 158 | 159 | template 160 | void HDLC::transmitEnd() 161 | { 162 | txcrc.final(); 163 | for(int8_t i = 0; i < txcrc.size; ++i) 164 | escapeAndWriteByte(txcrc[i]); 165 | writeByte(DATASTART); 166 | } 167 | 168 | template 169 | uint16_t HDLC::receive() 170 | { 171 | int16_t c = readByte(); 172 | if(c == -1) 173 | return 0U; 174 | 175 | if(status >= OK) 176 | init(); 177 | 178 | uint16_t retv = 0U; 179 | 180 | if(c == DATASTART) 181 | { 182 | if(status == RECEIVING && len != 0U) 183 | { 184 | if(crc.good()) 185 | { 186 | status = OK; 187 | len -= crc.size; 188 | retv = len; 189 | } 190 | else 191 | { 192 | status = CRCERR; 193 | } 194 | } 195 | else 196 | { 197 | init(); 198 | } 199 | } 200 | else 201 | { 202 | if(status == ESCAPED) 203 | { 204 | status = RECEIVING; 205 | 206 | c ^= DATAINVBIT; 207 | crc.update(c); 208 | if(len < RXBFLEN) 209 | data[len] = c; 210 | ++len; 211 | } 212 | else if(c != DATAESCAPE) 213 | { 214 | crc.update(c); 215 | if(len < RXBFLEN) 216 | data[len] = c; 217 | ++len; 218 | } 219 | else 220 | { 221 | status = ESCAPED; 222 | } 223 | } 224 | 225 | return retv; 226 | } 227 | 228 | template 229 | uint16_t HDLC::copyReceivedMessage(uint8_t (&buff)[RXBFLEN]) const 230 | { 231 | const uint16_t datalen = (len > RXBFLEN) ? RXBFLEN : len; 232 | memcpy(buff, data, datalen); 233 | return datalen; 234 | } 235 | 236 | template 237 | uint16_t HDLC:: 238 | copyReceivedMessage(uint8_t *buff, uint16_t pos, uint16_t num) const 239 | { 240 | const uint16_t datalen = (len > RXBFLEN) ? RXBFLEN : len; 241 | if(pos < RXBFLEN) 242 | { 243 | num = (pos + num) > datalen ? (datalen - pos) : num; 244 | memcpy(buff, &data[pos], num); 245 | } 246 | else 247 | { 248 | num = 0; 249 | } 250 | return num; 251 | } 252 | 253 | #endif /* HDLC_H_ */ 254 | -------------------------------------------------------------------------------- /HDLC_TL1B.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 Djones A. Boni 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #ifndef HDLC_TL1B_H_ 18 | #define HDLC_TL1B_H_ 19 | 20 | #define HDLC_TL1B_TEMPLATE \ 21 | int16_t (&readByte)(void), \ 22 | void (&writeByte)(uint8_t data), \ 23 | uint16_t rxBuffLen, \ 24 | class CRC, \ 25 | uint8_t seqMax, \ 26 | uint8_t noAckLim 27 | 28 | #define HDLC_TL1B_TEMPLATEDEFAULT \ 29 | int16_t (&readByte)(void), \ 30 | void (&writeByte)(uint8_t data), \ 31 | uint16_t rxBuffLen, \ 32 | class CRC, \ 33 | uint8_t seqMax = 63U, \ 34 | uint8_t noAckLim = 5U 35 | 36 | #define HDLC_TL1B_TEMPLATETYPE \ 37 | readByte, \ 38 | writeByte, \ 39 | rxBuffLen, \ 40 | CRC, \ 41 | seqMax, \ 42 | noAckLim 43 | 44 | #define HDLC_TL1B_BASE_TEMPLATETYPE \ 45 | readByte, \ 46 | writeByte, \ 47 | rxBuffLen + 1U, \ 48 | CRC 49 | 50 | #include "HDLC.h" 51 | 52 | template 53 | class HDLC_TL1B: 54 | private HDLC 55 | { 56 | private: 57 | static const uint8_t MASK = 0xC0U; 58 | static const uint8_t MASKINV = 0x3FU; 59 | static const uint8_t RESET = 0x00U; 60 | static const uint8_t ACK = 0x40U; 61 | static const uint8_t NACK = 0x80U; 62 | static const uint8_t DATA = 0xC0U; 63 | 64 | public: 65 | static const uint16_t RXBFLEN = rxBuffLen; 66 | 67 | HDLC_TL1B(); 68 | void init(); 69 | 70 | void transmitReset(); 71 | void transmitBlock(const void* vdata, uint16_t len); 72 | 73 | void transmitStart(); 74 | void transmitByte(uint8_t data); 75 | void transmitBytes(const void* vdata, uint16_t len); 76 | void transmitEnd(); 77 | 78 | uint16_t receive(); 79 | 80 | uint16_t copyReceivedMessage(uint8_t (&buff)[RXBFLEN]) const; 81 | 82 | private: 83 | void transmitAck(uint8_t rxs); 84 | void transmitNack(uint8_t rxs); 85 | 86 | uint8_t count_seq; 87 | uint8_t count_tx_noack; 88 | }; 89 | 90 | template 91 | HDLC_TL1B::HDLC_TL1B() 92 | { 93 | init(); 94 | } 95 | 96 | template 97 | void HDLC_TL1B::init() 98 | { 99 | HDLC::init(); 100 | count_seq = seqMax; 101 | count_tx_noack = 0U; 102 | } 103 | 104 | template 105 | void HDLC_TL1B:: 106 | transmitReset() 107 | { 108 | init(); 109 | HDLC::transmitStart(); 110 | HDLC::transmitByte(RESET); 111 | HDLC::transmitEnd(); 112 | } 113 | 114 | template 115 | void HDLC_TL1B:: 116 | transmitBlock(const void* vdata, uint16_t len) 117 | { 118 | transmitStart(); 119 | transmitBytes(vdata, len); 120 | transmitEnd(); 121 | } 122 | 123 | template 124 | void HDLC_TL1B:: 125 | transmitStart() 126 | { 127 | if(++count_tx_noack >= noAckLim) 128 | transmitReset(); 129 | 130 | HDLC::transmitStart(); 131 | count_seq = (count_seq < seqMax) ? (count_seq + 1U) : 0U; 132 | HDLC::transmitByte(DATA | count_seq); 133 | } 134 | 135 | template 136 | void HDLC_TL1B:: 137 | transmitByte(uint8_t data) 138 | { 139 | HDLC::transmitByte(data); 140 | } 141 | 142 | template 143 | void HDLC_TL1B:: 144 | transmitBytes(const void* vdata, uint16_t len) 145 | { 146 | const uint8_t* data = (const uint8_t*)vdata; 147 | while(len) 148 | { 149 | transmitByte(*data); 150 | ++data; 151 | --len; 152 | } 153 | } 154 | 155 | template 156 | void HDLC_TL1B::transmitEnd() 157 | { 158 | HDLC::transmitEnd(); 159 | } 160 | 161 | template 162 | uint16_t HDLC_TL1B::receive() 163 | { 164 | uint16_t datalen = HDLC::receive(); 165 | if(datalen != 0U) 166 | { 167 | datalen -= 1U; 168 | 169 | uint8_t frameseq; 170 | HDLC::copyReceivedMessage(&frameseq, 0U, 1U); 171 | 172 | uint8_t frame = frameseq & MASK; 173 | uint8_t rxs = frameseq & MASKINV; 174 | if(frame == DATA) 175 | { 176 | transmitAck(rxs); 177 | } 178 | else if(frame == ACK) 179 | { 180 | count_tx_noack = 0U; 181 | } 182 | else if(frame == NACK) 183 | { 184 | } 185 | else if(frame == RESET) 186 | { 187 | } 188 | else 189 | { 190 | } 191 | } 192 | return datalen; 193 | } 194 | 195 | template 196 | uint16_t HDLC_TL1B:: 197 | copyReceivedMessage(uint8_t (&buff)[RXBFLEN]) const 198 | { 199 | uint16_t datalen = HDLC:: 200 | copyReceivedMessage(buff, 1U, RXBFLEN); 201 | return datalen; 202 | } 203 | 204 | template 205 | void HDLC_TL1B:: 206 | transmitAck(uint8_t rxs) 207 | { 208 | rxs &= MASKINV; 209 | rxs |= ACK; 210 | HDLC::transmitStart(); 211 | HDLC::transmitByte(rxs); 212 | HDLC::transmitEnd(); 213 | } 214 | 215 | template 216 | void HDLC_TL1B:: 217 | transmitNack(uint8_t rxs) 218 | { 219 | rxs &= MASKINV; 220 | rxs |= NACK; 221 | HDLC::transmitStart(); 222 | HDLC::transmitByte(rxs); 223 | HDLC::transmitEnd(); 224 | } 225 | 226 | #endif /* HDLC_TL1B_H_ */ 227 | -------------------------------------------------------------------------------- /HDLC_TL3B_TOKEN.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 Djones A. Boni 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #ifndef HDLC_TL3B_TOKEN_H_ 18 | #define HDLC_TL3B_TOKEN_H_ 19 | 20 | #include "HDLC.h" 21 | 22 | #define HDLC_TL3B_TOKEN_TEMPLATE \ 23 | int16_t (&readByte)(void), \ 24 | void (&writeByte)(uint8_t data), \ 25 | uint16_t rxBuffLen, \ 26 | class CRC 27 | 28 | #define HDLC_TL3B_TOKEN_TEMPLATETYPE \ 29 | readByte, \ 30 | writeByte, \ 31 | rxBuffLen, \ 32 | CRC 33 | 34 | #define HDLC_TL3B_TOKEN_BASE_TEMPLATETYPE \ 35 | readByte, \ 36 | writeByte, \ 37 | rxBuffLen, \ 38 | CRC 39 | 40 | template 41 | class HDLC_TL3B_TOKEN: 42 | private HDLC 43 | { 44 | public: 45 | enum Command_t { 46 | CMD_RESET = 0, 47 | CMD_GIVE_TOKEN, 48 | CMD_ACK_TOKEN, 49 | CMD_WRITE, 50 | CMD_READ 51 | }; 52 | 53 | enum TokenState_t { 54 | TOKEN_HAVE = 0, 55 | TOKEN_PASSING, 56 | TOKEN_DONT_HAVE 57 | }; 58 | 59 | struct MessageHeader_t { 60 | Command_t command; 61 | uint8_t from; 62 | uint8_t to; 63 | }; 64 | 65 | static const uint16_t RXBFLEN = rxBuffLen; 66 | 67 | HDLC_TL3B_TOKEN(uint8_t address, bool master = false); 68 | 69 | void transmitReset(); 70 | void transmitGiveToken(uint8_t to_addr); 71 | private: 72 | void transmitAckToken(uint8_t to_addr); 73 | 74 | void transmitStart(Command_t command, uint8_t to_addr); 75 | 76 | public: 77 | void transmitStartWrite(uint8_t to_addr); 78 | void transmitStartRead(uint8_t to_addr); 79 | 80 | void transmitByte(uint8_t data); 81 | void transmitBlock(const void* vdata, uint16_t len); 82 | void transmitEnd(); 83 | 84 | uint16_t receive(); 85 | 86 | MessageHeader_t copyMessageHeader(); 87 | uint16_t copyMessageData(uint8_t *buff, uint16_t pos, uint16_t num) const; 88 | uint16_t copyMessageData(uint8_t (&buff)[RXBFLEN]) const; 89 | 90 | void setAddress(uint8_t address) { Address = address; } 91 | uint8_t getAddress() const { return Address; } 92 | uint16_t getRxCount() const { return RxCount; } 93 | uint16_t getTxCount() const { return TxCount; } 94 | TokenState_t getTokenState() const { return TokenState; } 95 | bool haveToken() const { return TokenState == TOKEN_HAVE; } 96 | uint8_t getTokenAddress() const { return TokenAddress; } 97 | 98 | private: 99 | uint8_t Address; 100 | uint16_t RxCount; 101 | uint16_t TxCount; 102 | TokenState_t TokenState; 103 | uint8_t TokenAddress; 104 | }; 105 | 106 | template 107 | HDLC_TL3B_TOKEN:: 108 | HDLC_TL3B_TOKEN(uint8_t address, bool master) 109 | { 110 | setAddress(address); 111 | RxCount = 0; 112 | TxCount = 0; 113 | TokenState = master ? TOKEN_HAVE : TOKEN_DONT_HAVE; 114 | TokenAddress = 0; 115 | } 116 | 117 | template 118 | void HDLC_TL3B_TOKEN::transmitReset() 119 | { 120 | TokenState = TOKEN_HAVE; 121 | transmitStart(CMD_RESET, 0); /* broadcast */ 122 | transmitEnd(); 123 | } 124 | 125 | template 126 | void HDLC_TL3B_TOKEN:: 127 | transmitGiveToken(uint8_t to_addr) 128 | { 129 | transmitStart(CMD_GIVE_TOKEN, to_addr); 130 | transmitEnd(); 131 | 132 | TokenAddress = to_addr; 133 | TokenState = TOKEN_PASSING; 134 | } 135 | 136 | template 137 | void HDLC_TL3B_TOKEN:: 138 | transmitAckToken(uint8_t to_addr) 139 | { 140 | transmitStart(CMD_ACK_TOKEN, to_addr); 141 | transmitEnd(); 142 | } 143 | 144 | template 145 | void HDLC_TL3B_TOKEN:: 146 | transmitStartWrite(uint8_t to_addr) 147 | { 148 | transmitStart(CMD_WRITE, to_addr); 149 | } 150 | 151 | template 152 | void HDLC_TL3B_TOKEN:: 153 | transmitStartRead(uint8_t to_addr) 154 | { 155 | transmitStart(CMD_READ, to_addr); 156 | } 157 | 158 | template 159 | void HDLC_TL3B_TOKEN:: 160 | transmitStart(Command_t command, uint8_t to_addr) 161 | { 162 | ++TxCount; 163 | 164 | HDLC::transmitStart(); 165 | HDLC::transmitByte(command); /* Command */ 166 | HDLC::transmitByte(Address); /* From */ 167 | HDLC::transmitByte(to_addr); /* To */ 168 | } 169 | 170 | template 171 | void HDLC_TL3B_TOKEN::transmitByte(uint8_t data) 172 | { 173 | HDLC::transmitByte(data); 174 | } 175 | 176 | template 177 | void HDLC_TL3B_TOKEN:: 178 | transmitBlock(const void* vdata, uint16_t len) 179 | { 180 | const uint8_t* data = (const uint8_t*)vdata; 181 | while(len) 182 | { 183 | transmitByte(*data); 184 | ++data; 185 | --len; 186 | } 187 | } 188 | 189 | template 190 | void HDLC_TL3B_TOKEN::transmitEnd() 191 | { 192 | HDLC::transmitEnd(); 193 | } 194 | 195 | template 196 | uint16_t HDLC_TL3B_TOKEN::receive() 197 | { 198 | uint16_t datalen = HDLC::receive(); 199 | 200 | if(datalen >= 3U) 201 | { 202 | ++RxCount; 203 | datalen -= 3U; 204 | 205 | MessageHeader_t header = copyMessageHeader(); 206 | 207 | if( 208 | (header.to == 0U || header.to == Address) && 209 | header.from != Address) 210 | { 211 | /* Message for me. */ 212 | 213 | switch(header.command) { 214 | 215 | case CMD_RESET: 216 | TokenState = TOKEN_DONT_HAVE; 217 | datalen = 0U; 218 | break; 219 | 220 | case CMD_GIVE_TOKEN: 221 | if(header.to != 0) 222 | { 223 | /* Do not accept a token given in a broadcast. */ 224 | TokenState = TOKEN_HAVE; 225 | transmitAckToken(header.from); 226 | TokenAddress = header.from; 227 | } 228 | else 229 | { 230 | /* Error. Token given in a broadcast. Not my fault. */ 231 | } 232 | datalen = 0U; 233 | break; 234 | 235 | case CMD_ACK_TOKEN: 236 | if(header.to != 0) 237 | { 238 | /* Do not accept a token acknowledged in a broadcast. */ 239 | TokenState = TOKEN_DONT_HAVE; 240 | } 241 | else 242 | { 243 | /* Error. Token acknowledged in a broadcast. Not my fault. */ 244 | } 245 | datalen = 0U; 246 | break; 247 | 248 | case CMD_WRITE: 249 | case CMD_READ: 250 | default: 251 | break; 252 | } 253 | } 254 | else 255 | { 256 | /* Message not for me. */ 257 | datalen = 0U; 258 | } 259 | } 260 | else 261 | { 262 | /* Invalid message (too short). */ 263 | datalen = 0U; 264 | } 265 | 266 | return datalen; 267 | } 268 | 269 | template 270 | typename HDLC_TL3B_TOKEN::MessageHeader_t 271 | HDLC_TL3B_TOKEN:: 272 | copyMessageHeader() 273 | { 274 | uint8_t buff[3U]; 275 | HDLC::copyReceivedMessage(&buff[0U], 0U, sizeof(buff)); 276 | MessageHeader_t header = { static_cast(buff[0U]), buff[1U], buff[2U] }; 277 | return header; 278 | } 279 | 280 | template 281 | uint16_t HDLC_TL3B_TOKEN:: 282 | copyMessageData(uint8_t *buff, uint16_t pos, uint16_t num) const 283 | { 284 | uint16_t datalen = HDLC:: 285 | copyReceivedMessage(buff, pos + 3U, num); 286 | return datalen; 287 | } 288 | 289 | template 290 | uint16_t HDLC_TL3B_TOKEN:: 291 | copyMessageData(uint8_t (&buff)[RXBFLEN]) const 292 | { 293 | uint16_t datalen = HDLC:: 294 | copyReceivedMessage(buff, 3U, RXBFLEN); 295 | return datalen; 296 | } 297 | 298 | #endif /* HDLC_TL3B_TOKEN_H_ */ 299 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # [HDLC](https://github.com/djboni/hdlc) 2 | 3 | by [Djones A. Boni](https://twitter.com/djonesboni) 4 | 5 | 6 | HDLC stads for High-Level Data Link Control. This library adapts the HDLC 7 | protocol for standard serial, allowing easy communication with CRC error 8 | detection among microcontrollers connected via a serial bus. 9 | 10 | For more information about HDLC and take a look at 11 | [RFC-1662 - PPP in HDLC-like Framing](https://tools.ietf.org/html/rfc1662) 12 | or in the doc/rfc1662.txt file. 13 | 14 | Implemented as a C++ class template, the HDLC Data Link Layer can be extended 15 | using class inheritance. The library also provides an One Byte Transport Layer 16 | derived class template as an extension example. 17 | 18 | You can use HDLC both for closed- and open-source projects. You are also 19 | free to keep changes to this library to yourself. However we'll enjoy your 20 | improvements and suggestions. `:-)` 21 | 22 | You are free to copy, modify, and distribute HDLC with attribution under 23 | the terms of the 24 | [Apache License Version 2.0](http://www.apache.org/licenses/LICENSE-2.0). 25 | See the doc/LICENSE file for details. 26 | 27 | 28 | ## Supported hardware 29 | 30 | The project has been developed and tested with AVR microcontroller family 31 | (ATmega 2560) using [Arduinutil](https://github.com/djboni/arduinutil) as 32 | development platform. 33 | 34 | However it should be very easy to port to another microcontroller family and 35 | development platform. 36 | 37 | 38 | ## How to use HDLC 39 | 40 | * Create an HDLC object 41 | * Send data with HDLC 42 | * Receive data with HDLC 43 | 44 | ```cpp 45 | #include "HDLC.h" 46 | #include "Arduinutil.h" 47 | 48 | HDLC hdlc; 49 | 50 | void hdlc_sendMsg() { 51 | uint8_t msg[] = "Hello world!"; 52 | hdlc.transmitBlock(msg, sizeof(msg)); 53 | } 54 | 55 | void hdlc_receiveMsg() { 56 | if(hdlc.receive() != 0U) 57 | { 58 | uint8_t buff[hdlc.RXBFLEN]; 59 | uint16_t size = hdlc.copyReceivedMessage(buff); 60 | 61 | Serial_print("Msg[%u]=%s\n", size, buff); 62 | } 63 | } 64 | 65 | int main(void) 66 | { 67 | init(); 68 | Serial_begin(115200, SERIAL_8N1); 69 | Serial1_begin(19200, SERIAL_8N1); 70 | 71 | Serial_print("Init\n"); 72 | 73 | hdlc_sendMsg(); 74 | 75 | for(;;) 76 | { 77 | hdlc_receiveMsg(); 78 | } 79 | } 80 | ``` 81 | 82 | 83 | ## Contributing to HDLC 84 | 85 | If you have suggestions for improving HDLC, please 86 | [open an issue or pull request on GitHub](https://github.com/djboni/hdlc). 87 | 88 | 89 | ## Important files 90 | 91 | [README.md](https://github.com/djboni/hdlc/blob/master/README.md) 92 | Fast introduction (this file). 93 | 94 | [doc/LICENCE](https://github.com/djboni/hdlc/blob/master/doc/LICENSE) 95 | Complete license text. 96 | 97 | -------------------------------------------------------------------------------- /doc/LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /doc/rfc1662.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Network Working Group W. Simpson, Editor 8 | Request for Comments: 1662 Daydreamer 9 | STD: 51 July 1994 10 | Obsoletes: 1549 11 | Category: Standards Track 12 | 13 | 14 | PPP in HDLC-like Framing 15 | 16 | 17 | Status of this Memo 18 | 19 | This document specifies an Internet standards track protocol for the 20 | Internet community, and requests discussion and suggestions for 21 | improvements. Please refer to the current edition of the "Internet 22 | Official Protocol Standards" (STD 1) for the standardization state 23 | and status of this protocol. Distribution of this memo is unlimited. 24 | 25 | 26 | Abstract 27 | 28 | The Point-to-Point Protocol (PPP) [1] provides a standard method for 29 | transporting multi-protocol datagrams over point-to-point links. 30 | 31 | This document describes the use of HDLC-like framing for PPP 32 | encapsulated packets. 33 | 34 | 35 | Table of Contents 36 | 37 | 38 | 1. Introduction .......................................... 1 39 | 1.1 Specification of Requirements ................... 2 40 | 1.2 Terminology ..................................... 2 41 | 42 | 2. Physical Layer Requirements ........................... 3 43 | 44 | 3. The Data Link Layer ................................... 4 45 | 3.1 Frame Format .................................... 5 46 | 3.2 Modification of the Basic Frame ................. 7 47 | 48 | 4. Octet-stuffed framing ................................. 8 49 | 4.1 Flag Sequence ................................... 8 50 | 4.2 Transparency .................................... 8 51 | 4.3 Invalid Frames .................................. 9 52 | 4.4 Time Fill ....................................... 9 53 | 4.4.1 Octet-synchronous ............................... 9 54 | 4.4.2 Asynchronous .................................... 9 55 | 4.5 Transmission Considerations ..................... 10 56 | 4.5.1 Octet-synchronous ............................... 10 57 | 4.5.2 Asynchronous .................................... 10 58 | 59 | 60 | Simpson [Page i] 61 | RFC 1662 HDLC-like Framing July 1994 62 | 63 | 64 | 5. Bit-stuffed framing ................................... 11 65 | 5.1 Flag Sequence ................................... 11 66 | 5.2 Transparency .................................... 11 67 | 5.3 Invalid Frames .................................. 11 68 | 5.4 Time Fill ....................................... 11 69 | 5.5 Transmission Considerations ..................... 12 70 | 71 | 6. Asynchronous to Synchronous Conversion ................ 13 72 | 73 | 7. Additional LCP Configuration Options .................. 14 74 | 7.1 Async-Control-Character-Map (ACCM) .............. 14 75 | 76 | APPENDICES ................................................... 17 77 | A. Recommended LCP Options ............................... 17 78 | B. Automatic Recognition of PPP Frames ................... 17 79 | C. Fast Frame Check Sequence (FCS) Implementation ........ 18 80 | C.1 FCS table generator ............................. 18 81 | C.2 16-bit FCS Computation Method ................... 19 82 | C.3 32-bit FCS Computation Method ................... 21 83 | 84 | SECURITY CONSIDERATIONS ...................................... 24 85 | REFERENCES ................................................... 24 86 | ACKNOWLEDGEMENTS ............................................. 25 87 | CHAIR'S ADDRESS .............................................. 25 88 | EDITOR'S ADDRESS ............................................. 25 89 | 90 | 91 | 92 | 93 | 1. Introduction 94 | 95 | This specification provides for framing over both bit-oriented and 96 | octet-oriented synchronous links, and asynchronous links with 8 bits 97 | of data and no parity. These links MUST be full-duplex, but MAY be 98 | either dedicated or circuit-switched. 99 | 100 | An escape mechanism is specified to allow control data such as 101 | XON/XOFF to be transmitted transparently over the link, and to remove 102 | spurious control data which may be injected into the link by 103 | intervening hardware and software. 104 | 105 | Some protocols expect error free transmission, and either provide 106 | error detection only on a conditional basis, or do not provide it at 107 | all. PPP uses the HDLC Frame Check Sequence for error detection. 108 | This is commonly available in hardware implementations, and a 109 | software implementation is provided. 110 | 111 | 112 | 113 | 114 | 115 | 116 | Simpson [Page 1] 117 | RFC 1662 HDLC-like Framing July 1994 118 | 119 | 120 | 1.1. Specification of Requirements 121 | 122 | In this document, several words are used to signify the requirements 123 | of the specification. These words are often capitalized. 124 | 125 | MUST This word, or the adjective "required", means that the 126 | definition is an absolute requirement of the specification. 127 | 128 | MUST NOT This phrase means that the definition is an absolute 129 | prohibition of the specification. 130 | 131 | SHOULD This word, or the adjective "recommended", means that there 132 | may exist valid reasons in particular circumstances to 133 | ignore this item, but the full implications must be 134 | understood and carefully weighed before choosing a 135 | different course. 136 | 137 | MAY This word, or the adjective "optional", means that this 138 | item is one of an allowed set of alternatives. An 139 | implementation which does not include this option MUST be 140 | prepared to interoperate with another implementation which 141 | does include the option. 142 | 143 | 144 | 1.2. Terminology 145 | 146 | This document frequently uses the following terms: 147 | 148 | datagram The unit of transmission in the network layer (such as IP). 149 | A datagram may be encapsulated in one or more packets 150 | passed to the data link layer. 151 | 152 | frame The unit of transmission at the data link layer. A frame 153 | may include a header and/or a trailer, along with some 154 | number of units of data. 155 | 156 | packet The basic unit of encapsulation, which is passed across the 157 | interface between the network layer and the data link 158 | layer. A packet is usually mapped to a frame; the 159 | exceptions are when data link layer fragmentation is being 160 | performed, or when multiple packets are incorporated into a 161 | single frame. 162 | 163 | peer The other end of the point-to-point link. 164 | 165 | silently discard 166 | The implementation discards the packet without further 167 | processing. The implementation SHOULD provide the 168 | capability of logging the error, including the contents of 169 | the silently discarded packet, and SHOULD record the event 170 | in a statistics counter. 171 | 172 | 173 | Simpson [Page 2] 174 | RFC 1662 HDLC-like Framing July 1994 175 | 176 | 177 | 2. Physical Layer Requirements 178 | 179 | PPP is capable of operating across most DTE/DCE interfaces (such as, 180 | EIA RS-232-E, EIA RS-422, and CCITT V.35). The only absolute 181 | requirement imposed by PPP is the provision of a full-duplex circuit, 182 | either dedicated or circuit-switched, which can operate in either an 183 | asynchronous (start/stop), bit-synchronous, or octet-synchronous 184 | mode, transparent to PPP Data Link Layer frames. 185 | 186 | Interface Format 187 | 188 | PPP presents an octet interface to the physical layer. There is 189 | no provision for sub-octets to be supplied or accepted. 190 | 191 | Transmission Rate 192 | 193 | PPP does not impose any restrictions regarding transmission rate, 194 | other than that of the particular DTE/DCE interface. 195 | 196 | Control Signals 197 | 198 | PPP does not require the use of control signals, such as Request 199 | To Send (RTS), Clear To Send (CTS), Data Carrier Detect (DCD), and 200 | Data Terminal Ready (DTR). 201 | 202 | When available, using such signals can allow greater functionality 203 | and performance. In particular, such signals SHOULD be used to 204 | signal the Up and Down events in the LCP Option Negotiation 205 | Automaton [1]. When such signals are not available, the 206 | implementation MUST signal the Up event to LCP upon 207 | initialization, and SHOULD NOT signal the Down event. 208 | 209 | Because signalling is not required, the physical layer MAY be 210 | decoupled from the data link layer, hiding the transient details 211 | of the physical transport. This has implications for mobility in 212 | cellular radio networks, and other rapidly switching links. 213 | 214 | When moving from cell to cell within the same zone, an 215 | implementation MAY choose to treat the entire zone as a single 216 | link, even though transmission is switched among several 217 | frequencies. The link is considered to be with the central 218 | control unit for the zone, rather than the individual cell 219 | transceivers. However, the link SHOULD re-establish its 220 | configuration whenever the link is switched to a different 221 | administration. 222 | 223 | Due to the bursty nature of data traffic, some implementations 224 | have choosen to disconnect the physical layer during periods of 225 | 226 | 227 | 228 | Simpson [Page 3] 229 | RFC 1662 HDLC-like Framing July 1994 230 | 231 | 232 | inactivity, and reconnect when traffic resumes, without informing 233 | the data link layer. Robust implementations should avoid using 234 | this trick over-zealously, since the price for decreased setup 235 | latency is decreased security. Implementations SHOULD signal the 236 | Down event whenever "significant time" has elapsed since the link 237 | was disconnected. The value for "significant time" is a matter of 238 | considerable debate, and is based on the tariffs, call setup 239 | times, and security concerns of the installation. 240 | 241 | 242 | 243 | 3. The Data Link Layer 244 | 245 | PPP uses the principles described in ISO 3309-1979 HDLC frame 246 | structure, most recently the fourth edition 3309:1991 [2], which 247 | specifies modifications to allow HDLC use in asynchronous 248 | environments. 249 | 250 | The PPP control procedures use the Control field encodings described 251 | in ISO 4335-1979 HDLC elements of procedures, most recently the 252 | fourth edition 4335:1991 [4]. 253 | 254 | This should not be construed to indicate that every feature of the 255 | above recommendations are included in PPP. Each feature included 256 | is explicitly described in the following sections. 257 | 258 | To remain consistent with standard Internet practice, and avoid 259 | confusion for people used to reading RFCs, all binary numbers in the 260 | following descriptions are in Most Significant Bit to Least 261 | Significant Bit order, reading from left to right, unless otherwise 262 | indicated. Note that this is contrary to standard ISO and CCITT 263 | practice which orders bits as transmitted (network bit order). Keep 264 | this in mind when comparing this document with the international 265 | standards documents. 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | Simpson [Page 4] 284 | RFC 1662 HDLC-like Framing July 1994 285 | 286 | 287 | 3.1. Frame Format 288 | 289 | A summary of the PPP HDLC-like frame structure is shown below. This 290 | figure does not include bits inserted for synchronization (such as 291 | start and stop bits for asynchronous links), nor any bits or octets 292 | inserted for transparency. The fields are transmitted from left to 293 | right. 294 | 295 | +----------+----------+----------+ 296 | | Flag | Address | Control | 297 | | 01111110 | 11111111 | 00000011 | 298 | +----------+----------+----------+ 299 | +----------+-------------+---------+ 300 | | Protocol | Information | Padding | 301 | | 8/16 bits| * | * | 302 | +----------+-------------+---------+ 303 | +----------+----------+----------------- 304 | | FCS | Flag | Inter-frame Fill 305 | |16/32 bits| 01111110 | or next Address 306 | +----------+----------+----------------- 307 | 308 | The Protocol, Information and Padding fields are described in the 309 | Point-to-Point Protocol Encapsulation [1]. 310 | 311 | Flag Sequence 312 | 313 | Each frame begins and ends with a Flag Sequence, which is the 314 | binary sequence 01111110 (hexadecimal 0x7e). All implementations 315 | continuously check for this flag, which is used for frame 316 | synchronization. 317 | 318 | Only one Flag Sequence is required between two frames. Two 319 | consecutive Flag Sequences constitute an empty frame, which is 320 | silently discarded, and not counted as a FCS error. 321 | 322 | Address Field 323 | 324 | The Address field is a single octet, which contains the binary 325 | sequence 11111111 (hexadecimal 0xff), the All-Stations address. 326 | Individual station addresses are not assigned. The All-Stations 327 | address MUST always be recognized and received. 328 | 329 | The use of other address lengths and values may be defined at a 330 | later time, or by prior agreement. Frames with unrecognized 331 | Addresses SHOULD be silently discarded. 332 | 333 | 334 | 335 | 336 | 337 | 338 | Simpson [Page 5] 339 | RFC 1662 HDLC-like Framing July 1994 340 | 341 | 342 | Control Field 343 | 344 | The Control field is a single octet, which contains the binary 345 | sequence 00000011 (hexadecimal 0x03), the Unnumbered Information 346 | (UI) command with the Poll/Final (P/F) bit set to zero. 347 | 348 | The use of other Control field values may be defined at a later 349 | time, or by prior agreement. Frames with unrecognized Control 350 | field values SHOULD be silently discarded. 351 | 352 | Frame Check Sequence (FCS) Field 353 | 354 | The Frame Check Sequence field defaults to 16 bits (two octets). 355 | The FCS is transmitted least significant octet first, which 356 | contains the coefficient of the highest term. 357 | 358 | A 32-bit (four octet) FCS is also defined. Its use may be 359 | negotiated as described in "PPP LCP Extensions" [5]. 360 | 361 | The use of other FCS lengths may be defined at a later time, or by 362 | prior agreement. 363 | 364 | The FCS field is calculated over all bits of the Address, Control, 365 | Protocol, Information and Padding fields, not including any start 366 | and stop bits (asynchronous) nor any bits (synchronous) or octets 367 | (asynchronous or synchronous) inserted for transparency. This 368 | also does not include the Flag Sequences nor the FCS field itself. 369 | 370 | When octets are received which are flagged in the Async- 371 | Control-Character-Map, they are discarded before calculating 372 | the FCS. 373 | 374 | For more information on the specification of the FCS, see the 375 | Appendices. 376 | 377 | The end of the Information and Padding fields is found by locating 378 | the closing Flag Sequence and removing the Frame Check Sequence 379 | field. 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | Simpson [Page 6] 394 | RFC 1662 HDLC-like Framing July 1994 395 | 396 | 397 | 3.2. Modification of the Basic Frame 398 | 399 | The Link Control Protocol can negotiate modifications to the standard 400 | HDLC-like frame structure. However, modified frames will always be 401 | clearly distinguishable from standard frames. 402 | 403 | Address-and-Control-Field-Compression 404 | 405 | When using the standard HDLC-like framing, the Address and Control 406 | fields contain the hexadecimal values 0xff and 0x03 respectively. 407 | When other Address or Control field values are in use, Address- 408 | and-Control-Field-Compression MUST NOT be negotiated. 409 | 410 | On transmission, compressed Address and Control fields are simply 411 | omitted. 412 | 413 | On reception, the Address and Control fields are decompressed by 414 | examining the first two octets. If they contain the values 0xff 415 | and 0x03, they are assumed to be the Address and Control fields. 416 | If not, it is assumed that the fields were compressed and were not 417 | transmitted. 418 | 419 | By definition, the first octet of a two octet Protocol field 420 | will never be 0xff (since it is not even). The Protocol field 421 | value 0x00ff is not allowed (reserved) to avoid ambiguity when 422 | Protocol-Field-Compression is enabled and the first Information 423 | field octet is 0x03. 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | Simpson [Page 7] 449 | RFC 1662 HDLC-like Framing July 1994 450 | 451 | 452 | 4. Octet-stuffed framing 453 | 454 | This chapter summarizes the use of HDLC-like framing with 8-bit 455 | asynchronous and octet-synchronous links. 456 | 457 | 458 | 459 | 4.1. Flag Sequence 460 | 461 | The Flag Sequence indicates the beginning or end of a frame. The 462 | octet stream is examined on an octet-by-octet basis for the value 463 | 01111110 (hexadecimal 0x7e). 464 | 465 | 466 | 467 | 4.2. Transparency 468 | 469 | An octet stuffing procedure is used. The Control Escape octet is 470 | defined as binary 01111101 (hexadecimal 0x7d), most significant bit 471 | first. 472 | 473 | As a minimum, sending implementations MUST escape the Flag Sequence 474 | and Control Escape octets. 475 | 476 | After FCS computation, the transmitter examines the entire frame 477 | between the two Flag Sequences. Each Flag Sequence, Control Escape 478 | octet, and any octet which is flagged in the sending Async-Control- 479 | Character-Map (ACCM), is replaced by a two octet sequence consisting 480 | of the Control Escape octet followed by the original octet 481 | exclusive-or'd with hexadecimal 0x20. 482 | 483 | This is bit 5 complemented, where the bit positions are numbered 484 | 76543210 (the 6th bit as used in ISO numbered 87654321 -- BEWARE 485 | when comparing documents). 486 | 487 | Receiving implementations MUST correctly process all Control Escape 488 | sequences. 489 | 490 | On reception, prior to FCS computation, each octet with value less 491 | than hexadecimal 0x20 is checked. If it is flagged in the receiving 492 | ACCM, it is simply removed (it may have been inserted by intervening 493 | data communications equipment). Each Control Escape octet is also 494 | removed, and the following octet is exclusive-or'd with hexadecimal 495 | 0x20, unless it is the Flag Sequence (which aborts a frame). 496 | 497 | A few examples may make this more clear. Escaped data is transmitted 498 | on the link as follows: 499 | 500 | 501 | 502 | 503 | Simpson [Page 8] 504 | RFC 1662 HDLC-like Framing July 1994 505 | 506 | 507 | 508 | 0x7e is encoded as 0x7d, 0x5e. (Flag Sequence) 509 | 0x7d is encoded as 0x7d, 0x5d. (Control Escape) 510 | 0x03 is encoded as 0x7d, 0x23. (ETX) 511 | 512 | Some modems with software flow control may intercept outgoing DC1 and 513 | DC3 ignoring the 8th (parity) bit. This data would be transmitted on 514 | the link as follows: 515 | 516 | 0x11 is encoded as 0x7d, 0x31. (XON) 517 | 0x13 is encoded as 0x7d, 0x33. (XOFF) 518 | 0x91 is encoded as 0x7d, 0xb1. (XON with parity set) 519 | 0x93 is encoded as 0x7d, 0xb3. (XOFF with parity set) 520 | 521 | 522 | 523 | 524 | 4.3. Invalid Frames 525 | 526 | Frames which are too short (less than 4 octets when using the 16-bit 527 | FCS), or which end with a Control Escape octet followed immediately 528 | by a closing Flag Sequence, or in which octet-framing is violated (by 529 | transmitting a "0" stop bit where a "1" bit is expected), are 530 | silently discarded, and not counted as a FCS error. 531 | 532 | 533 | 534 | 4.4. Time Fill 535 | 536 | 4.4.1. Octet-synchronous 537 | 538 | There is no provision for inter-octet time fill. 539 | 540 | The Flag Sequence MUST be transmitted during inter-frame time fill. 541 | 542 | 543 | 4.4.2. Asynchronous 544 | 545 | Inter-octet time fill MUST be accomplished by transmitting continuous 546 | "1" bits (mark-hold state). 547 | 548 | Inter-frame time fill can be viewed as extended inter-octet time 549 | fill. Doing so can save one octet for every frame, decreasing delay 550 | and increasing bandwidth. This is possible since a Flag Sequence may 551 | serve as both a frame end and a frame begin. After having received 552 | any frame, an idle receiver will always be in a frame begin state. 553 | 554 | 555 | 556 | 557 | Simpson [Page 9] 558 | RFC 1662 HDLC-like Framing July 1994 559 | 560 | 561 | Robust transmitters should avoid using this trick over-zealously, 562 | since the price for decreased delay is decreased reliability. Noisy 563 | links may cause the receiver to receive garbage characters and 564 | interpret them as part of an incoming frame. If the transmitter does 565 | not send a new opening Flag Sequence before sending the next frame, 566 | then that frame will be appended to the noise characters causing an 567 | invalid frame (with high reliability). 568 | 569 | It is suggested that implementations will achieve the best results by 570 | always sending an opening Flag Sequence if the new frame is not 571 | back-to-back with the last. Transmitters SHOULD send an open Flag 572 | Sequence whenever "appreciable time" has elapsed after the prior 573 | closing Flag Sequence. The maximum value for "appreciable time" is 574 | likely to be no greater than the typing rate of a slow typist, about 575 | 1 second. 576 | 577 | 578 | 579 | 4.5. Transmission Considerations 580 | 581 | 4.5.1. Octet-synchronous 582 | 583 | The definition of various encodings and scrambling is the 584 | responsibility of the DTE/DCE equipment in use, and is outside the 585 | scope of this specification. 586 | 587 | 588 | 4.5.2. Asynchronous 589 | 590 | All octets are transmitted least significant bit first, with one 591 | start bit, eight bits of data, and one stop bit. There is no 592 | provision for seven bit asynchronous links. 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | Simpson [Page 10] 612 | RFC 1662 HDLC-like Framing July 1994 613 | 614 | 615 | 5. Bit-stuffed framing 616 | 617 | This chapter summarizes the use of HDLC-like framing with bit- 618 | synchronous links. 619 | 620 | 621 | 622 | 5.1. Flag Sequence 623 | 624 | The Flag Sequence indicates the beginning or end of a frame, and is 625 | used for frame synchronization. The bit stream is examined on a 626 | bit-by-bit basis for the binary sequence 01111110 (hexadecimal 0x7e). 627 | 628 | The "shared zero mode" Flag Sequence "011111101111110" SHOULD NOT be 629 | used. When not avoidable, such an implementation MUST ensure that 630 | the first Flag Sequence detected (the end of the frame) is promptly 631 | communicated to the link layer. Use of the shared zero mode hinders 632 | interoperability with bit-synchronous to asynchronous and bit- 633 | synchronous to octet-synchronous converters. 634 | 635 | 636 | 637 | 5.2. Transparency 638 | 639 | After FCS computation, the transmitter examines the entire frame 640 | between the two Flag Sequences. A "0" bit is inserted after all 641 | sequences of five contiguous "1" bits (including the last 5 bits of 642 | the FCS) to ensure that a Flag Sequence is not simulated. 643 | 644 | On reception, prior to FCS computation, any "0" bit that directly 645 | follows five contiguous "1" bits is discarded. 646 | 647 | 648 | 649 | 5.3. Invalid Frames 650 | 651 | Frames which are too short (less than 4 octets when using the 16-bit 652 | FCS), or which end with a sequence of more than six "1" bits, are 653 | silently discarded, and not counted as a FCS error. 654 | 655 | 656 | 657 | 5.4. Time Fill 658 | 659 | There is no provision for inter-octet time fill. 660 | 661 | The Flag Sequence SHOULD be transmitted during inter-frame time fill. 662 | However, certain types of circuit-switched links require the use of 663 | 664 | 665 | 666 | Simpson [Page 11] 667 | RFC 1662 HDLC-like Framing July 1994 668 | 669 | 670 | mark idle (continuous ones), particularly those that calculate 671 | accounting based on periods of bit activity. When mark idle is used 672 | on a bit-synchronous link, the implementation MUST ensure at least 15 673 | consecutive "1" bits between Flags during the idle period, and that 674 | the Flag Sequence is always generated at the beginning of a frame 675 | after an idle period. 676 | 677 | This differs from practice in ISO 3309, which allows 7 to 14 bit 678 | mark idle. 679 | 680 | 681 | 682 | 5.5. Transmission Considerations 683 | 684 | All octets are transmitted least significant bit first. 685 | 686 | The definition of various encodings and scrambling is the 687 | responsibility of the DTE/DCE equipment in use, and is outside the 688 | scope of this specification. 689 | 690 | While PPP will operate without regard to the underlying 691 | representation of the bit stream, lack of standards for transmission 692 | will hinder interoperability as surely as lack of data link 693 | standards. At speeds of 56 Kbps through 2.0 Mbps, NRZ is currently 694 | most widely available, and on that basis is recommended as a default. 695 | 696 | When configuration of the encoding is allowed, NRZI is recommended as 697 | an alternative, because of its relative immunity to signal inversion 698 | configuration errors, and instances when it MAY allow connection 699 | without an expensive DSU/CSU. Unfortunately, NRZI encoding 700 | exacerbates the missing x1 factor of the 16-bit FCS, so that one 701 | error in 2**15 goes undetected (instead of one in 2**16), and triple 702 | errors are not detected. Therefore, when NRZI is in use, it is 703 | recommended that the 32-bit FCS be negotiated, which includes the x1 704 | factor. 705 | 706 | At higher speeds of up to 45 Mbps, some implementors have chosen the 707 | ANSI High Speed Synchronous Interface [HSSI]. While this experience 708 | is currently limited, implementors are encouraged to cooperate in 709 | choosing transmission encoding. 710 | 711 | 712 | 713 | 714 | 715 | 716 | 717 | 718 | 719 | 720 | 721 | Simpson [Page 12] 722 | RFC 1662 HDLC-like Framing July 1994 723 | 724 | 725 | 6. Asynchronous to Synchronous Conversion 726 | 727 | There may be some use of asynchronous-to-synchronous converters (some 728 | built into modems and cellular interfaces), resulting in an 729 | asynchronous PPP implementation on one end of a link and a 730 | synchronous implementation on the other. It is the responsibility of 731 | the converter to do all stuffing conversions during operation. 732 | 733 | To enable this functionality, synchronous PPP implementations MUST 734 | always respond to the Async-Control-Character-Map Configuration 735 | Option with the LCP Configure-Ack. However, acceptance of the 736 | Configuration Option does not imply that the synchronous 737 | implementation will do any ACCM mapping. Instead, all such octet 738 | mapping will be performed by the asynchronous-to-synchronous 739 | converter. 740 | 741 | 742 | 743 | 744 | 745 | 746 | 747 | 748 | 749 | 750 | 751 | 752 | 753 | 754 | 755 | 756 | 757 | 758 | 759 | 760 | 761 | 762 | 763 | 764 | 765 | 766 | 767 | 768 | 769 | 770 | 771 | 772 | 773 | 774 | 775 | 776 | Simpson [Page 13] 777 | RFC 1662 HDLC-like Framing July 1994 778 | 779 | 780 | 7. Additional LCP Configuration Options 781 | 782 | The Configuration Option format and basic options are already defined 783 | for LCP [1]. 784 | 785 | Up-to-date values of the LCP Option Type field are specified in the 786 | most recent "Assigned Numbers" RFC [10]. This document concerns the 787 | following values: 788 | 789 | 2 Async-Control-Character-Map 790 | 791 | 792 | 793 | 794 | 7.1. Async-Control-Character-Map (ACCM) 795 | 796 | Description 797 | 798 | This Configuration Option provides a method to negotiate the use 799 | of control character transparency on asynchronous links. 800 | 801 | Each end of the asynchronous link maintains two Async-Control- 802 | Character-Maps. The receiving ACCM is 32 bits, but the sending 803 | ACCM may be up to 256 bits. This results in four distinct ACCMs, 804 | two in each direction of the link. 805 | 806 | For asynchronous links, the default receiving ACCM is 0xffffffff. 807 | The default sending ACCM is 0xffffffff, plus the Control Escape 808 | and Flag Sequence characters themselves, plus whatever other 809 | outgoing characters are flagged (by prior configuration) as likely 810 | to be intercepted. 811 | 812 | For other types of links, the default value is 0, since there is 813 | no need for mapping. 814 | 815 | The default inclusion of all octets less than hexadecimal 0x20 816 | allows all ASCII control characters [6] excluding DEL (Delete) 817 | to be transparently communicated through all known data 818 | communications equipment. 819 | 820 | The transmitter MAY also send octets with values in the range 0x40 821 | through 0xff (except 0x5e) in Control Escape format. Since these 822 | octet values are not negotiable, this does not solve the problem 823 | of receivers which cannot handle all non-control characters. 824 | Also, since the technique does not affect the 8th bit, this does 825 | not solve problems for communications links that can send only 7- 826 | bit characters. 827 | 828 | 829 | 830 | 831 | Simpson [Page 14] 832 | RFC 1662 HDLC-like Framing July 1994 833 | 834 | 835 | Note that this specification differs in detail from later 836 | amendments, such as 3309:1991/Amendment 2 [3]. However, such 837 | "extended transparency" is applied only by "prior agreement". 838 | Use of the transparency methods in this specification 839 | constitute a prior agreement with respect to PPP. 840 | 841 | For compatibility with 3309:1991/Amendment 2, the transmitter 842 | MAY escape DEL and ACCM equivalents with the 8th (most 843 | significant) bit set. No change is required in the receiving 844 | algorithm. 845 | 846 | Following ACCM negotiation, the transmitter SHOULD cease 847 | escaping DEL. 848 | 849 | However, it is rarely necessary to map all control characters, and 850 | often it is unnecessary to map any control characters. The 851 | Configuration Option is used to inform the peer which control 852 | characters MUST remain mapped when the peer sends them. 853 | 854 | The peer MAY still send any other octets in mapped format, if it 855 | is necessary because of constraints known to the peer. The peer 856 | SHOULD Configure-Nak with the logical union of the sets of mapped 857 | octets, so that when such octets are spuriously introduced they 858 | can be ignored on receipt. 859 | 860 | A summary of the Async-Control-Character-Map Configuration Option 861 | format is shown below. The fields are transmitted from left to 862 | right. 863 | 864 | 0 1 2 3 865 | 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 866 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 867 | | Type | Length | ACCM 868 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 869 | ACCM (cont) | 870 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 871 | 872 | 873 | Type 874 | 875 | 2 876 | 877 | Length 878 | 879 | 6 880 | 881 | 882 | 883 | 884 | 885 | 886 | Simpson [Page 15] 887 | RFC 1662 HDLC-like Framing July 1994 888 | 889 | 890 | ACCM 891 | 892 | The ACCM field is four octets, and indicates the set of control 893 | characters to be mapped. The map is sent most significant octet 894 | first. 895 | 896 | Each numbered bit corresponds to the octet of the same value. If 897 | the bit is cleared to zero, then that octet need not be mapped. 898 | If the bit is set to one, then that octet MUST remain mapped. For 899 | example, if bit 19 is set to zero, then the ASCII control 900 | character 19 (DC3, Control-S) MAY be sent in the clear. 901 | 902 | Note: The least significant bit of the least significant octet 903 | (the final octet transmitted) is numbered bit 0, and would map 904 | to the ASCII control character NUL. 905 | 906 | 907 | 908 | 909 | 910 | 911 | 912 | 913 | 914 | 915 | 916 | 917 | 918 | 919 | 920 | 921 | 922 | 923 | 924 | 925 | 926 | 927 | 928 | 929 | 930 | 931 | 932 | 933 | 934 | 935 | 936 | 937 | 938 | 939 | 940 | 941 | Simpson [Page 16] 942 | RFC 1662 HDLC-like Framing July 1994 943 | 944 | 945 | A. Recommended LCP Options 946 | 947 | The following Configurations Options are recommended: 948 | 949 | High Speed links 950 | 951 | Magic Number 952 | Link Quality Monitoring 953 | No Address and Control Field Compression 954 | No Protocol Field Compression 955 | 956 | 957 | Low Speed or Asynchronous links 958 | 959 | Async Control Character Map 960 | Magic Number 961 | Address and Control Field Compression 962 | Protocol Field Compression 963 | 964 | 965 | 966 | B. Automatic Recognition of PPP Frames 967 | 968 | It is sometimes desirable to detect PPP frames, for example during a 969 | login sequence. The following octet sequences all begin valid PPP 970 | LCP frames: 971 | 972 | 7e ff 03 c0 21 973 | 7e ff 7d 23 c0 21 974 | 7e 7d df 7d 23 c0 21 975 | 976 | Note that the first two forms are not a valid username for Unix. 977 | However, only the third form generates a correctly checksummed PPP 978 | frame, whenever 03 and ff are taken as the control characters ETX and 979 | DEL without regard to parity (they are correct for an even parity 980 | link) and discarded. 981 | 982 | Many implementations deal with this by putting the interface into 983 | packet mode when one of the above username patterns are detected 984 | during login, without examining the initial PPP checksum. The 985 | initial incoming PPP frame is discarded, but a Configure-Request is 986 | sent immediately. 987 | 988 | 989 | 990 | 991 | 992 | 993 | 994 | 995 | 996 | Simpson [Page 17] 997 | RFC 1662 HDLC-like Framing July 1994 998 | 999 | 1000 | C. Fast Frame Check Sequence (FCS) Implementation 1001 | 1002 | The FCS was originally designed with hardware implementations in 1003 | mind. A serial bit stream is transmitted on the wire, the FCS is 1004 | calculated over the serial data as it goes out, and the complement of 1005 | the resulting FCS is appended to the serial stream, followed by the 1006 | Flag Sequence. 1007 | 1008 | The receiver has no way of determining that it has finished 1009 | calculating the received FCS until it detects the Flag Sequence. 1010 | Therefore, the FCS was designed so that a particular pattern results 1011 | when the FCS operation passes over the complemented FCS. A good 1012 | frame is indicated by this "good FCS" value. 1013 | 1014 | 1015 | 1016 | C.1. FCS table generator 1017 | 1018 | The following code creates the lookup table used to calculate the 1019 | FCS-16. 1020 | 1021 | /* 1022 | * Generate a FCS-16 table. 1023 | * 1024 | * Drew D. Perkins at Carnegie Mellon University. 1025 | * 1026 | * Code liberally borrowed from Mohsen Banan and D. Hugh Redelmeier. 1027 | */ 1028 | 1029 | /* 1030 | * The FCS-16 generator polynomial: x**0 + x**5 + x**12 + x**16. 1031 | */ 1032 | #define P 0x8408 1033 | 1034 | 1035 | main() 1036 | { 1037 | register unsigned int b, v; 1038 | register int i; 1039 | 1040 | printf("typedef unsigned short u16;\n"); 1041 | printf("static u16 fcstab[256] = {"); 1042 | for (b = 0; ; ) { 1043 | if (b % 8 == 0) 1044 | printf("\n"); 1045 | 1046 | v = b; 1047 | for (i = 8; i--; ) 1048 | 1049 | 1050 | 1051 | Simpson [Page 18] 1052 | RFC 1662 HDLC-like Framing July 1994 1053 | 1054 | 1055 | v = v & 1 ? (v >> 1) ^ P : v >> 1; 1056 | 1057 | printf("\t0x%04x", v & 0xFFFF); 1058 | if (++b == 256) 1059 | break; 1060 | printf(","); 1061 | } 1062 | printf("\n};\n"); 1063 | } 1064 | 1065 | 1066 | 1067 | C.2. 16-bit FCS Computation Method 1068 | 1069 | The following code provides a table lookup computation for 1070 | calculating the Frame Check Sequence as data arrives at the 1071 | interface. This implementation is based on [7], [8], and [9]. 1072 | 1073 | /* 1074 | * u16 represents an unsigned 16-bit number. Adjust the typedef for 1075 | * your hardware. 1076 | */ 1077 | typedef unsigned short u16; 1078 | 1079 | /* 1080 | * FCS lookup table as calculated by the table generator. 1081 | */ 1082 | static u16 fcstab[256] = { 1083 | 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, 1084 | 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, 1085 | 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, 1086 | 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, 1087 | 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, 1088 | 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, 1089 | 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, 1090 | 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, 1091 | 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, 1092 | 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, 1093 | 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, 1094 | 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, 1095 | 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, 1096 | 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, 1097 | 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, 1098 | 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, 1099 | 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, 1100 | 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, 1101 | 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, 1102 | 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, 1103 | 1104 | 1105 | 1106 | Simpson [Page 19] 1107 | RFC 1662 HDLC-like Framing July 1994 1108 | 1109 | 1110 | 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, 1111 | 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, 1112 | 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, 1113 | 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, 1114 | 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, 1115 | 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, 1116 | 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, 1117 | 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, 1118 | 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, 1119 | 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, 1120 | 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, 1121 | 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 1122 | }; 1123 | 1124 | #define PPPINITFCS16 0xffff /* Initial FCS value */ 1125 | #define PPPGOODFCS16 0xf0b8 /* Good final FCS value */ 1126 | 1127 | /* 1128 | * Calculate a new fcs given the current fcs and the new data. 1129 | */ 1130 | u16 pppfcs16(fcs, cp, len) 1131 | register u16 fcs; 1132 | register unsigned char *cp; 1133 | register int len; 1134 | { 1135 | ASSERT(sizeof (u16) == 2); 1136 | ASSERT(((u16) -1) > 0); 1137 | while (len--) 1138 | fcs = (fcs >> 8) ^ fcstab[(fcs ^ *cp++) & 0xff]; 1139 | 1140 | return (fcs); 1141 | } 1142 | 1143 | /* 1144 | * How to use the fcs 1145 | */ 1146 | tryfcs16(cp, len) 1147 | register unsigned char *cp; 1148 | register int len; 1149 | { 1150 | u16 trialfcs; 1151 | 1152 | /* add on output */ 1153 | trialfcs = pppfcs16( PPPINITFCS16, cp, len ); 1154 | trialfcs ^= 0xffff; /* complement */ 1155 | cp[len] = (trialfcs & 0x00ff); /* least significant byte first */ 1156 | cp[len+1] = ((trialfcs >> 8) & 0x00ff); 1157 | 1158 | 1159 | 1160 | 1161 | Simpson [Page 20] 1162 | RFC 1662 HDLC-like Framing July 1994 1163 | 1164 | 1165 | /* check on input */ 1166 | trialfcs = pppfcs16( PPPINITFCS16, cp, len + 2 ); 1167 | if ( trialfcs == PPPGOODFCS16 ) 1168 | printf("Good FCS\n"); 1169 | } 1170 | 1171 | 1172 | 1173 | C.3. 32-bit FCS Computation Method 1174 | 1175 | The following code provides a table lookup computation for 1176 | calculating the 32-bit Frame Check Sequence as data arrives at the 1177 | interface. 1178 | 1179 | /* 1180 | * The FCS-32 generator polynomial: x**0 + x**1 + x**2 + x**4 + x**5 1181 | * + x**7 + x**8 + x**10 + x**11 + x**12 + x**16 1182 | * + x**22 + x**23 + x**26 + x**32. 1183 | */ 1184 | 1185 | /* 1186 | * u32 represents an unsigned 32-bit number. Adjust the typedef for 1187 | * your hardware. 1188 | */ 1189 | typedef unsigned long u32; 1190 | 1191 | static u32 fcstab_32[256] = 1192 | { 1193 | 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 1194 | 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 1195 | 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 1196 | 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 1197 | 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 1198 | 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 1199 | 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 1200 | 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, 1201 | 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 1202 | 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 1203 | 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 1204 | 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 1205 | 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 1206 | 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, 1207 | 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 1208 | 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 1209 | 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 1210 | 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, 1211 | 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 1212 | 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, 1213 | 1214 | 1215 | 1216 | Simpson [Page 21] 1217 | RFC 1662 HDLC-like Framing July 1994 1218 | 1219 | 1220 | 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 1221 | 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 1222 | 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 1223 | 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, 1224 | 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 1225 | 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 1226 | 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 1227 | 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 1228 | 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 1229 | 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, 1230 | 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 1231 | 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 1232 | 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 1233 | 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 1234 | 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 1235 | 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 1236 | 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 1237 | 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, 1238 | 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 1239 | 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 1240 | 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 1241 | 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 1242 | 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 1243 | 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, 1244 | 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 1245 | 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 1246 | 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 1247 | 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, 1248 | 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 1249 | 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, 1250 | 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 1251 | 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 1252 | 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 1253 | 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, 1254 | 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 1255 | 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 1256 | 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 1257 | 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 1258 | 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 1259 | 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, 1260 | 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 1261 | 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, 1262 | 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 1263 | 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d 1264 | }; 1265 | 1266 | #define PPPINITFCS32 0xffffffff /* Initial FCS value */ 1267 | #define PPPGOODFCS32 0xdebb20e3 /* Good final FCS value */ 1268 | 1269 | 1270 | 1271 | Simpson [Page 22] 1272 | RFC 1662 HDLC-like Framing July 1994 1273 | 1274 | 1275 | /* 1276 | * Calculate a new FCS given the current FCS and the new data. 1277 | */ 1278 | u32 pppfcs32(fcs, cp, len) 1279 | register u32 fcs; 1280 | register unsigned char *cp; 1281 | register int len; 1282 | { 1283 | ASSERT(sizeof (u32) == 4); 1284 | ASSERT(((u32) -1) > 0); 1285 | while (len--) 1286 | fcs = (((fcs) >> 8) ^ fcstab_32[((fcs) ^ (*cp++)) & 0xff]); 1287 | 1288 | return (fcs); 1289 | } 1290 | 1291 | /* 1292 | * How to use the fcs 1293 | */ 1294 | tryfcs32(cp, len) 1295 | register unsigned char *cp; 1296 | register int len; 1297 | { 1298 | u32 trialfcs; 1299 | 1300 | /* add on output */ 1301 | trialfcs = pppfcs32( PPPINITFCS32, cp, len ); 1302 | trialfcs ^= 0xffffffff; /* complement */ 1303 | cp[len] = (trialfcs & 0x00ff); /* least significant byte first */ 1304 | cp[len+1] = ((trialfcs >>= 8) & 0x00ff); 1305 | cp[len+2] = ((trialfcs >>= 8) & 0x00ff); 1306 | cp[len+3] = ((trialfcs >> 8) & 0x00ff); 1307 | 1308 | /* check on input */ 1309 | trialfcs = pppfcs32( PPPINITFCS32, cp, len + 4 ); 1310 | if ( trialfcs == PPPGOODFCS32 ) 1311 | printf("Good FCS\n"); 1312 | } 1313 | 1314 | 1315 | 1316 | 1317 | 1318 | 1319 | 1320 | 1321 | 1322 | 1323 | 1324 | 1325 | 1326 | Simpson [Page 23] 1327 | RFC 1662 HDLC-like Framing July 1994 1328 | 1329 | 1330 | Security Considerations 1331 | 1332 | As noted in the Physical Layer Requirements section, the link layer 1333 | might not be informed when the connected state of the physical layer 1334 | has changed. This results in possible security lapses due to over- 1335 | reliance on the integrity and security of switching systems and 1336 | administrations. An insertion attack might be undetected. An 1337 | attacker which is able to spoof the same calling identity might be 1338 | able to avoid link authentication. 1339 | 1340 | 1341 | 1342 | References 1343 | 1344 | [1] Simpson, W., Editor, "The Point-to-Point Protocol (PPP)", 1345 | STD 50, RFC 1661, Daydreamer, July 1994. 1346 | 1347 | [2] ISO/IEC 3309:1991(E), "Information Technology - 1348 | Telecommunications and information exchange between systems - 1349 | High-level data link control (HDLC) procedures - Frame 1350 | structure", International Organization For Standardization, 1351 | Fourth edition 1991-06-01. 1352 | 1353 | [3] ISO/IEC 3309:1991/Amd.2:1992(E), "Information Technology - 1354 | Telecommunications and information exchange between systems - 1355 | High-level data link control (HDLC) procedures - Frame 1356 | structure - Amendment 2: Extended transparency options for 1357 | start/stop transmission", International Organization For 1358 | Standardization, 1992-01-15. 1359 | 1360 | [4] ISO/IEC 4335:1991(E), "Information Technology - 1361 | Telecommunications and information exchange between systems - 1362 | High-level data link control (HDLC) procedures - Elements of 1363 | procedures", International Organization For Standardization, 1364 | Fourth edition 1991-09-15. 1365 | 1366 | [5] Simpson, W., Editor, "PPP LCP Extensions", RFC 1570, 1367 | Daydreamer, January 1994. 1368 | 1369 | [6] ANSI X3.4-1977, "American National Standard Code for 1370 | Information Interchange", American National Standards 1371 | Institute, 1977. 1372 | 1373 | [7] Perez, "Byte-wise CRC Calculations", IEEE Micro, June 1983. 1374 | 1375 | [8] Morse, G., "Calculating CRC's by Bits and Bytes", Byte, 1376 | September 1986. 1377 | 1378 | 1379 | 1380 | 1381 | Simpson [Page 24] 1382 | RFC 1662 HDLC-like Framing July 1994 1383 | 1384 | 1385 | [9] LeVan, J., "A Fast CRC", Byte, November 1987. 1386 | 1387 | [10] Reynolds, J., and J. Postel, "Assigned Numbers", STD 2, RFC 1388 | 1340, USC/Information Sciences Institute, July 1992. 1389 | 1390 | 1391 | 1392 | Acknowledgements 1393 | 1394 | This document is the product of the Point-to-Point Protocol Working 1395 | Group of the Internet Engineering Task Force (IETF). Comments should 1396 | be submitted to the ietf-ppp@merit.edu mailing list. 1397 | 1398 | This specification is based on previous RFCs, where many 1399 | contributions have been acknowleged. 1400 | 1401 | The 32-bit FCS example code was provided by Karl Fox (Morning Star 1402 | Technologies). 1403 | 1404 | Special thanks to Morning Star Technologies for providing computing 1405 | resources and network access support for writing this specification. 1406 | 1407 | 1408 | 1409 | Chair's Address 1410 | 1411 | The working group can be contacted via the current chair: 1412 | 1413 | Fred Baker 1414 | Advanced Computer Communications 1415 | 315 Bollay Drive 1416 | Santa Barbara, California 93117 1417 | 1418 | fbaker@acc.com 1419 | 1420 | 1421 | Editor's Address 1422 | 1423 | Questions about this memo can also be directed to: 1424 | 1425 | William Allen Simpson 1426 | Daydreamer 1427 | Computer Systems Consulting Services 1428 | 1384 Fontaine 1429 | Madison Heights, Michigan 48071 1430 | 1431 | Bill.Simpson@um.cc.umich.edu 1432 | bsimpson@MorningStar.com 1433 | 1434 | 1435 | Simpson [Page 25] 1436 | 1437 | 1438 | 1439 | 1440 | 1441 | --------------------------------------------------------------------------------