diff --git a/frames/austria.raw b/frames/austria.raw index 67b3d113..1417688c 100644 --- a/frames/austria.raw +++ b/frames/austria.raw @@ -14,26 +14,91 @@ FF // Address (Broadcast address) DB // Encrypted 08 53 41 47 59 05 E6 D9 FD // System title 81 // Prefix for 1-byte length -F8 // Length (248) +F8 // Length (248), starting from 0xDB and including end byte 20 // Security tag 0010 0000, 0=Compression off, 0=Unicast, 1=Encryption, 0=No auth, 0000= Security Suite ID 00 72 00 76 // Frame counter -1F 16 66 EA 3C 81 67 0D 0C FE AC 1F 98 20 36 92 -DA 43 68 8F 58 58 23 7D D1 2F 02 C7 70 81 94 C6 -4D 24 EF DC 04 4A F4 F6 C6 61 92 5F 63 E4 17 78 -8A E3 A0 3B 8E 26 C8 9A FE 28 73 37 BA EF 13 BD -// 64 -50 78 AB EE E0 ED F5 4B 8C B7 2D 72 88 1A 30 54 -48 88 BE EE 7A 70 3A EA FA EC 90 88 39 08 8A 53 -14 37 16 CD 3F CA 7E 7B 68 46 5D 86 46 F6 CE 1F -28 32 A6 CF CB 4B 3A CB E7 05 7F 1A 52 06 DE E8 -// 128 -5B 68 02 A6 67 0E 0B EF 1E 6D 40 08 51 C7 C2 6E -7F AA C0 8A BD DC B6 1F F8 FA BA 54 CF C0 CC A4 -33 67 93 FA 0E DF 5E 64 89 72 CC 0E 85 19 F9 D7 -5E FF 0C DE B7 1E 20 A9 BB 90 22 2C D9 00 E2 DE -// 192 -17 E2 D9 25 45 BD B1 7B 62 C6 C4 0E A9 00 55 43 -12 75 85 C4 18 6B 22 D9 26 FB B3 25 28 39 0D 97 -// 224 -45 03 90 03 FF 05 AD E6 69 + +Some complete frames + +68 01 01 68 53 FF 00 01 67 DB 08 53 41 47 59 05 E6 D9 FD 81 F8 20 00 69 D1 4F D7 32 A2 4E 08 32 D8 38 62 C0 +91 7E 0F C3 BF 47 83 9A 1C 8F 81 D8 BC DB 8D C8 06 D6 8C B3 F2 7A 64 FF F5 AE F8 74 31 7F F0 D8 D8 30 57 57 +D7 23 C1 5A 50 23 A2 56 C5 4E 1B A3 C1 FC 75 65 75 31 4F EF D3 71 C3 E9 B4 1E CD 61 3E BF A7 27 26 A7 48 B4 +64 E3 75 B5 4A A3 57 B1 C1 8C E2 25 8F D9 14 C6 6F 9B 6B EE EF 7E 0B 3E 1C 7E 53 7F D4 A6 9D 5F 3E 5E 0B 4A +61 BA 45 8F A4 0E D5 2D 88 F3 51 76 1D 90 78 8E 0F 29 43 D4 DF 9E 05 88 26 1F C9 4A 1D F2 C2 95 84 57 A8 95 +19 EF 45 7B E8 17 CE 59 B1 78 1D 0D 82 E4 58 3F 1A 76 D2 01 CF 65 75 3C 53 97 78 C0 8A 8A 31 94 E5 15 01 81 +EB 58 E6 95 34 3D C9 46 AF FC 57 EE 5A 6D 5E 6F 6A 21 15 D1 6B 7D 4F E2 A1 83 C4 3A 81 CA 1E C9 D0 73 84 E1 +60 E5 0E 80 BC D5 58 2D B9 1A 16 + +// 19b +68 0D 0D 68 53 FF 11 01 67 CD 6B CB 69 13 53 FF 98 34 16 + +// 263b +68 01 01 68 53 FF 00 01 67 DB 08 53 41 47 59 05 +E6 D9 FD 81 F8 20 00 69 D1 50 55 28 2C E9 97 46 +82 61 19 3E 23 78 8A E6 E2 42 D1 D6 44 BA 2C 3C +55 0E 59 47 02 DC 8D D4 10 91 67 6B 76 9B F0 2F +42 BF D9 D2 FE A2 B3 AA 11 B1 BF 7B 8B B3 36 FE +7E B0 22 D7 60 10 48 1B 77 AA C2 DC 99 8D C2 C4 +5D 78 83 53 92 E8 66 44 CC 32 43 A9 E8 22 B2 0E +DF D8 39 B3 21 5B E6 A8 F1 83 5E 85 5A A3 5D 2B +92 ED 59 D7 24 2C CC 26 AB A6 0A FE 78 B0 E9 D3 +7C 6D B8 32 0F 36 C0 A0 9B A2 56 73 08 56 EE 9B +AD 7C CC F3 6B EC 13 63 55 2A 28 0E 7A 9B D9 2A +62 08 D5 9C AD E8 43 6D 7A CA 8B DD BF DB 3F E1 +88 3F 9D B9 7C 19 D3 68 8C 57 AB 82 46 4B 75 B8 +F3 9E 2C 22 06 2A 93 78 56 56 76 51 65 11 C7 12 +78 AB F2 97 97 51 2A 16 70 56 30 C9 12 00 08 BC +80 55 6E 44 51 A1 93 CD CF BA 9A DA CA 48 19 74 +E4 70 1E AD 63 99 16 + +68 0D 0D 68 53 FF 11 01 67 21 2B 32 52 74 00 40 41 90 16 + +68 01 01 68 53 FF 00 01 67 DB 08 53 +41 47 59 05 E6 D9 FD 81 F8 20 00 69 D1 51 A8 0C 89 6B 68 23 FE 94 57 3B AB 39 56 9F 26 E5 D9 A7 10 1C F3 E4 +0E 2E C6 8D 3F 0A FE 8B 54 ED AC AE 84 36 86 72 B6 AA 0D B3 94 88 C0 37 4C 75 09 53 6E 3F 44 E1 A9 28 F8 28 +7A D4 E0 65 0A FA 46 A9 08 A6 3A EE C6 20 B5 7C E8 F8 C1 92 40 84 54 2E F4 99 A9 04 86 42 9E 2F E3 D5 28 92 +99 80 EE 10 A4 96 7F BC 72 63 33 32 4E 1C FF 71 1C 4B 66 CE 48 9B 46 FF A5 36 F2 E6 FE 84 E8 38 56 65 2E 59 +79 4B 2A A1 84 B4 63 53 25 EA 02 F1 9B 50 A2 CA FB DE 22 BB E8 24 A5 70 52 F4 64 F5 93 D7 16 9D A1 90 6C F3 +04 C6 26 95 6E 60 3E C6 4A F6 BA BB AC 01 FE 23 74 26 3F 7E F1 05 BD 76 2A 7C 34 FA FC EF 1F 40 46 6E F1 6F +DA 36 75 00 E6 1A BF C2 B5 7F 34 D7 37 4C A0 6C CC A7 33 EF 9C 4A B0 E7 50 67 0A FB 85 18 25 31 67 DD 16 + +68 0D 0D 68 53 FF 11 01 67 CD 91 DA 34 7A CE 84 AD B0 16 + +68 01 01 68 53 FF 00 01 67 DB 08 53 41 47 59 05 E6 D9 +FD 81 F8 20 00 69 D1 52 7F 86 D1 DD 40 FD F7 2C 67 32 4F 5D 69 56 B0 8F FB 04 A9 E6 03 C6 A7 6B 7F 86 E7 BF +2D E6 44 09 42 BF C8 B3 92 D1 EB CA EF B2 78 56 14 F9 32 6B 8F A4 8E 44 DB 86 B8 D1 83 82 67 BC DF 3D 85 DE +42 9F FA 88 69 F4 06 C8 CB 4C A8 FF E6 7A 44 D3 29 97 90 CA 1B 22 F7 D8 8D 6E F7 69 34 1C 7F 6A B6 AA 95 96 +D0 48 95 02 0E 76 C0 BE 31 94 A1 72 66 30 E2 72 D9 82 30 1E 9A 81 DC 23 D7 AA 10 E5 91 19 AA 5B 97 F4 51 21 +17 97 E6 2E 25 D2 7C 8D E0 D8 10 19 ED B6 2A B7 29 EA 4B B1 35 F9 89 65 1A 4D 45 BE C5 3F E9 86 24 14 A3 5B +20 AD 9F 20 A5 57 9F DE 82 AD 58 4D 65 35 4D 4E 74 D2 0F EA DE 26 4F 48 AB 3D E0 91 0D 9C 1D E6 C8 2B 4F C2 +3B 53 21 2A 26 82 B2 7D 9F 93 83 91 9F 4C 0B 47 3A 48 60 7B A3 12 6D 0B 9A 40 77 88 16 + +68 0D 0D 68 53 FF 11 01 67 C7 91 CB B9 7B 23 AC 8D 7E 16 + +68 01 01 68 53 FF 00 01 67 DB 08 53 41 47 59 05 E6 D9 FD 81 F8 20 00 69 +D1 53 4F 0C 66 DD DE 97 31 C0 8B E5 2B CE C3 99 51 17 DE FE AB 9E 2F 1B 76 06 71 8D 2E 9D BF 54 6E E5 B3 7B +CE 05 34 58 22 6D 53 8F 95 6A 0A 6F EA 88 87 18 CD 29 B4 B1 99 8E 03 05 EB 1B 61 9B 36 09 99 E9 42 D4 D5 BC +E7 57 11 1E 95 FE 9B 76 CF C2 1A 52 EE 70 2B 1F 6A 52 CA 90 85 FF AB D1 F0 E5 20 90 82 3E 5E 2E 25 60 D0 FB +74 A1 7C A2 01 C2 AC 40 4A C6 0F 82 8C 0C CE 18 B8 18 1D EF 94 CC 54 16 D8 64 1F 60 B3 34 B8 0E 0C 10 56 11 +89 D6 1E 26 91 1F 85 C4 BE 55 69 96 DA D0 D6 9E 69 4A 8F 10 BF 37 97 68 55 3E 92 B1 F1 76 21 BF 34 03 54 DB +F1 2C 23 9F B7 79 02 E8 37 DD AF 15 79 70 C4 95 C9 28 90 4E 6F BC FA 52 E7 FE 27 B5 F3 6E C4 C3 C1 37 CF C9 +7C E8 B1 10 7F 6B 4D 49 88 CD 2B 60 22 51 D7 5C 5F E6 AA 0B E1 2B 16 + +68 0D 0D 68 53 FF 11 01 67 C5 B1 63 A0 24 39 F5 57 ED 16 + + + +68 01 01 68 53 FF 00 01 67 DB 08 53 41 47 59 05 E6 D9 FD 81 F8 20 00 69 D1 54 5B D2 4F 76 +37 23 43 D5 D1 C1 02 A8 E8 91 41 6D 6C F7 E5 10 1E D5 6A 1B 73 8C 54 B1 87 32 FB 85 A6 F1 80 CE 40 B9 48 5F +54 7F 1F 6A 18 F2 54 9E ED D9 18 33 DC 52 E2 14 E1 BF 65 FE 7B 58 9B 37 89 93 8D 98 AF 63 FB 90 FA A1 02 8B +80 32 BF 7D 9D 61 42 56 F0 2E 7A D1 1B B0 88 09 DC 21 F6 6E 0E 5D D3 D9 B8 66 69 96 2D 60 CC 55 2C F1 E3 A1 +5B 30 56 AB 57 FE 5D 6A 4F E4 40 CF A1 64 22 C7 4E 60 DD DA 8E 08 17 2F 49 F2 C8 0D F5 A0 ED 06 27 E0 A5 F9 +1C B2 7A 97 5E 59 0A CC C8 A9 25 AB 1F 6A B4 AD DE 8B FF AF 9A 4F 7F 44 D3 00 18 34 57 E3 15 A2 DB 4E D0 2A +20 54 61 60 47 50 B9 6C 8E D0 D4 7C 27 36 0C 89 0B 82 DD 14 2D BE A1 9C D9 DF 31 F9 BF 46 A4 14 26 4D 86 04 +28 54 44 F3 49 9C 12 CF 02 15 F9 4D B7 AB 4A B2 16 68 0D 0D 68 53 FF 11 01 67 70 74 A7 30 84 47 41 BE 50 16 +68 01 01 68 53 FF 00 01 67 DB 08 53 41 47 59 05 E6 D9 FD 81 F8 20 00 69 D1 55 59 04 1D D6 A4 96 28 33 5D A5 +A5 8F 22 2F 26 3C 77 F2 94 3C D7 ED 65 24 AA 5D 96 5E 95 71 E3 1C 99 83 40 31 A1 3F 2E BD 1F 32 A7 CE 5F 32 +59 05 55 AC C9 C0 9D 2A 59 AF 09 3A 81 61 BC DB 4D 60 CF 8D 65 BF 6E 06 E5 73 59 FE 1D 1C D3 1C 08 EC 5C 8E +57 AA 3E E6 06 6D 71 45 CE AB DC 5C 25 AC 15 09 BC A2 BD E8 12 C2 92 C9 9E D1 38 A4 02 59 38 98 38 63 3B 45 +B4 1A 20 4D 34 05 74 46 50 BE A5 87 D1 7A 5F 98 91 9A DA E9 FA 1E AA 72 10 58 3C 0A 5D 46 81 4E 57 B2 98 DF \ No newline at end of file diff --git a/src/ams/hdlc.cpp b/src/ams/hdlc.cpp index 49c9013b..836eae51 100644 --- a/src/ams/hdlc.cpp +++ b/src/ams/hdlc.cpp @@ -16,18 +16,21 @@ void mbus_hexdump(const uint8_t* buf, int len) { } int HDLC_validate(const uint8_t* d, int length, HDLCConfig* config, CosemDateTime* timestamp) { - HDLCHeader* h = (HDLCHeader*) d; - - // Length field (11 lsb of format) - int len = (ntohs(h->format) & 0x7FF) + 2; - if(len > length) + if(length < 10) return HDLC_FRAME_INCOMPLETE; + int len; int headersize = 3; int footersize = 1; + HDLCHeader* h = (HDLCHeader*) d; uint8_t* ptr = (uint8_t*) &h[1]; // Frame format type 3 if((h->format & 0xF0) == 0xA0) { + // Length field (11 lsb of format) + len = (ntohs(h->format) & 0x7FF) + 2; + if(len > length) + return HDLC_FRAME_INCOMPLETE; + HDLCFooter* f = (HDLCFooter*) (d + len - sizeof *f); footersize = sizeof *f; @@ -64,16 +67,11 @@ int HDLC_validate(const uint8_t* d, int length, HDLCConfig* config, CosemDateTim ptr += sizeof *t3; } else if((h->format & 0xF0) == 0x00) { - MbusFooter* f = (MbusFooter*) (d + len - sizeof *f); - footersize = sizeof *f; - - // First and last byte should be MBUS_HAN_TAG - if(h->flag != MBUS_START || f->flag != MBUS_END) + // First byte should be start byte + if(h->flag != MBUS_START) return HDLC_BOUNDRY_FLAG_MISSING; - // TODO: Verify FCS with crc8, not 16 - //if(ntohs(f->fcs) != crc16_x25(d + 1, len - sizeof *f - 1)) - // return HDLC_FCS_ERROR; + // TODO: Check that the two next bytes are identical // Ignore: Flag + Control field + Address ptr += 3; @@ -112,6 +110,11 @@ int HDLC_validate(const uint8_t* d, int length, HDLCConfig* config, CosemDateTim return ptr-d; } else if(((*ptr) & 0xFF) == 0xDB) { + if(length < headersize + 18) + return HDLC_FRAME_INCOMPLETE; + + uint8_t preheadersize = headersize; + ptr++; // Encrypted APDU // http://www.weigu.lu/tutorials/sensors2bus/04_encryption/index.html @@ -127,15 +130,23 @@ int HDLC_validate(const uint8_t* d, int length, HDLCConfig* config, CosemDateTim ptr += systemTitleLength; if(((*ptr) & 0xFF) == 0x81) { ptr++; + len = *ptr; // 1-byte payload length ptr++; } else if(((*ptr) & 0xFF) == 0x82) { - ptr++; - headersize++; - // 2-byte payload length - ptr += 2; - headersize += 2; + HDLCHeader* h = (HDLCHeader*) d; + + // Length field (11 lsb of format) + len = (ntohs(h->format) & 0xFFFF); + + ptr += 3; + headersize += 3; } + len += preheadersize; + if(len > length) + return HDLC_FRAME_INCOMPLETE; + + // TODO: FCS memcpy(config->additional_authenticated_data, ptr, 1);