New upstream version 0.20
Kyle Robertze
6 years ago
25 | 25 | endif() |
26 | 26 | |
27 | 27 | # Find tinfo for termcap functions |
28 | INCLUDE (CheckIncludeFiles) | |
29 | CHECK_INCLUDE_FILES(termcap.h HAVE_TERMCAP_H) | |
28 | 30 | find_library(tinfo_LIBRARY NAMES tinfo curses) |
29 | 31 | |
30 | 32 | # Architecture files |
19 | 19 | #include <netinet/in.h> |
20 | 20 | #include <mntent.h> |
21 | 21 | |
22 | #define LONG_TIMEOUT (60*1000) // 1 minutes | |
23 | #define SHORT_TIMEOUT (5*1000) // 5 seconds | |
24 | ||
22 | 25 | static void strtrim(char *s) |
23 | 26 | { |
24 | 27 | char *t; |
149 | 152 | |
150 | 153 | static int sg_ioctl(int fd, unsigned char *cdb, unsigned cdb_len, |
151 | 154 | unsigned char *buf, unsigned buf_len, |
152 | int dxfer_direction, | |
155 | int dxfer_direction, unsigned timeout, | |
153 | 156 | unsigned char *sense, unsigned sense_len, |
154 | 157 | unsigned *buf_read, unsigned *sense_read, |
155 | 158 | io_result_t *io_res) |
171 | 174 | hdr.dxferp = buf; |
172 | 175 | hdr.cmdp = cdb; |
173 | 176 | hdr.sbp = sense; |
174 | hdr.timeout = 10*60*1000; /* timeout in milliseconds */ | |
177 | hdr.timeout = timeout; /* timeout in milliseconds */ | |
175 | 178 | hdr.flags = SG_FLAG_LUN_INHIBIT; |
176 | 179 | hdr.pack_id = 0; |
177 | 180 | hdr.usr_ptr = 0; |
222 | 225 | } |
223 | 226 | |
224 | 227 | if (hdr.status != 0) { |
225 | // No sense but we have an error, consider it fatal | |
228 | // No sense but we have an error, consider it fatal if no data returned | |
226 | 229 | ERROR("IO failed with no sense: status=%d (%s) mask=%d driver=%d (%s) msg=%d host=%d (%s)", |
227 | 230 | hdr.status, status_code_to_str(hdr.status), |
228 | 231 | hdr.masked_status, |
229 | 232 | hdr.driver_status, driver_status_to_str(hdr.driver_status), |
230 | 233 | hdr.msg_status, |
231 | 234 | hdr.host_status, host_status_to_str(hdr.host_status)); |
232 | io_res->error = ERROR_UNKNOWN; | |
235 | ||
236 | if (*buf_read == 0) | |
237 | io_res->error = ERROR_UNKNOWN; | |
233 | 238 | return 0; |
234 | 239 | } |
235 | 240 | |
324 | 329 | |
325 | 330 | void disk_dev_cdb_out(disk_dev_t *dev, unsigned char *cdb, unsigned cdb_len, unsigned char *buf, unsigned buf_size, unsigned *buf_read, unsigned char *sense, unsigned sense_size, unsigned *sense_read, io_result_t *io_res) |
326 | 331 | { |
327 | sg_ioctl(dev->fd, cdb, cdb_len, buf, buf_size, SG_DXFER_TO_DEV, sense, sense_size, buf_read, sense_read, io_res); | |
332 | sg_ioctl(dev->fd, cdb, cdb_len, buf, buf_size, SG_DXFER_TO_DEV, LONG_TIMEOUT, sense, sense_size, buf_read, sense_read, io_res); | |
328 | 333 | } |
329 | 334 | |
330 | 335 | void disk_dev_cdb_in(disk_dev_t *dev, unsigned char *cdb, unsigned cdb_len, unsigned char *buf, unsigned buf_size, unsigned *buf_read, unsigned char *sense, unsigned sense_size, unsigned *sense_read, io_result_t *io_res) |
331 | 336 | { |
332 | sg_ioctl(dev->fd, cdb, cdb_len, buf, buf_size, SG_DXFER_FROM_DEV, sense, sense_size, buf_read, sense_read, io_res); | |
337 | sg_ioctl(dev->fd, cdb, cdb_len, buf, buf_size, SG_DXFER_FROM_DEV, LONG_TIMEOUT, sense, sense_size, buf_read, sense_read, io_res); | |
333 | 338 | } |
334 | 339 | |
335 | 340 | ssize_t disk_dev_read(disk_dev_t *dev, uint64_t offset_bytes, uint32_t len_bytes, void *buf, io_result_t *io_res) |
345 | 350 | memset(io_res, 0, sizeof(*io_res)); |
346 | 351 | |
347 | 352 | cdb_len = cdb_read_10(cdb, false, offset_bytes / dev->sector_size, len_bytes / dev->sector_size); |
348 | ret = sg_ioctl(dev->fd, cdb, cdb_len, buf, len_bytes, SG_DXFER_FROM_DEV, sense, sizeof(sense), &buf_read, &sense_read, io_res); | |
353 | ret = sg_ioctl(dev->fd, cdb, cdb_len, buf, len_bytes, SG_DXFER_FROM_DEV, LONG_TIMEOUT, sense, sizeof(sense), &buf_read, &sense_read, io_res); | |
349 | 354 | if (ret < 0) { |
350 | 355 | return -1; |
351 | 356 | } |
371 | 376 | memset(io_res, 0, sizeof(*io_res)); |
372 | 377 | |
373 | 378 | cdb_len = cdb_write_10(cdb, false, offset_bytes / dev->sector_size, len_bytes / dev->sector_size); |
374 | ret = sg_ioctl(dev->fd, cdb, cdb_len, buf, len_bytes, SG_DXFER_TO_DEV, sense, sizeof(sense), &buf_read, &sense_read, io_res); | |
379 | ret = sg_ioctl(dev->fd, cdb, cdb_len, buf, len_bytes, SG_DXFER_TO_DEV, LONG_TIMEOUT, sense, sizeof(sense), &buf_read, &sense_read, io_res); | |
375 | 380 | if (ret < 0) { |
376 | 381 | return -1; |
377 | 382 | } |
398 | 403 | memset(buf, 0, sizeof(buf)); |
399 | 404 | |
400 | 405 | cdb_len = cdb_read_capacity_10(cdb); |
401 | ret = sg_ioctl(dev->fd, cdb, cdb_len, buf, sizeof(buf), SG_DXFER_FROM_DEV, sense, sizeof(sense), &buf_read, &sense_read, &io_res); | |
406 | ret = sg_ioctl(dev->fd, cdb, cdb_len, buf, sizeof(buf), SG_DXFER_FROM_DEV, SHORT_TIMEOUT, sense, sizeof(sense), &buf_read, &sense_read, &io_res); | |
402 | 407 | if (ret < 0) |
403 | 408 | return -1; |
404 | 409 | |
418 | 423 | |
419 | 424 | // disk size is too large for READ CAPACITY 10, need to use READ CAPACITY 16 |
420 | 425 | cdb_len = cdb_read_capacity_16(cdb, sizeof(buf)); |
421 | ret = sg_ioctl(dev->fd, cdb, cdb_len, buf, sizeof(buf), SG_DXFER_FROM_DEV, sense, sizeof(sense), &buf_read, &sense_read, &io_res); | |
426 | ret = sg_ioctl(dev->fd, cdb, cdb_len, buf, sizeof(buf), SG_DXFER_FROM_DEV, SHORT_TIMEOUT, sense, sizeof(sense), &buf_read, &sense_read, &io_res); | |
422 | 427 | if (ret < 0) |
423 | 428 | return -1; |
424 | 429 | |
449 | 454 | *ata_buf_len = 0; |
450 | 455 | memset(buf, 0, sizeof(buf)); |
451 | 456 | |
452 | cdb_len = cdb_inquiry_simple(cdb, sizeof(buf)); | |
453 | ret = sg_ioctl(dev->fd, cdb, cdb_len, buf, sizeof(buf), SG_DXFER_FROM_DEV, sense, sizeof(sense), &buf_read, &sense_read, &io_res); | |
457 | cdb_len = cdb_inquiry_simple(cdb, 96); | |
458 | ret = sg_ioctl(dev->fd, cdb, cdb_len, buf, sizeof(buf), SG_DXFER_FROM_DEV, SHORT_TIMEOUT, sense, sizeof(sense), &buf_read, &sense_read, &io_res); | |
454 | 459 | if (ret < 0) |
455 | 460 | return -1; |
456 | 461 | |
457 | 462 | int device_type; |
458 | 463 | if (!parse_inquiry(buf, buf_read, &device_type, vendor, model, fw_rev, serial)) |
459 | 464 | { |
465 | INFO("Failed to parse the inquiry data"); | |
460 | 466 | return -1; |
461 | 467 | } |
462 | 468 | strtrim(vendor); |
473 | 479 | // For an ATA disk we need to get the proper ATA IDENTIFY response |
474 | 480 | memset(buf, 0, sizeof(buf)); |
475 | 481 | cdb_len = cdb_ata_identify(cdb); |
476 | ret = sg_ioctl(dev->fd, cdb, cdb_len, buf, sizeof(buf), SG_DXFER_FROM_DEV, sense, sizeof(sense), &buf_read, &sense_read, &io_res); | |
482 | ret = sg_ioctl(dev->fd, cdb, cdb_len, buf, sizeof(buf), SG_DXFER_FROM_DEV, SHORT_TIMEOUT, sense, sizeof(sense), &buf_read, &sense_read, &io_res); | |
477 | 483 | if (ret < 0) |
478 | 484 | return -1; |
479 | 485 | |
480 | ata_get_ata_identify_model((char*)buf, vendor); | |
486 | ata_get_ata_identify_model(buf, vendor); | |
481 | 487 | strtrim(vendor); |
482 | 488 | strcpy(model, vendor + strlen(vendor) + 1); |
483 | 489 | strtrim(model); |
484 | ata_get_ata_identify_fw_rev((char*)buf, fw_rev); | |
490 | ata_get_ata_identify_fw_rev(buf, fw_rev); | |
485 | 491 | strtrim(fw_rev); |
486 | ata_get_ata_identify_serial_number((char*)buf, serial); | |
492 | ata_get_ata_identify_serial_number(buf, serial); | |
487 | 493 | strtrim(serial); |
488 | 494 | |
489 | 495 | memcpy(ata_buf, buf, buf_read); |
509 | 509 | ERROR("Fatal error occurred, bailing out."); |
510 | 510 | return false; |
511 | 511 | } |
512 | if (io_res.error == ERROR_UNKNOWN) { | |
512 | if (io_res.error == ERROR_UNKNOWN || (s_errno != EIO && s_errno != 0)) { | |
513 | 513 | if (state->num_unknown_errors++ > 500) { |
514 | 514 | ERROR("%u unknown errors occurred, assuming fatal issue.", state->num_unknown_errors); |
515 | 515 | return false; |
517 | 517 | ERROR("Unknown error occurred, possibly untranslated error by storage layers, trying to continue."); |
518 | 518 | |
519 | 519 | } |
520 | ||
521 | if (s_errno != EIO && s_errno != 0) | |
522 | abort(); | |
523 | // TODO: What to do when no everything was read but errno is zero? | |
524 | 520 | } |
525 | 521 | else { |
526 | 522 | state->num_unknown_errors = 0; // Clear non-consecutive unknown errors |
12 | 12 | scsi_read_capacity_16 |
13 | 13 | scsi_inquiry |
14 | 14 | scsi_log_sense |
15 | scsi_mode_sense | |
16 | scsi_receive_diagnostics | |
17 | parse_scsi | |
18 | collect_raw_data | |
15 | 19 | test/libtestlib.a |
16 | 20 | |
17 | 21 | CMakeCache.txt |
3 | 3 | export(PACKAGE libscsicmd) |
4 | 4 | |
5 | 5 | include_directories("include") |
6 | add_compile_options(-Wall -Wextra -Wshadow -Wmissing-prototypes -Winit-self) | |
6 | add_compile_options(-Wall -Wextra -Wshadow -Wmissing-prototypes -Winit-self -g) | |
7 | 7 | add_definitions(-D_GNU_SOURCE -D_FORTIFY_SOURCE=2) |
8 | ||
9 | set(CMAKE_C_FLAGS_DEBUG "-Werror -O0 ${CMAKE_C_FLAGS_DEBUG}") | |
10 | set(CMAKE_C_FLAGS_RELEASE "-Wall -O3 ${CMAKE_C_FLAGS_RELEASE}") | |
8 | 11 | |
9 | 12 | add_subdirectory(src) |
10 | 13 | add_subdirectory(test) |
0 | libscsicmd | |
1 | ========== | |
0 | # libscsicmd | |
2 | 1 | |
3 | 2 | A library to create SCSI commands (CDBs) and parse the results, also for ATA commands and results. |
4 | 3 | |
6 | 5 | the commands themselves. The actual sending of the command is different between the different OSes and this library |
7 | 6 | tries to be OS agnostic. |
8 | 7 | |
9 | Build | |
10 | ===== | |
8 | ## Build | |
11 | 9 | |
12 | 10 | The build system is using cmake, you need to get it before you can build. |
13 | 11 | |
14 | 12 | To build, run: |
15 | cmake . && make | |
16 | 13 | |
17 | Author | |
18 | ====== | |
14 | cmake . && make | |
15 | ||
16 | For a developer debug build use: | |
17 | ||
18 | cmake -DCMAKE_BUILD_TYPE=Debug . | |
19 | ||
20 | To build for American Fuzzy Lop instrumentation: | |
21 | ||
22 | cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_COMPILER=/usr/bin/afl-gcc -DCMAKE_C_FLAGS=-DAFL_HARDEN=1 . | |
23 | ||
24 | ## Testing | |
25 | ||
26 | Testing is either done manually with some raw data collected from SCSI devices | |
27 | with test/collect\_raw\_data or with American Fuzzy Lop (AFL) for parsing | |
28 | problems. | |
29 | ||
30 | Using AFL: | |
31 | ||
32 | afl-fuzz -t 200 -i afl/testcase -o afl/finding test/parse_scsi | |
33 | ||
34 | ## Author | |
35 | ||
19 | 36 | Baruch Even <baruch@ev-en.org> |
0 | ,4d 00 55 00 00 00 00 40 00 00,,95 00 08 20 00 00 03 0c 00 10 9a 5e 00 08 02 32 00 00 02 32 00 01 03 14 00 00 16 c7 51 17 01 20 3b 37 06 46 00 00 00 00 0a 3b 31 ae 00 02 03 14 00 00 1e bc 51 17 01 20 45 0e 05 59 00 00 00 00 0b ef ff f5 00 03 03 14 00 00 29 a5 51 17 01 20 30 f7 01 4a 00 00 00 00 08 7d ea bc 00 04 03 14 00 00 31 95 51 17 01 20 30 f7 01 4e 00 00 00 00 08 7d ea c0 00 05 03 14 00 00 59 54 51 17 01 20 45 39 00 b7 00 00 00 00 0b f1 22 f3 00 06 03 14 00 02 10 4d 51 17 01 20 00 e1 01 a7 00 00 00 00 00 3c e8 11 00 07 03 14 00 02 8b 87 51 17 01 20 1d d9 07 13 00 00 00 00 05 4e 51 89 00 08 03 14 00 02 ad a8 51 17 01 20 55 1a 06 06 00 00 00 00 0e ad 67 8d 00 09 03 14 00 03 4a 6b 51 17 01 20 99 22 05 2c 00 00 00 00 19 c7 58 b0 00 0a 03 14 00 03 68 e6 51 17 01 20 88 b8 02 de 00 00 00 00 17 26 3a 94 00 0b 03 14 00 03 69 5f 51 17 01 40 17 58 04 d2 00 00 00 00 04 2f dc f6 00 0c 03 14 00 03 ac 6d 51 17 01 20 15 b2 02 54 00 00 00 00 03 d7 af b1 00 0d 03 14 00 03 de b4 51 17 01 20 00 e1 01 a3 00 00 00 00 00 3c e8 0d 00 0e 03 14 00 03 de b7 51 17 01 20 10 47 02 79 00 00 00 00 02 d9 5c d5 00 0f 03 14 00 03 de d5 51 17 01 20 ab a0 02 c8 00 00 00 00 1c c6 eb 8a 00 10 03 14 00 05 a8 fc 51 17 01 20 15 b2 02 51 00 00 00 00 03 d7 af ae 00 11 03 14 00 06 26 4e 51 17 01 20 15 b2 02 43 00 00 00 00 03 d7 af a0 00 12 03 14 00 06 33 f7 51 17 01 20 29 da 06 1f 00 00 00 00 07 53 23 4b 00 13 03 14 00 06 34 b2 51 17 01 20 17 38 01 ee 00 00 00 00 04 21 d7 6e 00 14 03 14 00 06 35 bc 51 17 01 20 01 d5 03 8f 00 00 00 00 00 57 bd 11 00 15 03 14 00 06 35 c5 51 17 01 20 1c 58 04 53 00 00 00 00 05 04 4a 6e 00 16 03 14 00 06 35 d0 51 17 01 20 3a c6 03 6b 00 00 00 00 0a 38 17 d3 00 17 03 14 00 06 36 cb 51 17 01 20 01 d5 03 8e 00 00 00 00 00 57 bd 10 00 18 03 14 00 06 3c ba 51 17 01 20 49 43 05 2e 00 00 00 00 0c ae da 39 00 19 03 14 00 06 6e 21 51 17 01 20 1d f8 02 78 00 00 00 00 05 4f 2a c6 00 1a 03 14 00 06 96 52 51 17 01 20 9d 87 04 b7 00 00 00 00 1a 71 05 cf 00 1b 03 14 00 06 97 30 51 17 01 20 2a a3 02 72 00 00 00 00 07 81 d5 26 00 1c 03 14 00 06 cb 8a 51 17 01 20 3e 2d 01 d2 00 00 00 00 0a cc 67 e2 00 1d 03 14 00 07 22 0b 51 17 01 20 1c 07 06 77 00 00 00 00 04 e4 bf 7b 00 1e 03 14 00 07 40 c7 51 17 01 20 86 3c 05 8d 00 00 00 00 16 c5 84 e5 00 1f 03 14 00 07 9d ea 51 17 01 20 19 70 02 06 00 00 00 00 04 70 f9 79 00 20 03 14 00 08 21 6f 51 17 01 20 01 8e 07 1f 00 00 00 00 00 39 4f e2 00 21 03 14 00 08 26 28 51 17 01 20 00 72 00 2c 00 00 00 00 00 0f c6 34 00 22 03 14 00 08 26 29 51 17 01 20 01 8e 07 12 00 00 00 00 00 39 4f d5 00 23 03 14 00 08 26 29 51 17 01 20 01 8e 07 13 00 00 00 00 00 39 4f d6 00 24 03 14 00 08 27 8c 51 17 01 20 00 72 00 27 00 00 00 00 00 0f c6 2f 00 25 03 14 00 08 3c d8 51 17 01 20 00 72 00 28 00 00 00 00 00 0f c6 30 00 26 03 14 00 08 3c ef 51 17 01 20 49 55 03 96 00 00 00 00 0c ae 5c e1 00 27 03 14 00 08 e6 f0 51 17 01 20 00 72 00 30 00 00 00 00 00 0f c6 38 00 28 03 14 00 09 9f eb 51 17 01 20 1c ce 02 64 00 00 00 00 05 07 94 ef 00 29 03 14 00 0a 4b aa 51 17 01 20 31 d6 06 4f 00 00 00 00 08 a7 65 49 00 2a 03 14 00 0a 4b af 51 17 01 20 3f 3d 00 16 00 00 00 00 0a f9 70 ad 00 2b 03 14 00 0b 70 fb 51 17 01 20 e9 d6 04 fc 00 00 00 00 26 72 2e ad 00 2c 03 14 00 0b 7d 35 51 17 01 20 3f 49 05 ee 00 00 00 00 0a f9 22 85 00 2d 03 14 00 0b 89 09 51 17 01 20 3c 2d 03 dd 00 00 00 00 0a 62 eb cd 00 2e 03 14 00 0b 8c 1f 51 17 01 20 00 ea 02 ce 00 00 00 00 00 3c a8 e7 00 2f 03 14 00 0b 94 3b 51 17 01 20 1d 18 04 a1 00 00 00 00 05 34 11 af 00 30 03 14 00 0b 9e fd 51 17 01 20 1e 6f 02 cf 00 00 00 00 05 52 7e b5 00 31 03 14 00 0b 9f 0a 51 17 01 20 44 26 02 43 00 00 00 00 0b d3 cd c3 00 32 03 14 00 0b a2 ce 51 17 01 20 01 69 05 7e 00 00 00 00 00 3a 55 bb 00 33 03 14 00 0b a7 5a 51 17 01 20 24 e8 00 97 00 00 00 00 06 77 04 e1 00 34 03 14 00 0b a8 b0 51 17 01 20 24 e8 00 9a 00 00 00 00 06 77 04 e4 00 35 03 14 00 0b f1 4c 51 17 01 21 2e 62 05 23 00 00 00 00 30 be 48 20 00 36 03 14 00 0c 09 56 51 17 01 20 35 88 01 66 00 00 00 00 09 58 a2 d3 00 37 03 14 00 0c 21 c0 51 17 01 21 2e 62 05 25 00 00 00 00 30 be 48 22 00 38 03 14 00 0c 2d f8 51 17 01 20 24 e8 00 ae 00 00 00 00 06 77 04 f8 00 39 03 14 00 0c 36 fe 51 17 01 20 9e 49 05 6c 00 00 00 00 1a 97 f7 b3 00 3a 03 14 00 0c 4d ef 51 17 01 20 24 e8 00 a9 00 00 00 00 06 77 04 f3 00 3b 03 14 00 0c 4f 52 51 17 01 20 4f 03 02 9e 00 00 00 00 0d a4 fe 0e 00 3c 03 14 00 0c 5b 5b 51 17 01 20 24 e8 00 9b 00 00 00 00 06 77 04 e5 00 3d 03 14 00 0c 81 ec 51 17 01 20 24 e8 00 aa 00 00 00 00 06 77 04 f4 00 3e 03 14 00 0c 81 ec 51 17 01 20 24 e8 00 ab 00 00 00 00 06 77 04 f5 00 3f 03 14 00 0c 88 98 51 17 01 21 2e 62 05 26 00 00 00 00 30 be 48 23 00 40 03 14 00 0c ab 23 51 17 01 20 00 03 02 0a 00 00 00 00 00 0c ae 1a 00 41 03 14 00 0c d8 7f 51 17 01 20 9e 49 05 70 00 00 00 00 1a 97 f7 b7 00 42 03 14 00 0c e0 ab 51 17 01 20 ed 32 00 6a 00 00 00 00 26 f5 c6 52 00 43 03 14 00 0c ef 0e 51 17 01 20 68 a7 03 a1 00 00 00 00 11 e1 48 c4 00 44 03 14 00 0d 00 1c 51 17 01 20 1e 6f 02 ce 00 00 00 00 05 52 7e b4 00 45 03 14 00 0d 06 3b 51 17 01 20 93 c6 06 5f 00 00 00 00 18 fa 98 dd 00 46 03 14 00 0d 0b ff 51 17 01 20 24 e8 00 99 00 00 00 00 06 77 04 e3 00 47 03 14 00 0d 6b 5f 51 17 01 20 05 9e 04 3a 00 00 00 00 00 f1 53 b6 00 48 03 14 00 0d 7b 58 51 17 01 20 24 e8 00 8f 00 00 00 00 06 77 04 d9 00 49 03 14 00 0d 86 9c 51 17 01 21 2e 62 05 27 00 00 00 00 30 be 48 24 00 4a 03 14 00 0d da 5b 51 17 01 20 29 b2 00 d2 00 00 00 00 07 52 05 fe 00 4b 03 14 00 0d da 81 51 17 01 20 9e 49 05 74 00 00 00 00 1a 97 f7 bb 00 4c 03 14 00 0e 1f 48 51 17 01 40 2d e3 06 44 00 00 00 00 08 09 eb 8e 00 4d 03 14 00 0e 4b 21 51 17 01 20 4f 03 02 9a 00 00 00 00 0d a4 fe 0a 00 4e 03 14 00 0e 5e 54 51 17 01 20 24 e8 00 9f 00 00 00 00 06 77 04 e9 00 4f 03 14 00 0e 71 d2 51 17 01 20 24 e8 00 9e 00 00 00 00 06 77 04 e8 00 50 03 14 00 0e 99 b1 51 17 01 20 29 b2 00 ce 00 00 00 00 07 52 05 fa 00 51 03 14 00 0f 10 6f 51 17 01 20 05 9e 04 3b 00 00 00 00 00 f1 53 b7 00 52 03 14 00 0f 13 48 51 17 01 21 87 1b 01 8e 00 00 00 00 3d 55 25 d6 00 53 03 14 00 0f 29 da 51 17 01 20 7f 65 00 1d 00 00 00 00 15 ac 02 e4 00 54 03 14 00 0f 71 11 51 17 01 20 1d 18 04 a0 00 00 00 00 05 34 11 ae 00 55 03 14 00 0f c7 1a 51 17 01 20 c2 04 05 15 00 00 00 00 20 3f 7a 16 00 56 03 14 00 0f ce ab 51 17 01 20 29 b2 00 d1 00 00 00 00 07 52 05 fd |
0 | ,4d 00 40 03 00 00 00 40 00 00,70 00 05 00 00 00 00 18 00 00 00 00 24 00 00 c0 00 03 00 00 f8 23 00 00 00 00 00 00 00 00 00 00 |
0 | ,1c 01 05 40 00 00,,05 00 01 50 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 46 41 14 0f 76 73 14 0f 76 73 14 0f 76 73 14 0f 76 73 14 0f 55 52 14 0f 55 52 14 0f 76 73 14 0f 76 73 14 0f 55 52 14 0f 55 52 14 0f 76 73 14 0f 76 73 14 0f 55 52 14 0f 55 52 14 0f 76 73 14 0f 76 73 14 0f 55 52 14 0f 55 52 14 0f 76 73 14 0f 76 73 14 0f 00 00 00 00 0e 0a 0a 14 0e 0a 0a 14 0e 0a 0a 14 0e 0a 0a 14 0e 0a 0a 14 0e 0a 0a 14 0e 0a 0a 14 0e 0a 0a 14 0e 0a 0a 14 0e 0a 0a 14 0e 0a 0a 14 0e 0a 0a 14 0e 0a 0a 14 0e 0a 0a 14 0e 0a 0a 14 0e 0a 0a 14 0e 0a 0a 14 0e 0a 0a 14 0e 0a 0a 14 0e 0a 0a 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |
0 | ,5a 00 3f ff 00 00 00 10 00 00,,00 3a 00 00 00 00 00 00 02 0e 00 00 00 00 00 00 27 10 00 09 00 00 00 00 0a 0a 00 00 00 00 00 00 00 00 00 00 18 06 06 00 00 00 00 00 19 0e 46 00 07 d0 00 00 00 00 00 00 00 00 00 00 |
0 | ,25 00 00 00 00 00 00 00 00 00,, |
0 | ,4d 00 40 ff 00 00 00 40 00 00,,00 00 00 4c 00 00 00 ff 02 00 02 ff 03 00 03 ff 05 00 05 ff 06 00 06 ff 0c 00 0c ff 0d 00 0d ff 0e 00 0e ff 0f 00 0f ff 10 00 10 ff 11 00 11 ff 15 00 15 ff 18 00 18 ff 19 00 19 ff 1a 00 1a ff 2f 00 2f ff 30 00 30 ff 31 00 31 ff 38 00 38 ff |
0 | ,9e 10 00 00 00 00 00 00 00 00 00 00 02 00 00 00,, |
0 | ,4d 00 40 ff 00 00 00 40 00 00,,40 ff 00 44 00 00 00 ff 02 00 02 ff 03 00 03 ff 05 00 05 ff 06 00 06 ff 0d 00 0d ff 0e 00 0e ff 0f 00 0f ff 10 00 10 ff 11 00 11 ff 15 00 15 ff 18 00 18 ff 1a 00 1a ff 2f 00 2f ff 30 00 30 ff 31 00 31 ff 37 00 37 ff |
0 | ,1c 01 00 40 00 00,,00 00 00 0a 00 01 02 04 05 07 0d 0e 0f 1d |
0 | ,37 00 0a 00 00 00 00 02 00 00,,00 0a 00 00 |
0 | ,1c 01 00 40 00 00,,00 00 00 02 00 3f |
0 | ,1a 00 3f ff ff 00,,37 00 00 08 00 00 00 00 00 00 02 00 01 0a 80 00 00 00 00 00 00 00 00 00 08 12 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0a 0a 02 00 00 00 00 00 ff ff 00 1e 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |
0 | ,b7 14 00 00 00 00 00 00 02 00 00 00,,00 16 00 00 00 00 17 f8 00 00 00 72 00 00 00 33 00 00 00 0f 00 00 00 70 00 00 00 17 00 00 00 cc 00 00 00 17 00 00 00 d0 00 00 00 61 00 00 01 85 00 00 00 0f 00 00 02 00 00 00 00 00 00 00 02 02 00 00 00 00 00 00 02 03 00 00 00 01 00 00 02 02 00 00 00 01 00 00 02 03 00 00 00 02 00 00 02 02 00 00 00 02 00 00 02 03 00 00 00 03 00 00 02 02 00 00 00 03 00 00 02 03 00 00 00 04 00 00 02 02 00 00 00 04 00 00 02 03 00 00 00 05 00 00 02 02 00 00 00 05 00 00 02 03 00 00 00 06 00 00 02 02 00 00 00 06 00 00 02 03 00 00 00 07 00 00 02 02 00 00 00 07 00 00 02 03 00 00 00 08 00 00 02 02 00 00 00 08 00 00 02 03 00 00 00 09 00 00 02 02 00 00 00 09 00 00 02 03 00 00 00 0a 00 00 02 02 00 00 00 0a 00 00 02 03 00 00 00 0b 00 00 02 02 00 00 00 0b 00 00 02 03 00 00 00 0c 00 00 02 02 00 00 00 0c 00 00 02 03 00 00 00 0d 00 00 02 02 00 00 00 0d 00 00 02 03 00 00 00 0e 00 00 02 02 00 00 00 0e 00 00 02 03 00 00 00 0f 00 00 02 02 00 00 00 0f 00 00 02 03 00 00 00 10 00 00 02 02 00 00 00 10 00 00 02 03 00 00 00 11 00 00 02 02 00 00 00 11 00 00 02 03 00 00 00 12 00 00 02 02 00 00 00 12 00 00 02 03 00 00 00 13 00 00 02 02 00 00 00 13 00 00 02 03 00 00 00 14 00 00 02 02 00 00 00 14 00 00 02 03 00 00 00 15 00 00 02 02 00 00 00 15 00 00 02 03 00 00 00 16 00 00 02 02 00 00 00 16 00 00 02 03 00 00 00 17 00 00 02 02 00 00 00 17 00 00 02 03 00 00 00 18 00 00 02 02 00 00 00 18 00 00 02 03 00 00 00 19 00 00 02 02 00 00 00 19 00 00 02 03 00 00 00 1a 00 00 02 02 00 00 00 1a 00 00 02 03 00 00 00 1b 00 00 02 02 00 00 00 1b 00 00 02 0 |
0 | ,1c 01 1b 40 00 00,,1b 00 00 04 00 01 00 03 |
0 | ,25 00 00 00 00 00 00 00 00 00,70 00 04 00 00 00 00 18 00 00 00 00 29 07 00 00 00 00 00 00 f5 19 00 00 00 00 00 00 00 00 00 00, |
0 | ,37 00 0e 00 00 00 00 00 08 00,70 00 01 00 00 00 00 10 00 00 00 00 1c 00 00 80 00 00 00 21 1c 00 00 00,00 0c 00 00 |
0 | ,37 00 08 00 00 00 00 00 08 00,,00 00 00 05 00 3f 45 46 82 27 21 60 00 00 02 00 81 0a c4 01 00 00 00 00 00 00 0c 00 82 0e 00 00 00 00 00 00 01 f4 00 00 00 00 00 00 03 16 00 00 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 40 00 00 00 04 16 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 87 0a 04 01 00 00 00 00 00 00 0c 00 88 12 10 00 ff ff 00 00 ff ff ff ff 00 00 00 00 00 00 00 00 8a 0a 00 10 00 00 00 00 00 00 00 06 ca 01 00 1c 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ca 02 01 8c 00 00 00 00 00 00 00 00 00 00 00 00 80 00 00 00 00 00 ff ff 00 00 00 00 00 00 00 00 ff ff ff ff ff ff ff ff 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |
0 | ,37 00 0a 00 00 00 00 00 08 00,70 00 01 00 00 00 00 18 00 00 00 00 1c 02 00 c0 00 02 00 00 17 48 00 00 00 00 00 00 00 00 00 00,00 0e 00 00 |
0 | ,1c 01 01 40 00 00,,01 04 04 68 00 00 00 08 11 00 0a ea 50 06 04 80 a0 1c 19 3e 45 4d 43 20 20 20 20 20 44 65 72 72 69 6e 67 65 72 20 4c 43 43 20 20 20 30 42 33 30 07 81 42 02 00 01 02 55 53 31 44 30 31 31 30 35 30 30 30 35 39 00 00 05 40 a6 20 31 35 31 20 53 58 50 20 33 36 78 36 47 73 65 63 00 40 20 20 33 31 34 20 53 58 50 20 33 36 78 36 47 73 65 63 00 40 21 20 32 32 32 20 53 58 50 20 33 36 78 36 47 73 65 63 00 40 22 20 32 31 36 20 53 58 50 20 33 36 78 36 47 73 65 63 00 40 23 20 30 32 31 20 43 44 45 46 00 00 00 00 00 00 00 00 00 10 02 80 00 01 03 00 02 01 04 80 02 00 05 01 40 00 06 03 40 00 07 85 00 00 08 86 00 00 09 02 00 00 0a 02 01 00 0b 02 02 00 0c 02 03 00 0d 02 04 00 0e 02 05 00 0f 02 06 00 10 02 07 00 11 04 00 00 02 c0 c1 05 4c 43 43 20 42 11 01 06 b5 50 06 04 80 d8 21 42 be 45 4d 43 20 20 20 20 20 44 65 72 72 69 6e 67 65 72 20 4c 43 43 20 20 20 30 42 33 30 07 80 41 02 01 00 01 4a 57 58 45 4c 31 33 30 35 30 30 35 35 31 00 00 05 5a 06 20 31 35 31 20 53 58 50 20 33 36 78 36 47 73 65 63 00 5a 00 20 33 31 34 20 53 58 50 20 33 36 78 36 47 73 65 63 00 5a 01 20 32 32 32 20 53 58 50 20 33 36 78 36 47 73 65 63 00 5a 02 20 32 31 36 20 53 58 50 20 33 36 78 36 47 73 65 63 00 5a 03 20 30 32 31 20 43 44 45 46 00 00 00 00 00 00 00 00 00 03 12 00 03 01 13 80 03 00 14 03 5a 00 01 c2 05 4c 43 43 20 41 11 02 04 4f 50 06 04 80 00 00 00 00 45 4d 43 20 20 20 20 20 44 65 72 72 69 6e 67 65 72 20 45 6e 63 6c 20 20 30 30 31 31 0e 1f 4d 02 02 02 00 43 4b 4d 30 30 31 33 31 38 30 31 37 35 38 00 00 00 02 00 00 01 01 01 80 01 00 01 c3 07 43 68 61 73 73 69 73 11 03 03 6a 50 06 04 80 00 00 00 00 45 4d 43 20 20 20 20 20 30 30 30 42 30 30 31 39 00 00 00 00 00 00 00 00 32 41 31 30 02 81 42 02 00 04 33 41 43 37 42 30 31 33 30 32 31 37 38 31 39 20 20 01 86 a4 20 35 2e 33 33 53 58 50 33 36 78 36 47 00 00 00 00 00 02 15 00 04 01 16 80 04 00 01 c4 0e 50 6f 77 65 72 20 53 75 70 70 6c 79 20 42 11 04 03 56 50 06 04 80 00 00 00 00 45 4d 43 20 20 20 20 20 45 4d 43 20 44 45 52 52 49 4e 47 45 52 20 50 53 43 30 33 30 02 80 41 02 01 03 32 41 43 37 42 30 31 33 30 32 31 37 35 31 38 20 20 00 02 17 00 05 01 18 80 05 00 01 c5 0e 50 6f 77 65 72 20 53 75 70 70 6c 79 20 41 17 19 00 0c 04 01 00 0e 0e 01 00 05 81 25 00 0c 18 01 00 0a 07 01 00 0c 19 0a 00 0f 0c 02 00 0d 0c 01 00 0c 10 01 00 08 04 01 01 0e 0e 01 01 05 81 08 01 0c 18 01 01 0a 07 01 01 0c 19 0a 01 0f 0e 01 02 09 03 00 02 0d 04 01 02 0e 19 1a 02 0f 03 02 03 0d 04 02 03 0e 02 01 03 0e 03 02 04 0d 04 02 04 0e 02 01 04 0e 41 72 72 61 79 20 44 65 76 69 63 65 54 65 6d 70 2e 20 53 65 6e 73 6f 72 20 42 4c 43 43 20 42 45 78 70 61 6e 64 65 72 20 50 68 79 45 78 70 61 6e 64 65 72 20 42 43 6f 6e 74 72 6f 6c 6c 65 72 20 42 53 41 53 20 43 6f 6e 6e 65 63 74 6f 72 20 42 44 69 73 70 6c 61 79 20 47 72 65 65 6e 44 69 73 70 6c 61 79 20 42 6c 75 65 4c 61 6e 67 75 61 67 65 54 65 6d 70 2e 20 53 65 6e 73 6f 72 20 41 4c 43 43 20 41 45 78 70 61 6e 64 65 72 20 50 68 79 45 78 70 61 6e 64 65 72 20 41 43 6f 6e 74 72 6f 6c 6c 65 72 20 41 53 41 53 20 43 6f 6e 6e 65 63 74 6f 72 20 41 45 6e 63 6c 6f 73 75 72 65 43 6f 6f 6c 69 6e 67 20 46 61 6e 20 4d 54 65 6d 70 2e 20 53 65 6e 73 6f 72 20 4d 53 41 53 20 43 6f 6e 6e 65 63 74 6f 72 20 4d 43 6f 6f 6c 69 6e 67 20 46 61 6e 20 42 54 65 6d 70 2e 20 53 65 6e 73 6f 72 20 42 50 6f 77 65 72 20 53 75 70 70 6c 79 20 42 43 6f 6f 6c 69 6e 67 20 46 61 6e 20 41 54 65 6d 70 2e 20 53 65 6e 73 6f 72 20 41 50 6f 77 65 72 20 53 75 70 70 6c 79 20 41 |
0 | ,1c 01 00 40 00 00,,00 00 00 03 00 3f 82 |
0 | ,1c 01 00 40 00 00,70 00 02 00 00 00 00 18 00 00 00 00 31 01 00 00 00 00 00 00 f5 07 00 00 00 00 00 00 00 00 00 00, |
0 | ,4d 00 40 ff 00 00 00 40 00 00,,40 ff 00 04 00 ff 34 ff 00 00 00 00 |
0 | ,1c 01 00 40 00 00,,00 00 00 11 00 01 02 04 05 0a 0e 10 11 80 81 82 83 90 91 f0 f1 |
0 | ,1c 01 04 40 00 00,,04 00 01 fa 30 37 3a 30 32 3a 31 31 3a 35 34 3a 35 33 37 20 74 6e 6c 2f 74 75 6e 6e 65 6c 5f 73 74 65 5f 72 65 63 76 5f 64 69 61 67 5f 6d 73 67 5f 68 61 6e 64 6c 65 72 3a 20 74 75 6e 6e 65 6c 69 6e 67 20 52 45 43 56 20 44 49 41 47 4e 4f 53 54 49 43 20 72 65 63 65 69 76 65 64 20 66 72 6f 6d 20 53 54 45 2e 0a 30 37 3a 30 32 3a 31 31 3a 35 34 3a 37 34 38 20 64 65 76 2f 70 68 79 2e 32 32 3a 20 72 65 61 64 79 0a 30 37 3a 30 32 3a 31 31 3a 35 34 3a 37 35 31 20 64 65 76 2f 70 68 79 2e 32 32 3a 20 6c 69 6e 6b 20 72 65 61 64 79 0a 30 37 3a 30 32 3a 31 31 3a 35 34 3a 37 35 38 20 64 65 76 2f 70 68 79 2e 32 32 3a 20 72 61 74 65 20 75 6e 6b 6e 6f 77 6e 2d 3e 36 47 0a 30 37 3a 30 32 3a 31 31 3a 35 34 3a 37 36 32 20 64 65 76 2f 70 68 79 2e 32 32 3a 20 61 74 74 61 63 68 65 64 20 70 68 79 20 69 64 20 30 78 66 66 2d 3e 30 78 30 30 0a 30 37 3a 30 32 3a 31 31 3a 35 34 3a 37 38 37 20 45 53 45 53 3a 20 66 77 64 6c 20 70 72 74 74 6e 20 63 6e 74 72 6c 20 73 74 61 74 75 73 20 72 65 63 65 69 76 65 64 3a 20 61 63 74 69 76 65 3a 20 31 20 64 61 74 61 3a 20 30 20 69 6d 67 30 63 72 63 3a 20 30 78 62 64 20 69 6d 67 31 63 72 63 3a 20 30 78 61 34 0a 30 37 3a 30 32 3a 31 31 3a 35 36 3a 37 37 35 20 45 4d 43 20 53 54 45 3a 20 54 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 56 50 44 20 70 61 67 65 73 20 77 61 73 20 31 30 2c 20 6e 6f 77 20 31 30 0a 30 37 3a 30 32 3a 31 31 3a 35 36 3a 37 38 34 20 45 4d 43 20 53 54 45 3a 20 54 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 56 50 44 20 70 61 67 65 73 20 77 61 73 20 31 30 2c 20 6e 6f 77 20 31 30 0a |
0 | ,1c 01 04 40 00 00,,04 00 0a a9 30 35 3a 31 37 3a 33 36 3a 35 38 3a 33 38 38 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 30 3a 20 73 65 6e 74 20 73 61 73 61 64 64 72 20 74 6f 20 70 65 65 72 0a 30 35 3a 31 37 3a 33 37 3a 30 31 3a 33 32 36 20 65 78 70 61 6e 64 65 72 3a 20 72 65 63 76 64 20 6d 73 67 20 74 79 70 65 3a 20 32 0a 30 35 3a 31 37 3a 33 37 3a 30 31 3a 33 33 30 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 31 3a 20 70 72 6f 63 65 73 73 20 70 63 64 20 73 65 6e 64 20 6d 73 67 0a 30 35 3a 31 37 3a 33 37 3a 30 31 3a 33 34 31 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 31 3a 20 73 65 6e 74 20 66 77 72 65 76 20 74 6f 20 70 65 65 72 0a 30 35 3a 31 37 3a 33 37 3a 30 31 3a 33 35 30 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 31 3a 20 73 65 6e 74 20 73 61 73 61 64 64 72 20 74 6f 20 70 65 65 72 0a 30 35 3a 31 37 3a 33 38 3a 35 38 3a 35 38 32 20 65 78 70 61 6e 64 65 72 3a 20 72 65 63 76 64 20 6d 73 67 20 74 79 70 65 3a 20 32 0a 30 35 3a 31 37 3a 33 38 3a 35 38 3a 35 38 36 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 30 3a 20 70 72 6f 63 65 73 73 20 70 63 64 20 73 65 6e 64 20 6d 73 67 0a 30 35 3a 31 37 3a 33 38 3a 35 38 3a 35 39 36 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 30 3a 20 73 65 6e 74 20 66 77 72 65 76 20 74 6f 20 70 65 65 72 0a 30 35 3a 31 37 3a 33 38 3a 35 38 3a 36 30 35 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 30 3a 20 73 65 6e 74 20 73 61 73 61 64 64 72 20 74 6f 20 70 65 65 72 0a 30 35 3a 31 37 3a 33 39 3a 30 31 3a 31 30 37 20 65 78 70 61 6e 64 65 72 3a 20 72 65 63 76 64 20 6d 73 67 20 74 79 70 65 3a 20 32 0a 30 35 3a 31 37 3a 33 39 3a 30 31 3a 31 31 31 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 31 3a 20 70 72 6f 63 65 73 73 20 70 63 64 20 73 65 6e 64 20 6d 73 67 0a 30 35 3a 31 37 3a 33 39 3a 30 31 3a 31 32 30 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 31 3a 20 73 65 6e 74 20 66 77 72 65 76 20 74 6f 20 70 65 65 72 0a 30 35 3a 31 37 3a 33 39 3a 30 31 3a 31 33 32 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 31 3a 20 73 65 6e 74 20 73 61 73 61 64 64 72 20 74 6f 20 70 65 65 72 0a 30 35 3a 31 37 3a 34 30 3a 35 38 3a 35 38 36 20 65 78 70 61 6e 64 65 72 3a 20 72 65 63 76 64 20 6d 73 67 20 74 79 70 65 3a 20 32 0a 30 35 3a 31 37 3a 34 30 3a 35 38 3a 35 39 30 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 30 3a 20 70 72 6f 63 65 73 73 20 70 63 64 20 73 65 6e 64 20 6d 73 67 0a 30 35 3a 31 37 3a 34 30 3a 35 38 3a 36 30 31 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 30 3a 20 73 65 6e 74 20 66 77 72 65 76 20 74 6f 20 70 65 65 72 0a 30 35 3a 31 37 3a 34 30 3a 35 38 3a 36 31 30 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 30 3a 20 73 65 6e 74 20 73 61 73 61 64 64 72 20 74 6f 20 70 65 65 72 0a 30 35 3a 31 37 3a 34 31 3a 30 31 3a 31 33 34 20 65 78 70 61 6e 64 65 72 3a 20 72 65 63 76 64 20 6d 73 67 20 74 79 70 65 3a 20 32 0a 30 35 3a 31 37 3a 34 31 3a 30 31 3a 31 33 38 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 31 3a 20 70 72 6f 63 65 73 73 20 70 63 64 20 73 65 6e 64 20 6d 73 67 0a 30 35 3a 31 37 3a 34 31 3a 30 31 3a 31 34 37 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 31 3a 20 73 65 6e 74 20 66 77 72 65 76 20 74 6f 20 70 65 65 72 0a 30 35 3a 31 37 3a 34 31 3a 30 31 3a 31 35 37 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 31 3a 20 73 65 6e 74 20 73 61 73 61 64 64 72 20 74 6f 20 70 65 65 72 0a 30 35 3a 31 37 3a 34 32 3a 35 38 3a 35 35 30 20 65 78 70 61 6e 64 65 72 3a 20 72 65 63 76 64 20 6d 73 67 20 74 79 70 65 3a 20 32 0a 30 35 3a 31 37 3a 34 32 3a 35 38 3a 35 35 34 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 30 3a 20 70 72 6f 63 65 73 73 20 70 63 64 20 73 65 6e 64 20 6d 73 67 0a 30 35 3a 31 37 3a 34 32 3a 35 38 3a 35 36 34 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 30 3a 20 73 65 6e 74 20 66 77 72 65 76 20 74 6f 20 70 65 65 72 0a 30 35 3a 31 37 3a 34 32 3a 35 38 3a 35 37 33 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 30 3a 20 73 65 6e 74 20 73 61 73 61 64 64 72 20 74 6f 20 70 65 65 72 0a 30 35 3a 31 37 3a 34 33 3a 30 31 3a 31 34 36 20 65 78 70 61 6e 64 65 72 3a 20 72 65 63 76 64 20 6d 73 67 20 74 79 70 65 3a 20 32 0a 30 35 3a 31 37 3a 34 33 3a 30 31 3a 31 35 30 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 31 3a 20 70 72 6f 63 65 73 73 20 70 63 64 20 73 65 6e 64 20 6d 73 67 0a 30 35 3a 31 37 3a 34 33 3a 30 31 3a 31 36 31 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 31 3a 20 73 65 6e 74 20 66 77 72 65 76 20 74 6f 20 70 65 65 72 0a 30 35 3a 31 37 3a 34 33 3a 30 31 3a 31 37 30 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 31 3a 20 73 65 6e 74 20 73 61 73 61 64 64 72 20 74 6f 20 70 65 65 72 0a 30 35 3a 31 37 3a 34 34 3a 35 38 3a 35 38 38 20 65 78 70 61 6e 64 65 72 3a 20 72 65 63 76 64 20 6d 73 67 20 74 79 70 65 3a 20 32 0a 30 35 3a 31 37 3a 34 34 3a 35 38 3a 35 39 32 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 30 3a 20 70 72 6f 63 65 73 73 20 70 63 64 20 73 65 6e 64 20 6d 73 67 0a 30 35 3a 31 37 3a 34 34 3a 35 38 3a 36 30 33 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 30 3a 20 73 65 6e 74 20 66 77 72 65 76 20 74 6f 20 70 65 65 72 0a 30 35 3a 31 37 3a 34 34 3a 35 38 3a 36 31 32 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 30 3a 20 73 65 6e 74 20 73 61 73 61 64 64 72 20 74 6f 20 70 65 65 72 0a 30 35 3a 31 37 3a 34 35 3a 30 31 3a 33 33 38 20 65 78 70 61 6e 64 65 72 3a 20 72 65 63 76 64 20 6d 73 67 20 74 79 70 65 3a 20 32 0a 30 35 3a 31 37 3a 34 35 3a 30 31 3a 33 34 32 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 31 3a 20 70 72 6f 63 65 73 73 20 70 63 64 20 73 65 6e 64 20 6d 73 67 0a 30 35 3a 31 37 3a 34 35 3a 30 31 3a 33 35 31 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 31 3a 20 73 65 6e 74 20 66 77 72 65 76 20 74 6f 20 70 65 65 72 0a 30 35 3a 31 37 3a 34 35 3a 30 31 3a 33 36 30 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 31 3a 20 73 65 6e 74 20 73 61 73 61 64 64 72 20 74 6f 20 70 65 65 72 0a 30 35 3a 31 37 3a 34 36 3a 35 38 3a 37 36 34 20 65 78 70 61 6e 64 65 72 3a 20 72 65 63 76 64 20 6d 73 67 20 74 79 70 65 3a 20 32 0a 30 35 3a 31 37 3a 34 36 3a 35 38 3a 37 36 38 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 30 3a 20 70 72 6f 63 65 73 73 20 70 63 64 20 73 65 6e 64 20 6d 73 67 0a 30 35 3a 31 37 3a 34 36 3a 35 38 3a 37 38 30 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 30 3a 20 73 65 6e 74 20 66 77 72 65 76 20 74 6f 20 70 65 65 72 0a 30 35 3a 31 37 3a 34 36 3a 35 38 3a 37 38 38 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 30 3a 20 73 65 6e 74 20 73 61 73 61 64 64 72 20 74 6f 20 70 65 65 72 0a 30 35 3a 31 37 3a 34 37 3a 30 31 3a 32 32 32 20 65 78 70 61 6e 64 65 72 3a 20 72 65 63 76 64 20 6d 73 67 20 74 79 70 65 3a 20 32 0a 30 35 3a 31 37 3a 34 37 3a 30 31 3a 32 32 37 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 31 3a 20 70 72 6f 63 65 73 73 20 70 63 64 20 73 65 6e 64 20 6d 73 67 0a 30 35 3a 31 37 3a 34 37 3a 30 31 3a 32 33 37 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 31 3a 20 73 65 6e 74 20 66 77 72 65 76 20 74 6f 20 70 65 65 72 0a 30 35 3a 31 37 3a 34 37 3a 30 31 3a 32 34 38 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 31 3a 20 73 65 6e 74 20 73 61 73 61 64 64 72 20 74 6f 20 70 65 65 72 0a 30 35 3a 31 37 3a 34 37 3a 30 31 3a 39 32 38 20 45 4d 43 20 53 54 45 3a 20 54 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 56 50 44 20 70 61 67 65 73 20 77 61 73 20 31 30 2c 20 6e 6f 77 20 31 30 0a 30 35 3a 31 37 3a 34 37 3a 30 31 3a 39 33 35 20 45 4d 43 20 53 54 45 3a 20 54 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 56 50 44 20 70 61 67 65 73 20 77 61 73 20 31 30 2c 20 6e 6f 77 20 31 30 0a 30 35 3a 31 37 3a 34 37 3a 30 33 3a 38 34 32 20 74 6e 6c 2f 74 75 6e 6e 65 6c 5f 73 74 65 5f 72 65 63 76 5f 64 69 61 67 5f 6d 73 67 5f 68 61 6e 64 6c 65 72 3a 20 74 75 6e 6e 65 6c 69 6e 67 20 52 45 43 56 20 44 49 41 47 4e 4f 53 54 49 43 20 72 65 63 65 69 76 65 64 20 66 72 6f 6d 20 53 54 45 2e 0a 30 35 3a 31 37 3a 34 37 3a 30 34 3a 30 35 32 20 45 53 45 53 3a 20 66 77 64 6c 20 70 72 74 74 6e 20 63 6e 74 72 6c 20 73 74 61 74 75 73 20 72 65 63 65 69 76 65 64 3a 20 61 63 74 69 76 65 3a 20 30 20 64 61 74 61 3a 20 31 20 69 6d 67 30 63 72 63 3a 20 30 78 62 64 20 69 6d 67 31 63 72 63 3a 20 30 78 65 34 0a 30 35 3a 31 37 3a 34 37 3a 34 39 3a 34 34 34 20 45 4d 43 20 53 54 45 3a 20 54 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 56 50 44 20 70 61 67 65 73 20 77 61 73 20 31 30 2c 20 6e 6f 77 20 31 30 0a 30 35 3a 31 37 3a 34 37 3a 34 39 3a 34 35 33 20 45 4d 43 20 53 54 45 3a 20 54 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 56 50 44 20 70 61 67 65 73 20 77 61 73 20 31 30 2c 20 6e 6f 77 20 31 30 0a |
0 | ,b7 0d 00 00 00 00 00 00 02 00 00 00,,00 0e 00 00 00 00 01 98 00 00 00 00 00 00 00 b6 00 00 00 00 00 00 04 62 00 00 00 00 00 00 00 70 00 00 00 00 00 00 00 98 00 00 00 00 00 00 02 ce 00 00 00 00 00 00 02 14 00 00 00 00 00 00 06 64 00 00 00 00 00 00 05 4a 00 00 00 00 00 00 07 02 00 00 00 00 00 00 04 bc 00 00 00 00 00 00 04 08 00 00 00 00 00 00 04 54 00 00 00 00 00 00 03 98 00 00 00 00 00 00 06 6e 00 00 00 00 00 00 00 9e 00 00 00 00 00 00 03 c0 00 00 00 00 00 00 01 12 00 00 00 00 00 00 02 92 00 00 00 00 00 00 02 a8 00 00 00 00 00 00 02 8c 00 00 00 00 00 00 04 de 00 00 00 00 00 00 03 a2 00 00 00 00 00 00 07 36 00 00 00 00 00 00 07 3e 00 00 00 00 00 00 04 40 00 00 00 00 00 00 05 0e 00 00 00 00 00 00 01 52 00 00 00 00 00 00 02 34 00 00 00 00 00 00 00 36 00 00 00 00 00 00 00 8c 00 00 00 00 00 00 05 b4 00 00 00 00 00 00 01 82 00 00 00 00 00 00 05 36 00 00 00 00 00 00 02 16 00 00 00 00 00 00 06 f2 00 00 00 00 00 00 04 ea 00 00 00 00 00 00 02 86 00 00 00 00 00 00 03 b8 00 00 00 00 00 00 01 60 00 00 00 00 00 00 05 cc 00 00 00 00 00 00 07 56 00 00 00 00 00 00 01 dc 00 00 00 00 00 00 01 3a 00 00 00 00 00 00 05 a0 00 00 00 00 00 00 05 08 00 00 00 00 00 00 01 a6 00 00 00 00 00 00 06 c0 00 00 00 00 00 00 05 d4 00 00 00 00 00 00 05 aa 00 00 00 00 00 00 00 e8 00 00 00 00 00 00 04 24 |
0 | ,25 00 00 00 00 00 00 00 00 00,70 00 06 00 00 00 00 18 00 00 00 00 3f 01 00 00 00 00 00 00 f5 22 00 00 00 00 00 00 00 00 00 00, |
0 | ,4d 00 42 00 00 00 00 40 00 00,,02 00 00 36 00 00 00 04 00 00 00 00 00 01 00 04 00 00 00 00 00 02 00 04 00 00 00 00 00 03 00 04 00 00 00 00 00 05 00 0a 00 00 00 00 00 00 00 01 80 00 00 06 00 04 00 00 00 00 |
0 | ,37 00 08 00 00 00 00 00 08 00,, |
0 | ,1a 00 7f ff ff 00,, |
0 | ,b7 0a 00 00 00 00 00 00 02 00 00 00,,00 83 00 48 01 03 00 08 50 00 cc a0 2b 03 e0 b0 61 93 00 08 50 00 cc a0 2b 03 e0 b2 61 94 00 04 00 00 00 02 61 a3 00 08 50 00 cc a0 2b 03 e0 b3 63 a8 00 18 6e 61 61 2e 35 30 30 30 43 43 41 30 32 42 30 33 45 30 42 33 00 00 00 00 00 00 02 03 00 00 00 03 00 00 02 02 00 00 00 03 00 00 02 03 00 00 00 04 00 00 02 02 00 00 00 04 00 00 02 03 00 00 00 05 00 00 02 02 00 00 00 05 00 00 02 03 00 00 00 06 00 00 02 02 00 00 00 06 00 00 02 03 00 00 00 07 00 00 02 02 00 00 00 07 00 00 02 03 00 00 00 08 00 00 02 02 00 00 00 08 00 00 02 03 00 00 00 09 00 00 02 02 00 00 00 09 00 00 02 03 00 00 00 0a 00 00 02 02 00 00 00 0a 00 00 02 03 00 00 00 0b 00 00 02 02 00 00 00 0b 00 00 02 03 00 00 00 0c 00 00 02 02 00 00 00 0c 00 00 02 03 00 00 00 0d 00 00 02 02 00 00 00 0d 00 00 02 03 00 00 00 0e 00 00 02 02 00 00 00 0e 00 00 02 03 00 00 00 0f 00 00 02 02 00 00 00 0f 00 00 02 03 00 00 00 10 00 00 02 02 00 00 00 10 00 00 02 03 00 00 00 11 00 00 02 02 00 00 00 11 00 00 02 03 00 00 00 12 00 00 02 02 00 00 00 12 00 00 02 03 00 00 00 13 00 00 02 02 00 00 00 13 00 00 02 03 00 00 00 14 00 00 02 02 00 00 00 14 00 00 02 03 00 00 00 15 00 00 02 02 00 00 00 15 00 00 02 03 00 00 00 16 00 00 02 02 00 00 00 16 00 00 02 03 00 00 00 17 00 00 02 02 00 00 00 17 00 00 02 03 00 00 00 18 00 00 02 02 00 00 00 18 00 00 02 03 00 00 00 19 00 00 02 02 00 00 00 19 00 00 02 03 00 00 00 1a 00 00 02 02 00 00 00 1a 00 00 02 03 00 00 00 1b 00 00 02 02 00 00 00 1b 00 00 02 03 00 00 00 1c 00 00 02 02 00 00 00 1c 00 00 02 03 00 00 00 1d 00 00 02 02 00 00 00 1d 00 00 02 03 |
0 | ,1c 01 04 40 00 00,,04 00 04 5f 30 33 3a 31 36 3a 35 38 3a 31 32 3a 32 30 39 20 45 4d 43 20 53 54 45 3a 20 54 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 56 50 44 20 70 61 67 65 73 20 77 61 73 20 31 30 2c 20 6e 6f 77 20 31 30 0a 30 33 3a 31 36 3a 35 38 3a 31 32 3a 32 31 38 20 45 4d 43 20 53 54 45 3a 20 54 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 56 50 44 20 70 61 67 65 73 20 77 61 73 20 31 30 2c 20 6e 6f 77 20 31 30 0a 30 33 3a 31 36 3a 35 38 3a 31 32 3a 32 32 39 20 64 65 76 2f 70 68 79 2e 30 3a 20 45 4e 41 42 4c 45 44 2d 3e 44 49 53 41 42 4c 45 44 0a 30 33 3a 31 36 3a 35 38 3a 31 32 3a 32 34 31 20 64 65 76 2f 70 68 79 2e 31 3a 20 45 4e 41 42 4c 45 44 2d 3e 44 49 53 41 42 4c 45 44 0a 30 33 3a 31 36 3a 35 38 3a 31 32 3a 32 35 33 20 64 65 76 2f 70 68 79 2e 32 3a 20 45 4e 41 42 4c 45 44 2d 3e 44 49 53 41 42 4c 45 44 0a 30 33 3a 31 36 3a 35 38 3a 31 32 3a 32 36 32 20 64 65 76 2f 70 68 79 2e 33 3a 20 45 4e 41 42 4c 45 44 2d 3e 44 49 53 41 42 4c 45 44 0a 30 33 3a 31 36 3a 35 38 3a 31 32 3a 32 36 37 20 64 65 76 2f 70 68 79 2e 30 3a 20 6e 6f 74 20 72 65 61 64 79 0a 30 33 3a 31 36 3a 35 38 3a 31 32 3a 32 37 32 20 64 65 76 2f 70 68 79 2e 30 3a 20 6c 69 6e 6b 20 6e 6f 74 20 72 65 61 64 79 0a 30 33 3a 31 36 3a 35 38 3a 31 32 3a 32 38 33 20 64 65 76 2f 70 68 79 2e 30 3a 20 72 61 74 65 20 36 47 2d 3e 75 6e 6b 6e 6f 77 6e 0a 30 33 3a 31 36 3a 35 38 3a 31 32 3a 32 38 39 20 64 65 76 2f 70 68 79 2e 30 3a 20 61 74 74 61 63 68 65 64 20 70 68 79 20 69 64 20 30 78 30 34 2d 3e 30 78 66 66 0a 30 33 3a 31 36 3a 35 38 3a 31 32 3a 33 30 31 20 64 65 76 2f 70 68 79 2e 31 3a 20 6e 6f 74 20 72 65 61 64 79 0a 30 33 3a 31 36 3a 35 38 3a 31 32 3a 33 30 36 20 64 65 76 2f 70 68 79 2e 31 3a 20 6c 69 6e 6b 20 6e 6f 74 20 72 65 61 64 79 0a 30 33 3a 31 36 3a 35 38 3a 31 32 3a 33 31 30 20 64 65 76 2f 70 68 79 2e 31 3a 20 72 61 74 65 20 36 47 2d 3e 75 6e 6b 6e 6f 77 6e 0a 30 33 3a 31 36 3a 35 38 3a 31 32 3a 33 31 35 20 64 65 76 2f 70 68 79 2e 31 3a 20 61 74 74 61 63 68 65 64 20 70 68 79 20 69 64 20 30 78 30 35 2d 3e 30 78 66 66 0a 30 33 3a 31 36 3a 35 38 3a 31 32 3a 33 32 37 20 74 6e 6c 2f 74 75 6e 6e 65 6c 5f 73 74 65 5f 72 65 63 76 5f 64 69 61 67 5f 6d 73 67 5f 68 61 6e 64 6c 65 72 3a 20 74 75 6e 6e 65 6c 69 6e 67 20 52 45 43 56 20 44 49 41 47 4e 4f 53 54 49 43 20 72 65 63 65 69 76 65 64 20 66 72 6f 6d 20 53 54 45 2e 0a 30 33 3a 31 36 3a 35 38 3a 31 32 3a 33 32 38 20 64 65 76 2f 70 68 79 2e 32 3a 20 6e 6f 74 20 72 65 61 64 79 0a 30 33 3a 31 36 3a 35 38 3a 31 32 3a 33 34 34 20 64 65 76 2f 70 68 79 2e 32 3a 20 6c 69 6e 6b 20 6e 6f 74 20 72 65 61 64 79 0a 30 33 3a 31 36 3a 35 38 3a 31 32 3a 33 34 38 20 64 65 76 2f 70 68 79 2e 32 3a 20 72 61 74 65 20 36 47 2d 3e 75 6e 6b 6e 6f 77 6e 0a 30 33 3a 31 36 3a 35 38 3a 31 32 3a 33 35 32 20 64 65 76 2f 70 68 79 2e 32 3a 20 61 74 74 61 63 68 65 64 20 70 68 79 20 69 64 20 30 78 30 36 2d 3e 30 78 66 66 0a 30 33 3a 31 36 3a 35 38 3a 31 32 3a 33 36 34 20 64 65 76 2f 70 68 79 2e 33 3a 20 6e 6f 74 20 72 65 61 64 79 0a 30 33 3a 31 36 3a 35 38 3a 31 32 3a 33 36 38 20 64 65 76 2f 70 68 79 2e 33 3a 20 6c 69 6e 6b 20 6e 6f 74 20 72 65 61 64 79 0a 30 33 3a 31 36 3a 35 38 3a 31 32 3a 33 37 33 20 64 65 76 2f 70 68 79 2e 33 3a 20 72 61 74 65 20 36 47 2d 3e 75 6e 6b 6e 6f 77 6e 0a 30 33 3a 31 36 3a 35 38 3a 31 32 3a 33 37 38 20 64 65 76 2f 70 68 79 2e 33 3a 20 61 74 74 61 63 68 65 64 20 70 68 79 20 69 64 20 30 78 30 37 2d 3e 30 78 66 66 0a |
0 | ,1c 01 02 40 00 00,,02 00 01 00 00 00 00 00 00 00 00 00 11 00 00 00 11 00 00 00 11 00 00 00 11 00 00 00 11 00 00 00 11 00 00 00 11 00 00 00 11 00 00 00 11 00 00 00 11 00 00 00 11 00 00 00 11 00 00 00 11 00 00 00 11 00 00 00 11 00 00 00 11 00 00 00 11 00 00 00 11 00 00 00 00 00 00 00 01 00 2f 00 01 00 30 00 01 00 30 00 01 00 30 00 01 00 30 00 01 00 31 00 01 00 33 00 01 00 34 00 01 00 37 00 01 00 34 00 01 00 34 00 01 00 31 00 01 00 31 00 01 00 30 00 01 00 30 00 01 00 30 00 01 00 30 00 01 00 2e 00 00 00 00 00 01 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 01 20 00 00 01 20 00 00 01 20 00 00 01 20 00 00 01 20 00 00 01 20 00 00 01 20 00 00 01 20 00 00 01 20 00 00 01 20 00 00 01 20 00 00 01 20 00 00 01 20 00 00 01 20 00 00 01 20 00 00 01 20 00 00 01 20 00 00 01 20 00 00 |
0 | ,1a 08 ff ff ff 00,70 00 02 00 00 00 00 18 00 00 00 00 04 03 00 00 00 00 00 00 02 04 03 00 ff ff ff ff ff ff 00 00,01 aa 00 10 01 00 00 10 00 00 00 00 68 cb 9e 30 00 00 00 00 00 00 02 00 81 0a 04 14 ff 00 00 00 05 00 0c 00 82 0e 00 00 00 00 00 00 00 00 01 3a 00 00 00 00 83 16 bb d0 00 00 00 00 03 80 04 c4 02 08 00 01 00 a0 00 18 40 00 00 00 84 16 02 d3 c1 06 00 00 00 00 00 00 00 00 00 00 00 00 00 00 27 31 00 00 87 0a 04 14 ff 00 00 00 00 00 0c 00 88 12 10 00 ff ff 00 00 ff ff ff ff 80 03 00 00 00 00 00 00 8a 0a 00 10 00 80 00 00 00 00 00 06 18 06 06 00 00 00 00 00 99 0e 06 00 23 28 1b 58 00 00 00 00 00 00 00 00 59 01 00 64 00 06 00 02 00 00 00 00 10 49 0e 00 50 00 c5 00 68 59 9c bd 50 01 e6 78 7a c0 e0 00 01 00 00 00 00 00 00 00 88 aa 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 50 00 c5 00 68 59 9c be 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |
0 | ,1a 08 3f ff ff 00,70 00 02 00 00 00 00 18 00 00 00 00 04 01 00 00 00 00 00 00 f5 02 00 00 00 00 00 00 00 00 00 00, |
0 | ,4d 00 71 00 00 00 00 40 00 00,,31 00 00 68 80 00 03 08 00 00 00 00 00 00 01 bd 80 01 03 08 00 00 00 00 00 00 01 bd 80 02 03 08 00 00 00 00 00 00 01 97 80 03 03 08 00 00 00 00 00 00 01 a6 8f fa 03 08 00 00 00 00 00 00 01 97 8f fb 03 08 00 00 00 00 00 00 01 a6 8f fc 03 04 00 00 00 63 8f fd 03 04 00 00 00 00 8f fe 03 04 00 00 10 70 8f ff 03 04 00 00 74 04 |
0 | ,1c 01 80 40 00 00,,80 00 00 1c 56 45 4e 44 4f 52 20 20 03 01 41 30 35 30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |
0 | ,25 00 00 00 00 00 00 00 00 00,,00 0e 00 00 00 00 00 00 |
0 | ,37 00 0b 00 00 00 00 02 00 00,,00 0e 01 18 00 00 00 12 00 00 07 75 00 00 00 12 00 00 00 c1 00 00 00 12 00 00 07 4f 00 00 00 12 00 00 01 3d 00 00 00 12 00 00 05 eb 00 00 00 12 00 00 05 bd 00 00 00 12 00 00 07 33 00 00 00 12 00 00 05 23 00 00 00 12 00 00 04 35 00 00 00 12 00 00 06 ed 00 00 00 12 00 00 01 97 00 00 00 12 00 00 02 07 00 00 00 12 00 00 02 2b 00 00 00 12 00 00 03 f5 00 00 00 12 00 00 04 f7 00 00 00 12 00 00 06 cf 00 00 00 12 00 00 04 17 00 00 00 12 00 00 01 0b 00 00 00 12 00 00 02 73 00 00 00 12 00 00 02 35 00 00 00 12 00 00 02 3d 00 00 00 12 00 00 01 31 00 00 00 12 00 00 03 37 00 00 00 12 00 00 06 07 00 00 00 12 00 00 00 5d 00 00 00 12 00 00 06 af 00 00 00 12 00 00 03 dd 00 00 00 12 00 00 00 6f 00 00 00 12 00 00 06 0d 00 00 00 12 00 00 05 9d 00 00 00 12 00 00 04 49 00 00 00 12 00 00 01 f5 00 00 00 12 00 00 06 a1 00 00 00 12 00 00 03 f3 00 00 00 12 00 00 03 55 |
0 | ,25 00 00 00 00 00 00 00 00 00,70 00 06 00 00 00 00 0a 00 00 00 00 29 00 00 00 00 00, |
0 | ,5a 00 3f ff 00 00 00 10 00 00,,00 52 00 00 00 00 00 00 02 0e 00 00 00 00 00 00 00 00 00 09 00 00 00 00 0a 0a 00 00 00 00 00 00 00 00 00 00 18 06 06 00 00 00 00 00 19 06 16 00 00 0a 00 00 a0 0e 00 00 00 00 00 00 00 00 00 00 00 00 00 00 21 0e 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |
0 | ,25 00 00 00 00 00 00 00 00 00,71 00 04 00 00 00 00 18 00 00 00 00 44 a2 00 00 00 00 00 00 f6 22 00 00 00 00 00 00 00 00 00 00, |
0 | ,1c 01 01 40 00 00,,01 00 00 d8 00 00 00 00 22 00 06 58 50 01 63 60 01 b6 34 3e 51 55 41 4e 54 41 00 00 4a 42 45 20 49 53 49 4d 37 20 20 20 00 00 00 00 30 31 30 34 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 17 12 00 10 04 12 00 10 07 01 00 10 0e 01 00 10 18 01 00 10 19 12 00 10 41 72 72 61 79 20 44 65 76 69 63 65 20 20 20 20 54 65 6d 70 65 72 61 74 75 72 65 20 20 20 20 20 45 4d 4d 20 20 20 20 20 20 20 20 20 20 20 20 20 45 6e 63 6c 6f 73 75 72 65 20 20 20 20 20 20 20 45 78 70 61 6e 64 65 72 20 20 20 20 20 20 20 20 43 6f 6e 6e 65 63 74 6f 72 20 20 20 20 20 20 20 |
0 | ,37 00 08 00 00 00 00 00 08 00,,00 0e 00 00 00 00 00 00 00 00 00 0c 00 00 00 70 00 00 00 0c 00 00 00 8e 00 00 00 0c 00 00 01 06 00 00 00 00 00 00 02 02 00 00 00 00 00 00 02 03 00 00 00 01 00 00 02 02 00 00 00 01 00 00 02 03 00 00 00 02 00 00 02 02 00 00 00 02 00 00 02 03 00 00 00 03 00 00 02 02 00 00 00 03 00 00 02 03 00 00 00 04 00 00 02 02 00 00 00 04 00 00 02 03 00 00 00 05 00 00 02 02 00 00 00 05 00 00 02 03 00 00 00 06 00 00 02 02 00 00 00 06 00 00 02 03 00 00 00 07 00 00 02 02 00 00 00 07 00 00 02 03 00 00 00 08 00 00 02 02 00 00 00 08 00 00 02 03 00 00 00 09 00 00 02 02 00 00 00 09 00 00 02 03 00 00 00 0a 00 00 02 02 00 00 00 0a 00 00 02 03 00 00 00 0b 00 00 02 02 00 00 00 0b 00 00 02 03 00 00 00 0c 00 00 02 02 00 00 00 0c 00 00 02 03 00 00 00 0d 00 00 02 02 00 00 00 0d 00 00 02 03 00 00 00 0e 00 00 02 02 00 00 00 0e 00 00 02 03 00 00 00 0f 00 00 02 02 00 00 00 0f 00 00 02 03 00 00 00 10 00 00 02 02 00 00 00 10 00 00 02 03 00 00 00 11 00 00 02 02 00 00 00 11 00 00 02 03 00 00 00 12 00 00 02 02 00 00 00 12 00 00 02 03 00 00 00 13 00 00 02 02 00 00 00 13 00 00 02 03 00 00 00 14 00 00 02 02 00 00 00 14 00 00 02 03 00 00 00 15 00 00 02 02 00 00 00 15 00 00 02 03 00 00 00 16 00 00 02 02 00 00 00 16 00 00 02 03 00 00 00 17 00 00 02 02 00 00 00 17 00 00 02 03 00 00 00 18 00 00 02 02 00 00 00 18 00 00 02 03 00 00 00 19 00 00 02 02 00 00 00 19 00 00 02 03 00 00 00 1a 00 00 02 02 00 00 00 1a 00 00 02 03 00 00 00 1b 00 00 02 02 00 00 00 1b 00 00 02 03 00 00 00 1c 00 00 02 02 00 00 00 1c 00 00 02 03 00 00 00 1d 00 00 02 02 00 00 00 1d 00 00 02 03 |
0 | ,25 00 00 00 00 00 00 00 00 00,70 00 03 00 00 00 00 18 00 00 00 00 31 00 03 00 00 00 00 00 03 31 00 03 ff ff ff ff ff ff 00 00,00 83 00 48 01 03 00 08 |
0 | ,1c 01 00 40 00 00,,00 00 00 04 00 3f 40 82 |
0 | ,b7 0d 00 00 00 00 00 00 00 08 00 00,,00 0e 00 00 00 00 00 00 00 00 00 00 00 00 00 5a 00 00 00 01 00 00 00 5a 00 00 00 02 00 00 00 5a 00 00 00 03 00 00 00 5a 00 00 00 04 00 00 00 5a 00 00 00 06 00 00 00 5a 00 00 00 07 00 00 00 5a 00 00 00 08 00 00 00 5a 00 00 00 09 00 00 00 5a 00 00 00 0a 00 00 00 5a 00 00 00 0b 00 00 00 5a 00 00 00 12 00 00 00 5a 00 00 00 0c 00 00 00 5a 00 00 00 0d 00 00 00 5a 00 00 00 0e 00 00 00 5a 00 00 00 0f 00 00 00 5a 00 00 00 10 00 00 00 5a 00 00 00 05 00 00 00 5a 00 00 00 11 00 00 00 5a 00 00 00 13 00 00 00 5a 00 00 00 1e 00 00 00 5a 00 00 00 14 00 00 00 5a 00 00 00 15 00 00 00 5a 00 00 00 16 00 00 00 5a 00 00 00 17 00 00 00 5a 00 00 00 1f 00 00 00 5a 00 00 00 20 00 00 00 5a 00 00 00 21 00 00 00 5a 00 00 00 22 00 00 00 5a 00 00 00 23 00 00 00 5a 00 00 00 18 00 00 00 5a 00 00 00 19 00 00 00 5a 00 00 00 1a 00 00 00 5a 00 00 00 1b 00 00 00 5a 00 00 00 1c 00 00 00 5a 00 00 00 1d 00 00 00 5a 00 00 00 24 00 00 00 5a 00 00 00 25 00 00 00 5a 00 00 00 26 00 00 00 5a 00 00 00 27 00 00 00 5a 00 00 00 28 00 00 00 5a 00 00 00 29 00 00 00 5a 00 00 00 2a 00 00 00 5a 00 00 00 2d 00 00 00 5a 00 00 00 2e 00 00 00 5a 00 00 00 2f 00 00 00 5a 00 00 00 30 00 00 00 5a 00 00 00 31 00 00 00 5a 00 00 00 32 00 00 00 5a 00 00 00 33 00 00 00 5a 00 00 00 34 00 00 00 5a 00 00 00 35 00 00 00 5a 00 00 00 2b 00 00 00 5a 00 00 00 2c 00 00 00 5a 00 00 00 06 00 00 00 5b 00 00 00 00 00 00 00 5b 00 00 00 01 00 00 00 5b 00 00 00 04 00 00 00 5b 00 00 00 02 00 00 00 5b 00 00 00 03 00 00 00 5b 00 00 00 05 00 00 00 5b 00 00 00 07 00 00 00 5b 00 00 00 38 00 00 00 5a |
0 | ,37 00 11 00 00 00 00 00 08 00,70 00 01 00 00 00 00 18 00 00 00 00 1c 01 00 c0 00 02 00 00 17 47 00 00 00 00 00 00 00 00 00 00,00 16 04 50 00 00 00 00 |
0 | ,4d 00 4d 00 00 00 00 40 00 00,,0d 00 00 0c 00 00 43 02 00 17 00 01 43 02 00 46 |
0 | ,1a 08 bf ff ff 00,70 00 05 00 00 00 00 18 00 00 00 00 24 00 00 c0 00 04 00 00 05 24 00 00 ff ff ff ff ff ff 00 00,01 aa 00 10 01 00 00 10 00 00 00 00 68 cb 9e 30 00 00 00 00 00 00 02 00 81 0a c4 14 ff 00 00 00 05 00 0c 00 82 0e 00 00 00 00 00 00 00 00 01 3a 00 00 00 00 83 16 bb d0 00 00 00 00 03 80 04 c4 02 00 00 01 00 a0 00 18 40 00 00 00 84 16 02 d3 c1 06 00 00 00 00 00 00 00 00 00 00 00 00 00 00 27 31 00 00 87 0a 04 14 ff 00 00 00 00 00 0c 00 88 12 14 00 ff ff 00 00 ff ff ff ff 80 03 00 00 00 00 00 00 8a 0a 00 10 00 80 00 00 00 00 00 06 18 06 06 00 00 00 00 00 99 0e 06 00 23 28 1b 58 00 00 00 00 00 00 00 00 59 01 00 64 00 06 00 02 00 00 00 00 10 49 0e 00 50 00 c5 00 54 97 b0 31 50 01 e6 75 96 b7 10 00 01 00 00 00 00 00 00 00 88 aa 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 50 00 c5 00 54 97 b0 32 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |
0 | ,5a 08 ff ff 00 00 00 10 00 00,,01 f6 00 00 00 00 00 00 81 0a c8 ff ff 00 00 00 ff 00 13 88 82 0e 00 00 00 0a 00 00 00 00 01 00 00 00 00 00 83 16 00 80 00 00 00 00 00 00 00 80 02 00 00 01 00 00 00 00 40 00 00 00 84 16 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 87 0a 08 ff ff 00 00 00 00 00 13 88 88 12 14 00 ff ff 00 00 00 00 ff ff 00 08 00 00 00 00 00 00 8a 0a 00 00 00 00 00 00 00 00 07 08 ca 01 00 1c 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 98 06 06 00 00 00 00 00 99 0e 06 00 23 28 1b 58 00 00 00 00 00 00 00 00 d9 01 00 64 00 06 01 02 00 00 00 00 21 1a 02 02 50 00 03 96 9c 89 bf e2 50 06 04 80 78 0f c3 3f 0e 00 00 00 00 00 00 00 88 bb 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 21 1a 02 02 50 00 03 96 9c 89 bf e3 50 06 04 80 78 0e dc bf 20 00 00 00 00 00 00 00 88 bb 00 00 00 00 00 00 00 00 00 00 00 00 00 00 d9 02 00 0c 00 06 00 00 00 00 00 00 00 00 00 00 59 03 00 2c 00 06 01 02 00 00 00 10 80 ab 00 00 80 af 00 01 c0 a8 00 01 00 00 0a 00 00 01 00 10 80 ab 00 00 80 af 00 01 c0 a8 00 01 00 00 0a 00 9a 26 00 02 00 00 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 08 da 01 00 0c 00 00 00 00 00 00 00 00 00 00 00 00 9c 0a 08 00 00 00 00 00 00 00 00 01 a4 0e 00 00 40 37 0f 13 00 00 00 00 00 00 00 00 e4 01 00 0c 00 00 00 00 00 00 00 00 00 00 00 00 c0 01 00 30 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |
0 | ,1a 00 7f ff ff 00,70 00 02 00 00 00 00 18 00 00 00 00 04 04 00 80 30 9e 00 00 f5 04 00 00 00 00 00 00 00 00 00 00, |
0 | ,12 00 00 02 00 00,,0d 00 06 12 83 00 d0 02 45 4d 43 20 20 20 20 20 45 53 45 53 20 45 6e 63 6c 6f 73 75 72 65 20 20 30 30 30 31 50 4d 43 53 49 45 52 41 80 05 02 00 00 00 00 00 00 00 00 00 00 00 00 75 0c 00 03 01 03 e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02 00 03 00 00 00 01 41 50 4d 30 30 31 34 30 37 32 34 32 36 38 00 00 |
0 | ,1a 08 bf ff ff 00,,00 0e 00 00 00 00 00 00 00 00 00 03 00 00 00 2c 00 00 00 00 00 00 00 5a 00 00 00 01 00 00 00 5a 00 00 00 02 00 00 00 5a 00 00 00 03 00 00 00 5a 00 00 00 04 00 00 00 5a 00 00 00 06 00 00 00 5a 00 00 00 07 00 00 00 5a 00 00 00 08 00 00 00 5a 00 00 00 09 00 00 00 5a 00 00 00 0a 00 00 00 5a 00 00 00 0b 00 00 00 5a 00 00 00 12 00 00 00 5a 00 00 00 0c 00 00 00 5a 00 00 00 0d 00 00 00 5a 00 00 00 0e 00 00 00 5a 00 00 00 0f 00 00 00 5a 00 00 00 10 00 00 00 5a 00 00 00 05 00 00 00 5a 00 00 00 11 00 00 00 5a 00 00 00 13 00 00 00 5a 00 00 00 1e 00 00 00 5a 00 00 00 14 00 00 00 5a 00 00 00 15 00 00 00 5a 00 00 00 16 00 00 00 5a 00 00 00 17 00 00 00 5a 00 00 00 1f 00 00 00 5a 00 00 00 20 00 00 00 5a 00 00 00 21 00 00 00 5a 00 00 00 22 00 00 00 5a 00 00 00 23 00 00 00 |
0 | ,4d 00 77 00 00 00 00 40 00 00,,37 00 00 28 00 00 02 04 4a 92 79 ba 00 01 02 04 71 dd 1f cd 00 02 02 04 6d 2c da 32 00 03 02 04 01 87 03 91 00 04 02 04 00 00 00 00 |
0 | ,1a 00 bf ff ff 00,70 00 05 00 00 00 00 28 00 00 00 00 24 00 00 c0 00 04 00 1a 13 01 01 00 00 00 00 00 00 00 78 00 00 1d 31 1a 18 00 00 00 00 00 14 00 00 00 00 00, |
0 | ,1a 08 3f ff ff 00,70 00 05 00 00 00 00 18 00 00 00 00 24 00 00 c0 00 04 00 00 05 24 00 00 ff ff ff ff ff ff 00 00,01 aa 00 10 01 00 00 10 00 00 00 00 68 cb 9e 30 00 00 00 00 00 00 02 00 81 0a 04 14 ff 00 00 00 05 00 0c 00 82 0e 00 00 00 00 00 00 00 00 01 3a 00 00 00 00 83 16 bb d0 00 00 00 00 03 80 04 c4 02 00 00 01 00 a0 00 18 40 00 00 00 84 16 02 d3 c1 06 00 00 00 00 00 00 00 00 00 00 00 00 00 00 27 31 00 00 87 0a 04 14 ff 00 00 00 00 00 0c 00 88 12 14 00 ff ff 00 00 ff ff ff ff 80 03 00 00 00 00 00 00 8a 0a 00 10 00 80 00 00 00 00 00 06 18 06 06 00 00 00 00 00 99 0e 06 00 23 28 1b 58 00 00 00 00 00 00 00 00 59 01 00 64 00 06 00 02 00 00 00 00 10 49 0e 00 50 00 c5 00 70 c8 b6 d5 50 01 e6 78 ea fa c0 00 01 00 00 00 00 00 00 00 88 aa 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 50 00 c5 00 70 c8 b6 d6 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |
0 | ,1a 08 3f ff ff 00,,23 00 10 00 08 12 10 00 ff ff 00 00 ff ff ff ff 00 ff 00 00 00 00 00 00 1c 0a 00 00 00 00 00 00 00 00 00 00 |
0 | ,4d 00 5f d2 00 00 00 40 00 00,70 00 05 00 00 00 00 18 00 00 00 00 24 00 00 cd 00 02 00 00 f8 23 00 00 00 00 00 00 00 00 00 00, |
0 | ,1c 01 04 40 00 00,,04 00 01 4d 32 34 3a 31 35 3a 31 31 3a 31 37 3a 30 30 30 20 74 6e 6c 2f 74 75 6e 6e 65 6c 5f 73 74 65 5f 72 65 63 76 5f 64 69 61 67 5f 6d 73 67 5f 68 61 6e 64 6c 65 72 3a 20 74 75 6e 6e 65 6c 69 6e 67 20 52 45 43 56 20 44 49 41 47 4e 4f 53 54 49 43 20 72 65 63 65 69 76 65 64 20 66 72 6f 6d 20 53 54 45 2e 0a 32 34 3a 31 35 3a 31 31 3a 31 37 3a 32 30 33 20 45 53 45 53 3a 20 66 77 64 6c 20 70 72 74 74 6e 20 63 6e 74 72 6c 20 73 74 61 74 75 73 20 72 65 63 65 69 76 65 64 3a 20 61 63 74 69 76 65 3a 20 31 20 64 61 74 61 3a 20 30 20 69 6d 67 30 63 72 63 3a 20 30 78 62 64 20 69 6d 67 31 63 72 63 3a 20 30 78 61 34 0a 32 34 3a 31 35 3a 31 31 3a 32 35 3a 31 38 30 20 45 4d 43 20 53 54 45 3a 20 54 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 56 50 44 20 70 61 67 65 73 20 77 61 73 20 31 30 2c 20 6e 6f 77 20 31 30 0a 32 34 3a 31 35 3a 31 31 3a 32 35 3a 31 38 38 20 45 4d 43 20 53 54 45 3a 20 54 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 56 50 44 20 70 61 67 65 73 20 77 61 73 20 31 30 2c 20 6e 6f 77 20 31 30 0a |
0 | ,9e 10 00 00 00 00 00 00 00 00 00 00 02 00 00 00,,00 00 00 00 00 e7 bf ff 00 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |
0 | ,12 01 88 02 00 00,,00 88 00 30 00 00 00 01 00 00 00 00 00 00 00 0c 61 93 00 08 50 00 c5 00 67 b9 53 ad 00 00 00 02 00 00 00 00 00 00 00 0c 61 93 00 08 50 00 c5 00 67 b9 53 ae |
0 | ,12 01 c0 02 00 00,,0d c0 00 24 01 00 00 00 24 00 00 00 66 2f e0 06 0d 00 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 23 4a 88 75 |
0 | ,1c 01 82 40 00 00,,82 00 00 6e 48 49 54 41 43 48 49 20 43 32 36 30 00 01 00 00 00 00 00 00 0b 08 00 00 00 00 00 00 00 01 00 01 00 00 00 00 00 0e 00 01 00 01 00 00 00 5f 00 02 00 00 00 00 00 0b 00 02 00 01 00 00 00 11 00 03 00 00 00 00 00 00 00 03 00 01 00 00 00 00 00 04 00 00 00 00 00 00 00 04 00 01 00 00 00 00 00 05 00 00 00 00 00 0e 00 05 00 01 00 00 00 50 |
0 | ,1a 00 bf ff ff 00,,bf 00 10 08 2e 90 ed d0 00 00 02 00 81 0a 04 01 00 00 00 00 00 00 0c 00 82 0e 00 00 00 00 00 00 01 f4 00 00 00 00 00 00 03 16 00 00 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 40 00 00 00 04 16 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 87 0a 04 01 00 00 00 00 00 00 0c 00 88 12 10 00 ff ff 00 00 ff ff ff ff 00 00 00 00 00 00 00 00 8a 0a 00 10 00 00 00 00 00 00 00 06 ca 01 00 1c 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 98 06 06 00 00 00 00 00 99 0e 06 00 23 28 1b 58 00 00 00 00 00 00 00 00 d9 01 00 64 00 06 02 02 00 00 00 00 21 0a 02 02 50 00 cc a0 13 07 16 b1 50 06 04 80 d8 12 41 bf 18 00 00 00 00 00 00 00 88 aa 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 21 0a 02 02 50 00 cc |
0 | ,1C 00 43 00 00 00 00 40 00 00,,01 aa 00 54 00 00 00 08 00 00 00 00 00 00 00 00 00 01 00 08 00 00 00 00 00 00 00 00 00 02 00 08 00 00 00 00 00 00B00030 00 03 00 08 00 00 00 00 00 00 00 00 00 04 00 08 00 00 00 00 00 00 00 00 00 05 00 08 00 00 73 e0 f6 d9 46 00 00 06 00 08 00 00 00 00 00 00 00 00 |
0 | ,5a 10 300,,00 2e 00 10 01 00 00 18 00 00 00 00 00 e7 bf ff 00 00 00 00 00 00 02 00 08 12 10 00 ff ff 00 00 ff ff ff fD 00 ff 00 00 00 00 00 00 1c 0a 00 00 |
0 | ,5a 00 bf ff 00 00 00 10 00 00,,01 a2 00 10 00 00 00 08 68 cb 9e 30 00 00 02 00 81 0a 04 14 ff 00 00 00 05 00 0c 00 82 0e 00 00 00 00 00 00 00 00 01 3a 00 00 00 00 83 16 bb d0 00 00 00 00 03 80 04 c4 02 08 00 01 00 a0 00 18 40 00 00 00 84 16 02 d3 c1 06 00 00 00 00 00 00 00 00 00 00 00 00 00 00 27 31 00 00 87 0a 04 14 ff 00 00 00 00 00 0c 00 88 12 10 00 ff ff 00 00 ff ff ff ff 80 03 00 00 00 00 00 00 8a 0a 00 10 00 80 00 00 00 00 00 06 18 0B 06 00 00 00 00 00 99 0e 06 00 23 28 1b 58 00 00 00 00 00 00 00 00 59 01 00 64 00 06 00 02 00 00 00 00 10 49 0e 00 50 00 c5 00 ff fd f2 f1 50 01 e6 77 5a 4d b0 00 01 00 00 00 00 00 00 00 88 aa 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 50 00 c5 00 5f 0d f2 f2 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 88 aa 00 00 00 00 00 00 00 00 00 00 00 00 00 00 59 02 00 0c 00 06 03 e8 00 00 00 00 00 00 00 00 59 03 00 2c 00 06 00 02 00 00 00 10 80 ac 00 01 80 ac 00 01 00 00 00 00 00 00 09 00 00 01 00 10 80 ac 00 01 80 ac 00 01 00 00 00 00 00 00 00 00 9a 26 00 00 00 00 00 0a 00 00 8c a0 00 00 17 70 00 00 46 50 00 00 46 50 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 9c 0a 00 04 00 00 00 00 00 00 00 01 dc 01 00 0c 01 00 00 48 00 18 01 f4 00 00 00 00 80 16 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0c 00 00 00 00 00 00 |
0 | ,5a 10 3f ff00,,00 0e 40 10 01 00 00 10 00 00 00 00 00 e7 bf ff 00 00 00 00 00 00 d2 00 08 00 ff ff ff ff ff ffff 0000 ff 00 00 ff ff 00 ff 00 00 00 00 00 00 1⏎ |
Binary diff not shown
0 | ,5a 10 3f ff00,,00 2e 00 10 01 00 00 10 00 00 00 00 00 e7 bd ff 00 00 00 00 00 00 08 12 10 09 ff ff 00 02 00 0810 00 ff ff ff ff fd 00 ff 00 00 0000 00 1c 0a ⏎ |
0 | ,12 01 43 00 00 00 00 40 00 00,,03 40 00 54,00 00 00 08 00 00 00 00 00 00 00 00 00 01 00 08 00 00 00 00 00 00 00 00 00 02 00 08 00 00 00 00 00 00B00030 00 03 00 08 00 00 00 00 00 00 00 00 00 04 00 08 00 00 00 00 00 00 00 00 00 05 00 08 00 00 73 e0 f6 d9 46 00 00 06 00 08 00 00 00 00 00 00 00 00 |
0 | ,1a 08 300,,23 00 10 00 08 12 1F 00 ff ff 00 00 ff ff ff ff 00 ff 00 00 00 00 00fffffffffdffffffffffff00 00 ⏎ |
Binary diff not shown
0 | ,5a 20 3f ff00 00 10 00 00,,00 52 00 00 00 00 00 00 02 0e 00 00 00 00 00 00 40 00 00 09 00 00 00 00 0a 0a 00 00 00 00 00 00 00 00 0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfffffff0 00 18 06fffffffffffff⏎ |
0 | ,4d 00 55 00 00 00 00,,95 00 07 60 00 00 03 0c 00 0e ad cb 00 08 02 32 00 00 02 32 00 01 03 94 00 00 d8 00 13 11 00 01 e7 50 03 91 00 00 00 00 4a 26 37 51 00 02 03 14 00 01 e9 72 13 11 00 40 2b 52 02 8d 00 00 00 00 07 9f 84 21 00 03 03 14 00 02 22 c6 51 17 01 42 c5 b9 01 a9 00 00 00 00 66 25 50 00 00 04 03 14 00 02 27 74 51 17 01 41 f0 e7 00 6e 00 00 00 00 4d dd e2 00 00 05 03 14 00 02 30 a0 13 11 00 30 ff 76 03 41 00 00 00 00 29 9a 7c 93 00 06 03 14 00 02 42 cf 13 11 00 50 45 63 04 c2 00 00 00 00 0c 30 a4 fc 00 07 03 14 00 03 d9 dd 13 11 00 10 d6 c8 04 28 00 00 00 00 25 5d 1f a2 00 08 03 14 00 06 69 3a 51 17 01 50 19 fb 03 97 00 00 00 00 04 c3 f6 00 00 09 03 14 00 07 c0 13 51 17 01 52 94 3f 01 31 00 00 00 00 5e fc 5d e2 00 0a 03 14 00 08 79 da 51 17 01 42 c4 56 02 6f 00 00 00 00 65 fd 2d a6 00 0b 03 14 00 09 ed 76 51 17 01 52 88 b3 00 41 00 00 00 00 5d c1 81 dc 00 0c 03 14 00 0a 55 83 51 17 01 12 31 4f 00 4c 00 00 00 00 55 d9 f2 c0 00 0d 03 14 00 0a 55 94 51 17 01 02 7b fe 03 4d 00 00 00 00 5b ad f8 43 00 0e 03 14 00 0a 55 94 51 17 01 02 7b fe 03 52 00 00 00 00 5b ad f8 48 00 0f 03 14 00 0a 55 94 51 17 01 02 7b fe 03 57 00 00 00 00 5b ad f8 4d 00 10 03 14 00 0a 55 94 51 17 01 02 7b fe 03 62 00 00 00 00 5b ad f8 58 00 11 03 14 00 0a 55 94 51 17 01 02 7b fe 03 63 00 00 00 00 5b ad f8 59 00 12 03 14 00 0a 55 94 51 17 01 02 7b fe 03 64 00 00 00 00 5b ad f8 5a 00 13 03 14 00 0a 55 94 51 17 01 02 7b fe 03 6e 00 00 00 00 5b ad f8 64 00 14 03 14 00 0a 55 94 51 18 01 02 7b fe 03 71 00 00 00 00 5b ad f8 67 00 15 03 14 00 0a 55 94 51 17 01 02 7b fe 03 76 00 00 00 00 5b ad f8 6c 00 16 03 14 00 0a 55 94 51 17 01 02 7b fe 03 81 00 00 00 00 5b ad f8 77 00 17 03 14 00 0a 55 94 51 17 01 02 7b fe 03 82 00 00 00 00 5b ad f8 78 00 18 03 14 00 0a 55 9a 51 17 01 02 7b fe 03 83 00 00 00 00 5b ad f8 79 00 19 03 14 00 0a 55 e5 51 17 01 02 7b fe 03 84 00 00 00 00 5b ad f8 7a 00 1a 03 14 00 0a 55 e5 51 18 01 02 7b fe 03 85 00 00 00 00 5b ad f8 7b 00 1b 03 14 00 0a 55 e5 51 18 01 02 7b fe 03 8d 00 00 00 00 5b ad f8 83 00 1c 03 14 00 0a 55 e5 51 17 01 02 7b fe 03 8e 00 00 00 00 5b ad f8 84 00 1d 03 14 00 0a 55 e5 51 17 01 02 7b fe 03 8f 00 00 00 00 5b ad f8 85 00 1e 03 14 00 0a 55 e5 51 17 01 02 7b fe 03 90 00 00 00 00 5b ad f8 86 00 1f 03 14 00 0a 56 87 13 11 00 02 7b fe 03 91 00 00 00 00 5b ad f8 87 00 20 03 14 00 0a 56 87 13 11 00 02 7b fe 03 92 00 00 00 00 5b ad f8 88 00 21 03 14 00 0a 56 87 51 18 01 02 7b fe 03 93 00 00 00 00 5b ad f8 89 00 22 03 14 00 0a 56 87 51 17 01 02 7b fe 03 94 00 00 00 00 5b ad f8 8a 00 23 03 14 00 0a 56 87 13 11 00 02 7b fe 03 95 00 00 00 00 5b ad f8 8b 00 24 03 14 00 0a 56 87 51 17 01 02 7b fe 03 96 00 00 00 00 5b ad f8 8c 00 25 03 14 00 0a 56 87 51 17 01 02 7b fe 03 97 00 00 00 00 5b ad f8 8d 00 26 03 14 00 0a 56 87 51 17 01 02 7b fe 03 99 00 00 00 00 5b ad f8 8f 00 27 03 14 00 0a 56 e0 13 11 00 02 7b fe 03 9a 00 00 00 00 5b ad f8 90 00 28 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 9f 00 00 00 00 5b ad f8 95 00 29 03 14 00 0a 56 e0 51 18 01 02 7b fe 03 a4 00 00 00 00 5b ad f8 9a 00 2a 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 a5 00 00 00 00 5b ad f8 9b 00 2b 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 a6 00 00 00 00 5b ad f8 9c 00 2c 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 a7 00 00 00 00 5b ad f8 9d 00 2d 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 b4 00 00 00 00 5b ad f8 aa 00 2e 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 b5 00 00 00 00 5b ad f8 ab 00 2f 03 14 00 0a 56 e0 51 18 01 02 7b fe 03 b6 00 00 00 00 5b ad f8 ac 00 30 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 c7 00 00 00 00 5b ad f8 bd 00 31 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 c8 00 00 00 00 5b ad f8 be 00 32 03 14 00 0a 56 e0 51 18 01 02 7b fe 03 c9 00 00 00 00 5b ad f8 bf 00 33 03 14 00 0a 56 e0 51 18 01 02 7b fe 03 ca 00 00 00 00 5b ad f8 c0 00 34 03 14 00 0a 56 e0 51 17 01 02 7b ff 03 56 00 00 00 00 5b ad fc c8 00 35 03 14 00 0a 56 e0 51 17 01 02 7b ff 03 57 00 00 00 00 5b ad fc c9 00 36 03 14 00 0a 56 e0 51 18 01 02 7b ff 03 80 00 00 00 00 5b ad fc f2 00 37 03 14 00 0a 56 e0 51 17 01 02 7b ff 03 84 00 00 00 00 5b ad fc f6 00 38 03 14 00 0a 56 e0 51 17 01 02 7b ff 03 86 00 00 00 00 5b ad fc f8 00 39 03 14 00 0a 56 e0 51 17 01 02 7b ff 03 87 00 00 00 00 5b ad fc f9 00 3a 03 14 00 0a 57 8b 51 18 01 02 7b ff 03 88 00 00 00 00 5b ad fc fa 00 3b 03 14 00 0a 57 8b 51 17 01 02 7b ff 03 89 00 00 00 00 5b ad fc fb 00 3c 03 14 00 0a 57 8b 51 18 01 02 7b ff 03 95 00 00 00 00 5b ad fd 07 00 3d 03 14 00 0a 57 8b 51 17 01 02 7b ff 03 96 00 00 00 00 5b ad fd 08 00 3e 03 14 00 0a 57 8b 51 17 01 02 7b ff 03 97 00 00 00 00 5b ad fd 09 00 3f 03 14 00 0a 57 8b 51 18 01 02 7c 00 03 7b 00 00 00 00 5b ae 01 68 00 40 03 14 00 0a 57 b9 13 11 00 02 7c 00 03 7c 00 00 00 00 5b ae 01 69 00 41 03 14 00 0a 5e 51 51 17 01 02 7c 00 03 69 00 00 00 00 5b ae 01 56 00 42 03 14 00 0a 67 7a 51 17 01 02 7b ff 03 a4 00 00 00 00 5b ad fd 16 00 43 03 14 00 0a 73 09 51 17 01 02 7b ff 03 85 00 00 00 00 5b ad fc f7 00 44 03 14 00 0a 79 20 51 17 01 02 7c 00 03 68 00 00 00 00 5b ae 01 55 00 45 03 14 00 0a 85 b4 51 17 01 02 7b fe 03 b3 00 00 00 00 5b ad f8 a9 00 46 03 14 00 0a 85 b4 51 17 01 02 7b fe 03 cb 00 00 00 00 5b ad f8 c1 00 47 03 14 00 0a 8a 35 51 17 01 02 7b ff 03 64 00 00 00 00 5b ad fc d6 00 48 03 14 00 0a 9a da 51 17 01 02 7b ff 035b ad fc d7 00 49 03 14 00 0a d5 f7 51 17 01 02 7b ff 03 83 00 00 00 00 5b ad fc f5 00 4a 03 14 00 0a e8 64 51 17 01 02 7b fe 03 4a 00 00 00 00 5b ad f8 40 00 4b 03 14 00 0a e8 64 51 17 01 02 7c 00 03 38 00 00 00 00 5b ae 01 25 00 4c 03 14 00 0b b3 10 51 17 01 32 a3 06 01 d6 00 00 00 00 5f 89 3d 79 00 4d 03 14 00 0b b3 10 51 17 01 32 a3 0a 01 6a 00 00 00 00 5f 89 4f 6d 00 4e 03 14 00 0c a0 61 51 17 01 33 00 9e 02 e8 00 00 00 00 ⏎ |
0 | ,5a 00 bf ff 00 00 00 10 00 00,,01 a2 00 10 00 00 00 08 68 cb 9e 30 00 00 02 00 81 0a 04 14 ff 00 00 00 05 00 0c 00 82 0e 00 00 00 00 00 00 00 00 01 3a 00 00 00 00 83 16 bb d0 00 00 00 00 03 80 04 c4 02 08 00 01 00 a0 00 18 40 00 00 00 84 16 02 d3 c1 06 00 00 00 00 00 00 00 00 00 00 00 00 00 00 27 31 00 00 87 0a 04 14 ff 00 00 00 00 00 0c 00 88 12 10 00 ff ff 00 00 ff ff ff ff 80 03 00 00 00 00 00 00 8a 0a 00 10 00 80 00 00 00 00 00 06 18 06 06 00 00 00 00 00 99 0e 06 00 23 28 1b 58 00 00 00 00 00 00 00 00 59 01 00 65 00 06 00 02 00 00 00 00 10 49 0e 00 50 00 c5 00 5f 0d f2 f1 50 01 e6 77 5a 4d b0 00 01 00 00 00 00 00 00 00 88 aa 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 50 00 c5 00 5f 0d f2 f2 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 88 aa 00 00 00 00 00 00 00 00 00 00 00 00 00 00 59 ff ff fd 00 06 03 e8 00 00 00 00 00 00 00 00 59 03 00 2c 00 06 00 02 00 00 00 10 80 ac 00 01 80 ac 00 01 00 00 00 00 00 00 09 00 00 01 00 10 80 ac 00 01 80 ac 00 01 00 00 00 00 00 00 00 00 9a 26 00 00 00 00 00 0a 00 00 8c a0 00 00 17 70 00 00 46 50 00 00 46 50 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 9c 0a 00 04 00 00 00 00 00 00 00 01 dc 01 00 0c 01 00 00 48 00 18 01 f4 00 00 00 00 80 16 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0c 00 00 00 00 00 00 |
0 | ,4d 00 55 00 00 00 00,,95 00 07 60 00 00 03 0c 00 0e ad cb 00 08 02 32 00 00 02 32 00 01 03 14 00 00 d8 00 13 11 00 01 e7 50 03 91 00 00 00 00 4a 26 37 51 00 02 03 14 00 01 e9 72 13 11 00 40 2b 52 02 8d 00 00 00 00 07 9f 84 21 00 03 03 14 00 02 22 c6 51 17 01 42 c5 b9 01 a9 00 00 00 00 66 25 50 00 00 04 03 14 00 02 27 74 51 17 01 41 f0 e7 00 6e 00 00 00 00 4d dd e2 00 00 05 03 14 00 02 30 a0 13 11 00 30 ff 76 03 41 00 00 00 00 29 9a 7c 93 00 06 03 14 00 02 42 cf 13 11 00 50 45 63 04 c2 00 00 00 00 0c 30 a4 fc 00 07 03 14 00 03 d9 dd 13 11 00 10 d6 c8 04 28 00 00 00 00 25 5d 1f a2 00 08 03 14 00 06 69 3a 51 17 01 50 19 fb 03 97 00 00 00 00 04 c3 f6 00 00 09 03 16 00 07 c0 13 51 17 01 52 94 3f 01 31 00 00 00 00 5e fc 5d e2 00 0a 03 14 00 08 79 da 51 17 01 42 c4 56 02 6f 00 00 00 00 65 fd 2d a6 00 0b 03 14 00 09 ed 76 51 17 01 52 88 b3 00 41 00 00 00 00 5d c1 81 dc 00 0c 03 14 00 0a 55 83 51 17 01 12 31 4f 00 4c 00 00 00 00 55 d9 f2 c0 00 0d 03 14 00 0a 55 94 51 17 01 02 7b fe 03 4d 00 00 00 00 5b ad f8 43 00 0e 03 14 00 0a 55 94 51 17 01 02 7b fe 03 52 00 00 00 00 5b ad f8 48 00 0f 03 14 00 0a 55 94 51 17 01 02 7b fe 03 57 00 00 00 00 5b ad f8 4d 00 10 03 14 00 0a 55 94 51 17 01 02 7b fe 03 62 00 00 00 00 5b ad f8 58 00 11 03 14 00 0a 55 94 51 17 01 02 7b fe 03 63 00 00 00 00 5b ad f8 59 00 12 03 14 00 0a 55 94 51 17 01 02 7b fe 03 64 00 00 00 00 5b ad f8 5a 00 13 03 14 00 0a 55 94 51 17 01 02 7b fe 03 6e 00 00 00 00 5b ad f8 64 00 14 03 14 00 0a 55 94 51 18 01 02 7b fe 03 71 00 00 00 00 5b ad f8 67 00 15 03 14 00 0a 55 94 51 17 01 02 7b fe 03 76 00 00 00 00 5b ad f8 6c 00 16 03 14 00 0a 55 94 51 17 01 02 7b fe 03 81 00 00 00 00 5b ad f8 77 00 17 03 14 00 0a 55 94 51 17 01 02 7b fe 03 82 00 00 00 00 5b ad f8 78 00 18 03 14 00 0a 55 9a 51 17 01 02 7b fe 03 83 00 00 00 00 5b ad f8 79 00 19 03 14 00 0a 55 e5 51 17 01 02 7b fe 03 84 00 00 00 00 5b ad f8 7a 00 1a 03 14 00 0a 55 e5 51 18 01 02 7b fe 03 85 00 00 00 00 5b ad f8 7b 00 1b 03 14 00 0a 55 e5 51 18 01 02 7b fe 03 8d 00 00 00 00 5b ad f8 83 00 1c 03 14 00 0a 55 e5 51 17 01 02 7b fe 03 8e 00 00 00 00 5b ad f8 84 00 1d 03 14 00 0a 55 e5 51 17 01 02 7b fe 03 8f 00 00 00 00 5b ad f8 85 00 1e 03 14 00 0a 55 e5 51 17 01 02 7b fe 03 90 00 00 00 00 5b ad f8 86 00 1f 03 14 00 0a 56 87 13 11 00 02 7b fe 03 91 00 00 00 00 5b ad f8 87 00 20 03 14 00 0a 56 87 13 11 00 02 7b fe 03 92 00 00 00 00 5b ad f8 88 00 21 03 14 00 0a 56 87 51 18 01 02 7b fe 03 93 00 00 00 00 5b ad f8 89 00 22 03 14 00 0a 56 87 51 17 01 02 7b fe 03 94 00 00 00 00 5b ad f8 8a 00 23 03 14 00 0a 56 87 13 11 00 02 7b fe 03 95 00 00 00 00 5b ad f8 8b 00 24 03 14 00 0a 56 87 51 17 01 02 7b fe 03 96 00 00 00 00 5b ad f8 8c 00 25 03 14 00 0a 56 87 51 17 01 02 7b fe 03 97 00 00 00 00 5b ad f8 8d 00 26 03 14 00 0a 56 87 51 17 01 02 7b fe 03 99 00 00 00 00 5b ad f8 8f 00 27 03 14 00 0a 56 e0 13 11 00 02 7b fe 03 9a 00 00 00 00 5b ad f8 90 00 28 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 9f 00 00 00 00 5b ad f8 95 00 29 03 14 00 0a 56 e0 51 18 01 02 7b fe 03 a4 00 00 00 00 5b ad f8 9a 00 2a 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 a5 00 00 00 00 5b ad f8 9b 00 2b 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 a6 00 00 00 00 5b ad f8 9c 00 2c 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 a7 00 00 00 00 5b ad f8 9d 00 2d 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 b4 00 00 00 00 5b ad f8 aa 00 2e 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 b5 00 00 00 00 5b ad f8 ab 00 2f 03 14 00 0a 56 e0 51 18 01 02 7b fe 03 b6 00 00 00 00 5b ad f8 ac 00 30 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 c7 00 00 00 00 5b ad f8 bd 00 31 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 c8 00 00 00 00 5b ad f8 be 00 32 03 14 00 0a 56 e0 51 18 01 02 7b fe 03 c9 00 00 00 00 5b ad f8 bf 00 33 03 14 00 0a 56 e0 51 18 01 02 7b fe 03 ca 00 00 00 00 5b ad f8 c0 00 34 03 14 00 0a 56 e0 51 17 01 02 7b ff 03 56 00 00 00 00 5b ad fc c8 00 35 03 14 00 0a 56 e0 51 17 01 02 7b ff 03 57 00 00 00 00 5b ad fc c9 00 36 03 14 00 0a 56 e0 51 18 01 02 7b ff 03 80 00 00 00 00 5b ad fc f2 00 37 03 14 00 0a 56 e0 51 17 01 02 7b ff 03 84 00 00 00 00 5b ad fc f6 00 38 03 14 00 0a 56 e0 51 17 01 02 7b ff 03 86 00 00 00 00 5b ad fc f8 00 39 03 14 00 0a 56 e0 51 17 01 02 7b ff 03 87 00 00 00 00 5b ad fc f9 00 3a 03 14 00 0a 57 8b 51 18 01 02 7b ff 03 88 00 00 00 00 5b ad fc fa 00 3b 03 14 00 0a 57 8b 51 17 01 02 7b ff 03 89 00 00 00 00 5b ad fc fb 00 3c 03 14 00 0a 57 8b 51 18 01 02 7b ff 03 95 00 00 00 00 5b ad fd 07 00 3d 03 14 00 0a 57 8b 51 17 01 02 7b ff 03 96 00 00 00 00 5b ad fd 08 00 3e 03 14 00 0a 57 8b 51 17 01 02 7b ff 03 97 00 00 00 00 5b ad fd 09 00 3f 03 14 00 0a 57 8b 51 18 01 02 7c 00 03 7b 00 00 00 00 5b ae 01 68 00 40 03 14 00 0a 57 b9 13 11 00 02 7c 00 03 7c 00 00 00 00 5b ae 01 69 00 41 03 14 00 0a 5e 51 51 17 01 02 7c 00 03 69 00 00 00 00 5b ae 01 56 00 42 03 14 00 0a 67 7a 51 17 01 02 7b ff 03 a4 00 00 00 00 5b ad fd 16 00 43 03 14 00 0a 73 09 51 17 01 02 7b ff 03 85 00 00 00 00 5b ad fc f7 00 44 03 14 00 0a 79 20 51 17 01 02 7c 00 03 68 00 00 00 00 5b ae 01 55 00 45 03 14 00 0a 85 b4 51 17 01 02 7b fe 03 b3 00 00 00 00 5b ad f8 a9 00 46 03 14 00 0a 85 b4 51 17 01 02 7b fe 03 cb 00 00 00 00 5b ad f8 c1 00 47 03 14 00 0a 8a 35 51 17 01 02 7b ff 03 64 00 00 00 00 5b ad fc d6 00 48 03 14 00 0a 9a da 51 17 01 02 7b ff 035b ad fc d7 00 49 03 14 00 0a d5 f7 51 17 01 02 7b ff 03 83 00 00 00 00 5b ad fc f5 00 4a 03 14 00 0a e8 64 51 17 01 02 7b fe 03 4a 00 00 00 00 5b ad f8 40 00 4b 03 14 00 0a e8 64 51 17 01 02 7c 00 03 38 00 00 00 00 5b ae 01 25 00 4c 03 14 00 0b b3 10 51 17 01 32 a3 06 01 d6 00 00 00 00 5f 89 3d 79 00 4d 03 14 00 0b b3 10 51 17 01 32 a3 0a 01 6a 00 00 00 00 5f 89 4f 6d 00 4e 03 14 00 0c a0 61 51 17 01 33 00 9e 02 e8 00 00 00 00 ⏎ |
Binary diff not shown
0 | ,4d 00 55 00 00 00 00,,95 00 07 60 00 00 03 0c 00 0e ad cb 00 08 02 32 00 00 02 32 00 01 03 14 00 00 d8 00 13 11 00 01 e7 50 03 91 00 00 00 00 4a 26 37 51 00 02 03 14 00 01 e9 72 13 11 00 40 2b 52 02 8d 00 00 00 00 07 9f 84 21 00 03 03 14 00 02 22 c6 51 17 01 42 c5 b9 01 a9 00 00 00 00 66 25 50 00 00 04 03 14 00 02 27 74 51 17 01 41 f0 e7 00 6e 00 00 00 00 4d dd e2 00 00 05 03 14 00 02 30 a0 13 11 00 30 ff 76 03 41 00 00 00 00 29 9a 7c 93 00 06 03 14 00 02 42 cf 13 11 00 50 45 63 04 c2 00 00 00 00 0c 30 a4 fc 00 07 03 14 00 03 d9 dd 13 11 00 10 d6 c8 04 28 00 00 00 00 25 5d 1f a2 00 08 03 14 00 06 69 3a 51 17 01 50 19 fb 03 97 00 00 00 00 04 c3 f6 00 00 09 03 14 00 07 c0 13 51 17 01 52 94 3f 01 31 00 00 00 00 5e fc 5d e2 00 0a 03 14 00 08 79 da 51 17 01 42 c4 56 02 6f 00 00 00 00 65 fd 2d a6 00 0b 03 14 00 09 ed 76 51 17 01 52 88 b3 00 41 00 00 00 00 5d c1 81 dc 00 0c 03 14 00 0a 55 83 51 17 01 12 31 4f 00 4c 00 00 00 00 55 d9 f2 c0 00 0d 03 14 00 0a 55 94 51 17 01 02 7b fe 03 4d 00 00 00 00 5b ad f8 43 00 0e 03 14 00 0a 55 94 51 17 01 02 7b fe 03 52 00 00 00 00 5b ad f8 48 00 0f 03 14 00 0a 55 94 51 17 01 02 7b fe 03 57 00 00 00 00 5b ad f8 4d 00 10 03 14 00 0a 55 94 51 17 01 02 7b fe 03 62 00 00 00 00 5b ad f8 58 00 11 03 14 00 0a 55 94 51 17 01 02 7b fe 03 63 00 00 00 00 5b ad f8 59 00 12 03 14 00 0a 55 94 51 17 01 02 7b fe 03 64 00 00 00 00 5b ad f8 5a 00 13 03 14 00 0a 55 94 51 17 01 02 7b fe 03 6e 00 00 00 00 5b ad f8 64 00 14 03 14 00 0a 55 94 51 18 01 02 7b fe 03 71 00 00 00 00 5b ad f8 67 00 15 03 14 00 0a 55 94 51 17 01 02 7b fe 03 76 00 00 00 00 5b ad f8 6c 00 16 03 14 00 0a 55 94 51 17 01 02 7b fe 03 81 00 00 00 00 5b ad f8 77 00 17 03 14 00 0a 55 94 51 17 01 02 7b fe 03 82 00 00 00 00 5b ad f8 78 00 18 03 14 00 0a 55 9a 51 17 01 02 7b fe 03 83 00 00 00 00 5b ad f8 79 00 19 03 14 00 0a 55 e5 51 17 01 02 7b fe 03 84 00 00 00 00 5b ad f8 7a 00 1a 03 14 00 0a 55 e5 51 18 01 02 7b fe 03 85 00 00 00 00 5b ad f8 7b 00 1b 03 14 00 0a 55 e5 51 18 01 02 7b fe 03 8d 00 00 00 00 5b ad f8 83 00 1c 03 14 00 0a 55 e5 51 17 01 02 7b fe 03 8e 00 00 00 00 5b ad f8 84 00 1d 03 14 00 0a 55 e5 51 17 01 02 7b fe 03 8f 00 00 00 00 5b ad f8 85 00 1e 03 14 00 0a 55 e5 51 17 01 02 7b fe 03 90 00 00 00 00 5b ad f8 86 00 1f 03 14 00 0a 56 87 13 11 00 02 7b fe 03 91 00 00 00 00 5b ad f8 87 00 20 03 94 00 0a 56 87 13 11 00 02 7b fe 03 92 00 00 00 00 5b ad f8 88 00 21 03 14 00 0a 56 87 51 18 01 02 7b fe 03 93 00 00 00 00 5b ad f8 89 00 22 03 14 00 0a 56 87 51 17 01 02 7b fe 03 94 00 00 00 00 5b ad f8 8a 00 23 03 14 00 0a 56 87 13 11 00 02 7b fe 03 95 00 00 00 00 5b ad f8 8b 00 24 03 14 00 0a 56 87 51 17 01 02 7b fe 03 96 00 00 00 00 5b ad f8 8c 00 25 03 14 00 0a 56 87 51 17 01 02 7b fe 03 97 00 00 00 00 5b ad f8 8d 00 26 03 14 00 0a 56 87 51 17 01 02 7b fe 03 99 00 00 00 00 5b ad f8 8f 00 27 03 14 00 0a 56 e0 13 11 00 02 7b fe 03 9a 00 00 00 00 5b ad f8 90 00 28 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 9f 00 00 00 00 5b ad f8 95 00 29 03 14 00 0a 56 e0 51 18 01 02 7b fe 03 a4 00 00 00 00 5b ad f8 9a 00 2a 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 a5 00 00 00 00 5b ad f8 9b 00 2b 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 a6 00 00 00 00 5b ad f8 9c 00 2c 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 a7 00 00 00 00 5b ad f8 9d 00 2d 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 b4 00 00 00 00 5b ad f8 aa 00 2e 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 b5 00 00 00 00 5b ad f8 ab 00 2f 03 14 00 0a 56 e0 51 18 01 02 7b fe 03 b6 00 00 00 00 5b ad f8 ac 00 30 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 c7 00 00 00 00 5b ad f8 bd 00 31 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 c8 00 00 00 00 5b ad f8 be 00 32 03 14 00 0a 56 e0 51 18 01 02 7b fe 03 c9 00 00 00 00 5b ad f8 bf 00 33 03 14 00 0a 56 e0 51 18 01 02 7b fe 03 ca 00 00 00 00 5b ad f8 c0 00 34 03 14 00 0a 56 e0 51 17 01 02 7b ff 03 56 00 00 00 00 5b ad fc c8 00 35 03 14 00 0a 56 e0 51 17 01 02 7b ff 03 57 00 00 00 00 5b ad fc c9 00 36 03 14 00 0a 56 e0 51 18 01 02 7b ff 03 80 00 00 00 00 5b ad fc f2 00 37 03 14 00 0a 56 e0 51 17 01 02 7b ff 03 84 00 00 00 00 5b ad fc f6 00 38 03 14 00 0a 56 e0 51 17 01 02 7b ff 03 86 00 00 00 00 5b ad fc f8 00 39 03 14 00 0a 56 e0 51 17 01 02 7b ff 03 87 00 00 00 00 5b ad fc f9 00 3a 03 14 00 0a 57 8b 51 18 01 02 7b ff 03 88 00 00 00 00 5b ad fc fa 00 3b 03 14 00 0a 57 8b 51 17 01 02 7b ff 03 89 00 00 00 00 5b ad fc fb 00 3c 03 14 00 0a 57 8b 51 18 01 02 7b ff 03 95 00 00 00 00 5b ad fd 07 00 3d 03 14 00 0a 57 8b 51 17 01 02 7b ff 03 96 00 00 00 00 5b ad fd 08 00 3e 03 14 00 0a 57 8b 51 17 01 02 7b ff 03 97 00 00 00 00 5b ad fd 09 00 3f 03 14 00 0a 57 8b 51 18 01 02 7c 00 03 7b 00 00 00 00 5b ae 01 68 00 40 03 14 00 0a 57 b9 13 11 00 02 7c 00 03 7c 00 00 00 00 5b ae 01 69 00 41 03 14 00 0a 5e 51 51 17 01 02 7c 00 03 69 00 00 00 00 5b ae 01 56 00 42 03 14 00 0a 67 7a 51 17 01 02 7b ff 03 a4 00 00 00 00 5b ad fd 16 00 43 03 14 00 0a 73 09 51 17 01 02 7b ff 03 85 00 00 00 00 5b ad fc f7 00 44 03 14 00 0a 79 20 51 17 01 02 7c 00 03 68 00 00 00 00 5b ae 01 55 00 45 03 14 00 0a 85 b4 51 17 01 02 7b fe 03 b3 00 00 00 00 5b ad f8 a9 00 46 03 14 00 0a 85 b4 51 17 01 02 7b fe 03 cb 00 00 00 00 5b ad f8 c1 00 47 03 14 00 0a 8a 35 51 17 01 02 7b ff 03 64 00 00 00 00 5b ad fc d6 00 48 03 14 00 0a 9a da 51 17 01 02 7b ff 035b ad fc d7 00 49 03 14 00 0a d5 f7 51 17 01 02 7b ff 03 83 00 00 00 00 5b ad fc f5 00 4a 03 14 00 0a e8 64 51 17 01 02 7b fe 03 4a 00 00 00 00 5b ad f8 40 00 4b 03 14 00 0a e8 64 51 17 01 02 7c 00 03 38 00 00 00 00 5b ae 01 25 00 4c 03 14 00 0b b3 10 51 17 01 32 a3 06 01 d6 00 00 00 00 5f 89 3d 79 00 4d 03 14 00 0b b3 10 51 17 01 32 a3 0a 01 6a 00 00 00 00 5f 89 4f 6d 00 4e 03 14 00 0c a0 61 51 17 01 33 00 9e 02 e8 00 00 00 00 ⏎ |
0 | ,4d 00 55 00 00 00 00,,95 00 07 60 00 00 03 0c 00 0e ad cb 00 08 02 32 00 00 02 32 00 01 03 14 00 00 d8 00 13 11 00 01 e7 50 03 91 00 00 00 00 4a 26 37 51 00 02 03 14 00 01 e9 72 13 11 00 40 2b 52 02 8d 00 00 00 00 07 9f 84 21 00 03 03 12 00 02 22 c6 51 17 01 42 c5 b9 01 a9 00 00 00 00 66 25 50 00 00 04 03 14 00 02 27 74 51 17 01 41 f0 e7 00 6e 00 00 00 00 4d dd e2 00 00 05 03 14 00 02 30 a0 13 11 00 30 ff 76 03 41 00 00 00 00 29 9a 7c 93 00 06 03 14 00 02 42 cf 13 11 00 50 45 63 04 c2 00 00 00 00 0c 30 a4 fc 00 07 03 14 00 03 d9 dd 13 11 00 10 d6 c8 04 28 00 00 00 00 25 5d 1f a2 00 08 03 14 00 06 69 3a 51 17 01 50 19 fb 03 97 00 00 00 00 04 c3 f6 00 00 09 03 14 00 07 c0 13 51 17 01 52 94 3f 01 31 00 00 00 00 5e fc 5d e2 00 0a 03 14 00 08 79 da 51 17 01 42 c4 56 02 6f 00 00 00 00 65 fd 2d a6 00 0b 03 14 00 09 ed 76 51 17 01 52 88 b3 00 41 00 00 00 00 5d c1 81 dc 00 0c 03 14 00 0a 55 83 51 17 01 12 31 4f 00 4c 00 00 00 00 55 d9 f2 c0 00 0d 03 14 00 0a 55 94 51 17 01 02 7b fe 03 4d 00 00 00 00 5b ad f8 43 00 0e 03 14 00 0a 55 94 51 17 01 02 7b fe 03 52 00 00 00 00 5b ad f8 48 00 0f 03 14 00 0a 55 94 51 17 01 02 7b fe 03 57 00 00 00 00 5b ad f8 4d 00 10 03 14 00 0a 55 94 51 17 01 02 7b fe 03 62 00 00 00 00 5b ad f8 58 00 11 03 14 00 0a 55 94 51 17 01 02 7b fe 03 63 00 00 00 00 5b ad f8 59 00 12 03 14 00 0a 55 94 51 17 01 02 7b fe 03 64 00 00 00 00 5b ad f8 5a 00 13 03 14 00 0a 55 94 51 17 01 02 7b fe 03 6e 00 00 00 00 5b ad f8 64 00 14 03 14 00 0a 55 94 51 18 01 02 7b fe 03 71 00 00 00 00 5b ad f8 67 00 15 03 14 00 0a 55 94 51 17 01 02 7b fe 03 76 00 00 00 00 5b ad f8 6c 00 16 03 14 00 0a 55 94 51 17 01 02 7b fe 03 81 00 00 00 00 5b ad f8 77 00 17 03 14 00 0a 55 94 51 17 01 02 7b fe 03 82 00 00 00 00 5b ad f8 78 00 18 03 14 00 0a 55 9a 51 17 01 02 7b fe 03 83 00 00 00 00 5b ad f8 79 00 19 03 14 00 0a 55 e5 51 17 01 02 7b fe 03 84 00 00 00 00 5b ad f8 7a 00 1a 03 14 00 0a 55 e5 51 18 01 02 7b fe 03 85 00 00 00 00 5b ad f8 7b 00 1b 03 14 00 0a 55 e5 51 18 01 02 7b fe 03 8d 00 00 00 00 5b ad f8 83 00 1c 03 14 00 0a 55 e5 51 17 01 02 7b fe 03 8e 00 00 00 00 5b ad f8 84 00 1d 03 14 00 0a 55 e5 51 17 01 02 7b fe 03 8f 00 00 00 00 5b ad f8 85 00 1e 03 14 00 0a 55 e5 51 17 01 02 7b fe 03 90 00 00 00 00 5b ad f8 86 00 1f 03 14 00 0a 56 87 13 11 00 02 7b fe 03 91 00 00 00 00 5b ad f8 87 00 20 03 14 00 0a 56 87 13 11 00 02 7b fe 03 92 00 00 00 00 5b ad f8 88 00 21 03 14 00 0a 56 87 51 18 01 02 7b fe 03 93 00 00 00 00 5b ad f8 89 00 22 03 14 00 0a 56 87 51 17 01 02 7b fe 03 94 00 00 00 00 5b ad f8 8a 00 23 03 14 00 0a 56 87 13 11 00 02 7b fe 03 95 00 00 00 00 5b ad f8 8b 00 24 03 14 00 0a 56 87 51 17 01 02 7b fe 03 96 00 00 00 00 5b ad f8 8c 00 25 03 14 00 0a 56 87 51 17 01 02 7b fe 03 97 00 00 00 00 5b ad f8 8d 00 26 03 14 00 0a 56 87 51 17 01 02 7b fe 03 99 00 00 00 00 5b ad f8 8f 00 27 03 14 00 0a 56 e0 13 11 00 02 7b fe 03 9a 00 00 00 00 5b ad f8 90 00 28 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 9f 00 00 00 00 5b ad f8 95 00 29 03 14 00 0a 56 e0 51 18 01 02 7b fe 03 a4 00 00 00 00 5b ad f8 9a 00 2a 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 a5 00 00 00 00 5b ad f8 9b 00 2b 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 a6 00 00 00 00 5b ad f8 9c 00 2c 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 a7 00 00 00 00 5b ad f8 9d 00 2d 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 b4 00 00 00 00 5b ad f8 aa 00 2e 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 b5 00 00 00 00 5b ad f8 ab 00 2f 03 14 00 0a 56 e0 51 18 01 02 7b fe 03 b6 00 00 00 00 5b ad f8 ac 00 30 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 c7 00 00 00 00 5b ad f8 bd 00 31 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 c8 00 00 00 00 5b ad f8 be 00 32 03 14 00 0a 56 e0 51 18 01 02 7b fe 03 c9 00 00 00 00 5b ad f8 bf 00 33 03 14 00 0a 56 e0 51 18 01 02 7b fe 03 ca 00 00 00 00 5b ad f8 c0 00 34 03 14 00 0a 56 e0 51 17 01 02 7b ff 03 56 00 00 00 00 5b ad fc c8 00 35 03 14 00 0a 56 e0 51 17 01 02 7b ff 03 57 00 00 00 00 5b ad fc c9 00 36 03 14 00 0a 56 e0 51 18 01 02 7b ff 03 80 00 00 00 00 5b ad fc f2 00 37 03 14 00 0a 56 e0 51 17 01 02 7b ff 03 84 00 00 00 00 5b ad fc f6 00 38 03 14 00 0a 56 e0 51 17 01 02 7b ff 03 86 00 00 00 00 5b ad fc f8 00 39 03 14 00 0a 56 e0 51 17 01 02 7b ff 03 87 00 00 00 00 5b ad fc f9 00 3a 03 14 00 0a 57 8b 51 18 01 02 7b ff 03 88 00 00 00 00 5b ad fc fa 00 3b 03 14 00 0a 57 8b 51 17 01 02 7b ff 03 89 00 00 00 00 5b ad fc fb 00 3c 03 14 00 0a 57 8b 51 18 01 02 7b ff 03 95 00 00 00 00 5b ad fd 07 00 3d 03 14 00 0a 57 8b 51 17 01 02 7b ff 03 96 00 00 00 00 5b ad fd 08 00 3e 03 14 00 0a 57 8b 51 17 01 02 7b ff 03 97 00 00 00 00 5b ad fd 09 00 3f 03 14 00 0a 57 8b 51 18 01 02 7c 00 03 7b 00 00 00 00 5b ae 01 68 00 40 03 14 00 0a 57 b9 13 11 00 02 7c 00 03 7c 00 00 00 00 5b ae 01 69 00 41 03 14 00 0a 5e 51 51 17 01 02 7c 00 03 69 00 00 00 00 5b ae 01 56 00 42 03 14 00 0a 67 7a 51 17 01 02 7b ff 03 a4 00 00 00 00 5b ad fd 16 00 43 03 14 00 0a 73 09 51 17 01 02 7b ff 03 85 00 00 00 00 5b ad fc f7 00 44 03 14 00 0a 79 20 51 17 01 02 7c 00 03 68 00 00 00 00 5b ae 01 55 00 45 03 14 00 0a 85 b4 51 17 01 02 7b fe 03 b3 00 00 00 00 5b ad f8 a9 00 46 03 14 00 0a 85 b4 51 17 01 02 7b fe 03 cb 00 00 00 00 5b ad f8 c1 00 47 03 14 00 0a 8a 35 51 17 01 02 7b ff 03 64 00 00 00 00 5b ad fc d6 00 48 03 14 00 0a 9a da 51 17 01 02 7b ff 035b ad fc d7 00 49 03 14 00 0a d5 f7 51 17 01 02 7b ff 03 83 00 00 00 00 5b ad fc f5 00 4a 03 14 00 0a e8 64 51 17 01 02 7b fe 03 4a 00 00 00 00 5b ad f8 40 00 4b 03 14 00 0a e8 64 51 17 01 02 7c 00 03 38 00 00 00 00 5b ae 01 25 00 4c 03 14 00 0b b3 10 51 17 01 32 a3 06 01 d6 00 00 00 00 5f 89 3d 79 00 4d 03 14 00 0b b3 10 51 17 01 32 a3 0a 01 6a 00 00 00 00 5f 89 4f 6d 00 4e 03 14 00 0c a0 61 51 17 01 33 00 9e 02 e8 00 00 00 00 ⏎ |
0 | ,4d 00 55 00 00 00 00 40 00 00,,95 00 00 88 00 00 03 0c 00 0f 17 2b 00 08 02 5d 00 00 02 5d 00 01 03 14 00 03 7f bf 51 18 01 50 5b 54 03 48 00 00 00 00 11 57 80 1b 00 02 03 14 00 0c 68 1c 13 11 00 20 44 4c 03 9d 00 00 00 00 0b 8f 13 7a 00 03 03 14 00 0c 6c da 51 17 01 20 9d ef 05 26 00 00 00 00 1a 25 64 00 00 04 03 14 00 0c f2 ec 51 17 01 21 f2 bd 04 4a 00 00 00 00 4a cf 77 f7 00 05 03 14 00 0d ab 1d 51 17 01 21 89 2a 03 75 00 00 00 00 3c f7 ac 00 |
0 | ,4d 00 7e 00 00 00 00 40 00 00,,3e 00 00 24 00 00 02 04 00 10 c8 20 00 08 02 04 00 00 00 10 00 09 02 04 00 00 00 3c 00 0e 02 08 00 00 3c 04 24 09 8b 7d |
0 | ,4d 00 40 00 00 00 00 40 00 00,,00 00 00 11 00 02 03 05 06 0d 0e 0f 10 11 15 18 1a 2f 30 31 37 |
0 | ,4d 00 40 00 00 00 00 40 00 00,,00 00 00 0f 00 02 03 05 06 0d 0e 0f 10 11 15 18 1a 2f 31 |
0 | ,4d 00 6f 00 00 00 00 40 00 00,,2f 00 00 3c 00 00 03 08 00 00 19 55 21 00 00 00 00 01 03 04 5d 53 00 00 00 02 03 04 5d 54 00 00 00 03 03 04 5d 28 00 00 00 04 03 04 0b 06 00 00 00 05 03 04 5d 55 00 00 00 06 03 04 5d 56 00 00 |
0 | ,4d 00 4e 00 00 00 00 40 00 00,,0e 00 00 34 00 01 01 06 32 30 31 33 34 37 00 02 01 06 32 30 31 33 34 37 00 03 03 04 00 00 27 10 00 04 03 04 00 00 05 53 00 05 03 04 00 04 93 e0 00 06 03 04 00 00 05 53 |
0 | ,4d 00 46 00 00 00 00 40 00 00,,06 00 00 08 00 00 02 04 00 00 02 44 |
0 | ,4d 00 6f 00 00 00 00 40 00 00,,2f 00 00 4c 00 00 03 08 00 00 1c 46 26 00 00 00 00 01 03 04 5d 53 00 00 00 02 03 04 5d 54 00 00 00 03 03 04 5d 57 00 00 00 04 03 04 5d 28 00 00 00 05 03 04 0b 06 01 00 00 06 03 04 5d 56 38 00 00 07 03 04 5d 55 00 00 00 08 03 04 5d 20 00 00 |
0 | ,4d 00 59 00 00 00 00 40 00 00,,19 00 00 5c 00 01 02 40 00 00 00 05 1d 74 16 f0 00 00 00 04 62 22 c5 8d 00 00 00 43 98 00 04 2c 00 00 00 53 be 7d 55 4d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02 02 08 00 00 00 00 01 b4 c1 aa 00 03 03 08 00 00 00 02 00 00 00 05 |
0 | ,4d 00 43 00 00 00 00 40 00 00,,03 00 00 54 00 00 00 08 00 00 00 00 00 00 00 00 00 01 00 08 00 00 00 00 00 00 00 00 00 02 00 08 00 00 00 00 00 00 00 00 00 03 00 08 00 00 00 00 00 00 00 00 00 04 00 08 00 00 00 00 00 00 00 00 00 05 00 08 00 01 69 53 90 5e 44 00 00 06 00 08 00 00 00 00 00 00 00 00 |
22 | 22 | |
23 | 23 | typedef uint16_t ata_word_t; |
24 | 24 | typedef uint32_t ata_longword_t; |
25 | typedef uint64_t ata_qword_t; | |
25 | 26 | |
26 | 27 | typedef enum passthrough_protocol_e { |
27 | 28 | PT_PROTO_HARDWARE_RESET = 0, |
46 | 47 | ATA_PT_LEN_SPEC_TPSIU = 3, |
47 | 48 | } ata_passthrough_len_spec_e; |
48 | 49 | |
49 | static inline ata_word_t ata_get_word(const char *buf, int word) | |
50 | static inline ata_word_t ata_get_word(const unsigned char *buf, int word) | |
50 | 51 | { |
51 | 52 | return (uint16_t)(buf[word*2+1])<<8 | buf[word*2]; |
52 | 53 | } |
53 | 54 | |
54 | static inline uint16_t ata_get_bits(const char *buf, int word, int start_bit, int end_bit) | |
55 | static inline uint16_t ata_get_bits(const unsigned char *buf, int word, int start_bit, int end_bit) | |
55 | 56 | { |
56 | 57 | uint16_t val = ata_get_word(buf, word); |
57 | 58 | uint16_t shift = start_bit; |
79 | 80 | return (val >> shift) & mask; |
80 | 81 | } |
81 | 82 | |
82 | static inline bool ata_get_bit(char *buf, int word, int bit) | |
83 | static inline bool ata_get_bit(const unsigned char *buf, int word, int bit) | |
83 | 84 | { |
84 | 85 | return ata_get_bits(buf, word, bit, bit); |
85 | 86 | } |
86 | 87 | |
87 | static inline char *ata_get_string(const char *buf, int word_start, int word_end, char *str) | |
88 | static inline char *ata_get_string(const unsigned char *buf, int word_start, int word_end, char *str) | |
88 | 89 | { |
89 | 90 | int word; |
90 | 91 | int i; |
99 | 100 | return str; |
100 | 101 | } |
101 | 102 | |
102 | static inline ata_longword_t ata_get_longword(const char *buf, int start_word) | |
103 | static inline ata_longword_t ata_get_longword(const unsigned char *buf, int start_word) | |
103 | 104 | { |
104 | 105 | ata_longword_t high = ata_get_word(buf, start_word+1); |
105 | 106 | ata_longword_t low = ata_get_word(buf, start_word); |
107 | 108 | return longword; |
108 | 109 | } |
109 | 110 | |
110 | bool ata_inquiry_checksum_verify(const char *buf, int buf_len); | |
111 | static inline ata_qword_t ata_get_qword(const unsigned char *buf, int start_word) | |
112 | { | |
113 | ata_qword_t low = ata_get_longword(buf, start_word); | |
114 | ata_qword_t high = ata_get_longword(buf, start_word+2); | |
115 | ata_qword_t qword = high << 32 | low; | |
116 | return qword; | |
117 | } | |
118 | ||
119 | bool ata_inquiry_checksum_verify(const unsigned char *buf, int buf_len); | |
111 | 120 | |
112 | 121 | static inline unsigned char ata_passthrough_flags_2(int offline, int ck_cond, int direction_in, int transfer_block, ata_passthrough_len_spec_e len_spec) |
113 | 122 | { |
194 | 203 | return cdb_ata_passthrough_12(cdb, 0xB0, 0xD0, 0xC24F<<8, 1, PT_PROTO_DMA, true, 0); |
195 | 204 | } |
196 | 205 | |
206 | static inline int cdb_ata_smart_read_log(unsigned char *cdb, uint8_t log_addr, uint8_t num_pages) | |
207 | { | |
208 | return cdb_ata_passthrough_12(cdb, 0xB0, 0xD5, (0xC24F<<8) | log_addr, num_pages, PT_PROTO_PIO_DATA_IN, true, 0); | |
209 | } | |
197 | 210 | |
198 | 211 | static inline int cdb_ata_smart_read_threshold(unsigned char *cdb) |
199 | 212 | { |
203 | 216 | static inline int cdb_ata_check_power_mode(unsigned char *cdb) |
204 | 217 | { |
205 | 218 | return cdb_ata_passthrough_12(cdb, 0xE5, 0, 0, 0, PT_PROTO_NON_DATA, true, 1); |
219 | } | |
220 | ||
221 | static inline int cdb_ata_read_log_ext(unsigned char *cdb, uint16_t block_count, uint16_t page_number, uint8_t log_address) | |
222 | { | |
223 | uint64_t lba = ((page_number & 0xFF00) << 24) | ((page_number & 0xFF) << 8) | log_address; | |
224 | return cdb_ata_passthrough_16(cdb, 0x2F, 0, lba, block_count, PT_PROTO_PIO_DATA_IN, true, false, 0); | |
206 | 225 | } |
207 | 226 | |
208 | 227 | /* Parse ATA SMART READ DATA results */ |
221 | 240 | uint8_t threshold; |
222 | 241 | } ata_smart_thresh_t; |
223 | 242 | |
224 | static inline uint8_t ata_calc_ata_smart_read_data_checksum(const unsigned char *buf) { | |
243 | /** Calculate the page checksum for an ATA buffer, this is needed on ATA IDENTIFY DEVICE and in SMART commands. | |
244 | * We assume the buffer size is 512 always. | |
245 | */ | |
246 | static inline uint8_t ata_calc_checksum(const unsigned char *buf) { | |
225 | 247 | unsigned val = 0; |
226 | 248 | int i; |
227 | 249 | for (i = 0; i < 511; i++) |
229 | 251 | return 0x100 - (val & 0xFF); // We want the complement |
230 | 252 | } |
231 | 253 | |
254 | static inline bool ata_checksum_verify(const unsigned char *buf) { | |
255 | return ata_calc_checksum(buf) == buf[511]; | |
256 | } | |
257 | ||
232 | 258 | static inline uint8_t ata_get_ata_smart_read_data_checksum(const unsigned char *buf) { |
233 | 259 | return buf[511]; |
234 | 260 | } |
235 | 261 | |
236 | 262 | static inline bool ata_check_ata_smart_read_data_checksum(const unsigned char *buf) { |
237 | return ata_get_ata_smart_read_data_checksum(buf) == ata_calc_ata_smart_read_data_checksum(buf); | |
263 | return ata_checksum_verify(buf); | |
238 | 264 | } |
239 | 265 | |
240 | 266 | uint16_t ata_get_ata_smart_read_data_version(const unsigned char *buf); |
1 | 1 | #ifndef ATA_PARSE_H |
2 | 2 | #define ATA_PARSE_H |
3 | 3 | #include "ata.h" |
4 | static inline bool ata_get_ata_identify_smart_enabled(const char *buf) { | |
4 | static inline bool ata_get_ata_identify_smart_enabled(const unsigned char *buf) { | |
5 | 5 | ata_word_t val = ata_get_word(buf, 85); |
6 | 6 | return val & (1 << 0); |
7 | 7 | } |
8 | 8 | |
9 | static inline bool ata_get_ata_identify_cfast_supported(const char *buf) { | |
10 | ata_word_t val = ata_get_word(buf, 69); | |
11 | return val & (1 << 15); | |
12 | } | |
13 | ||
14 | static inline bool ata_get_ata_identify_sct_write_same_supported(const char *buf) { | |
9 | static inline bool ata_get_ata_identify_sct_write_same_supported(const unsigned char *buf) { | |
15 | 10 | ata_word_t val = ata_get_word(buf, 206); |
16 | 11 | return val & (1 << 2); |
17 | 12 | } |
18 | 13 | |
19 | static inline bool ata_get_ata_identify_lps_misalignment_reporting_supported(const char *buf) { | |
20 | ata_word_t val = ata_get_word(buf, 69); | |
21 | return val & (1 << 13); | |
22 | } | |
23 | ||
24 | static inline bool ata_get_ata_identify_extended_number_of_user_addressable_sectors(const char *buf) { | |
25 | ata_word_t val = ata_get_word(buf, 69); | |
26 | return val & (1 << 3); | |
27 | } | |
28 | ||
29 | static inline bool ata_get_ata_identify_sense_data_supported(const char *buf) { | |
14 | static inline bool ata_get_ata_identify_extended_number_of_user_addressable_sectors(const unsigned char *buf) { | |
15 | ata_word_t val = ata_get_word(buf, 69); | |
16 | return val & (1 << 3); | |
17 | } | |
18 | ||
19 | static inline bool ata_get_ata_identify_sense_data_supported(const unsigned char *buf) { | |
30 | 20 | ata_word_t val = ata_get_word(buf, 119); |
31 | 21 | return val & (1 << 6); |
32 | 22 | } |
33 | 23 | |
34 | static inline bool ata_get_ata_identify_fields_valid_words_64_70(const char *buf) { | |
24 | static inline bool ata_get_ata_identify_fields_valid_words_64_70(const unsigned char *buf) { | |
35 | 25 | ata_word_t val = ata_get_word(buf, 53); |
36 | 26 | return val & (1 << 1); |
37 | 27 | } |
38 | 28 | |
39 | static inline bool ata_get_ata_identify_crypto_scramble_supported(const char *buf) { | |
29 | static inline bool ata_get_ata_identify_crypto_scramble_supported(const unsigned char *buf) { | |
40 | 30 | ata_word_t val = ata_get_word(buf, 59); |
41 | 31 | return val & (1 << 13); |
42 | 32 | } |
43 | 33 | |
44 | static inline bool ata_get_ata_identify_rzat_supported(const char *buf) { | |
45 | ata_word_t val = ata_get_word(buf, 69); | |
46 | return val & (1 << 5); | |
47 | } | |
48 | ||
49 | static inline bool ata_get_ata_identify_address_48bit_supported(const char *buf) { | |
50 | ata_word_t val = ata_get_word(buf, 83); | |
51 | return val & (1 << 10); | |
52 | } | |
53 | ||
54 | static inline bool ata_get_ata_identify_set_max_set_password_dma_and_set_max_unlock_dma_supported(const char *buf) { | |
55 | ata_word_t val = ata_get_word(buf, 69); | |
56 | return val & (1 << 9); | |
57 | } | |
58 | ||
59 | static inline bool ata_get_ata_identify_volatile_write_cache_supported(const char *buf) { | |
60 | ata_word_t val = ata_get_word(buf, 82); | |
61 | return val & (1 << 5); | |
62 | } | |
63 | ||
64 | static inline bool ata_get_ata_identify_standby_timer_values_settable(const char *buf) { | |
34 | static inline bool ata_get_ata_identify_rzat_supported(const unsigned char *buf) { | |
35 | ata_word_t val = ata_get_word(buf, 69); | |
36 | return val & (1 << 5); | |
37 | } | |
38 | ||
39 | static inline ata_qword_t ata_get_ata_identify_extended_num_user_addressable_sectors(const unsigned char *buf) { | |
40 | return ata_get_qword(buf, 230); | |
41 | } | |
42 | ||
43 | static inline bool ata_get_ata_identify_wwn_64bit_supported(const unsigned char *buf) { | |
44 | ata_word_t val = ata_get_word(buf, 84); | |
45 | return val & (1 << 8); | |
46 | } | |
47 | ||
48 | static inline bool ata_get_ata_identify_standby_timer_values_settable(const unsigned char *buf) { | |
65 | 49 | ata_word_t val = ata_get_word(buf, 49); |
66 | 50 | return val & (1 << 13); |
67 | 51 | } |
68 | 52 | |
69 | static inline bool ata_get_ata_identify_sata_dma_setup_auto_activation_enabled(const char *buf) { | |
70 | ata_word_t val = ata_get_word(buf, 79); | |
71 | return val & (1 << 2); | |
72 | } | |
73 | ||
74 | static inline void ata_get_ata_identify_fw_rev(const char *buf, char *out) { | |
53 | static inline bool ata_get_ata_identify_write_buffer_dma_supported(const unsigned char *buf) { | |
54 | ata_word_t val = ata_get_word(buf, 69); | |
55 | return val & (1 << 10); | |
56 | } | |
57 | ||
58 | static inline void ata_get_ata_identify_fw_rev(const unsigned char *buf, char *out) { | |
75 | 59 | ata_get_string(buf, 23, 26, out); |
76 | 60 | } |
77 | 61 | |
78 | static inline bool ata_get_ata_identify_write_buffer_dma_supported(const char *buf) { | |
79 | ata_word_t val = ata_get_word(buf, 69); | |
62 | static inline bool ata_get_ata_identify_sata_software_settings_preservation_enabled(const unsigned char *buf) { | |
63 | ata_word_t val = ata_get_word(buf, 79); | |
64 | return val & (1 << 6); | |
65 | } | |
66 | ||
67 | static inline bool ata_get_ata_identify_sata_device_initiated_power_management_enabled(const unsigned char *buf) { | |
68 | ata_word_t val = ata_get_word(buf, 79); | |
69 | return val & (1 << 3); | |
70 | } | |
71 | ||
72 | static inline bool ata_get_ata_identify_write_uncorrectable_enabled(const unsigned char *buf) { | |
73 | ata_word_t val = ata_get_word(buf, 120); | |
74 | return val & (1 << 2); | |
75 | } | |
76 | ||
77 | static inline bool ata_get_ata_identify_sct_command_transport_supported(const unsigned char *buf) { | |
78 | ata_word_t val = ata_get_word(buf, 206); | |
79 | return val & (1 << 0); | |
80 | } | |
81 | ||
82 | static inline ata_longword_t ata_get_ata_identify_wwn_high(const unsigned char *buf) { | |
83 | return ata_get_longword(buf, 108); | |
84 | } | |
85 | ||
86 | static inline bool ata_get_ata_identify_supports_sata_gen1_1_5gbps(const unsigned char *buf) { | |
87 | ata_word_t val = ata_get_word(buf, 76); | |
88 | return val & (1 << 1); | |
89 | } | |
90 | ||
91 | static inline bool ata_get_ata_identify_supports_receipt_of_host_initiated_power_management_requests(const unsigned char *buf) { | |
92 | ata_word_t val = ata_get_word(buf, 76); | |
93 | return val & (1 << 9); | |
94 | } | |
95 | ||
96 | static inline bool ata_get_ata_identify_supports_receive_fpdma_queued(const unsigned char *buf) { | |
97 | ata_word_t val = ata_get_word(buf, 77); | |
98 | return val & (1 << 6); | |
99 | } | |
100 | ||
101 | static inline bool ata_get_ata_identify_smart_self_test_supported(const unsigned char *buf) { | |
102 | ata_word_t val = ata_get_word(buf, 84); | |
103 | return val & (1 << 1); | |
104 | } | |
105 | ||
106 | static inline bool ata_get_ata_identify_overwrite_supported(const unsigned char *buf) { | |
107 | ata_word_t val = ata_get_word(buf, 59); | |
108 | return val & (1 << 14); | |
109 | } | |
110 | ||
111 | static inline unsigned ata_get_ata_identify_queue_depth(const unsigned char *buf) { | |
112 | ata_word_t val = ata_get_word(buf, 75); | |
113 | return (val >> 0) & ((1<<(4 - 0 + 1)) - 1); | |
114 | } | |
115 | ||
116 | static inline bool ata_get_ata_identify_encrypt_all_supported(const unsigned char *buf) { | |
117 | ata_word_t val = ata_get_word(buf, 69); | |
118 | return val & (1 << 4); | |
119 | } | |
120 | ||
121 | static inline bool ata_get_ata_identify_write_buffer_supported(const unsigned char *buf) { | |
122 | ata_word_t val = ata_get_word(buf, 82); | |
123 | return val & (1 << 12); | |
124 | } | |
125 | ||
126 | static inline bool ata_get_ata_identify_streaming_supported(const unsigned char *buf) { | |
127 | ata_word_t val = ata_get_word(buf, 84); | |
128 | return val & (1 << 4); | |
129 | } | |
130 | ||
131 | static inline bool ata_get_ata_identify_download_microcode_supported(const unsigned char *buf) { | |
132 | ata_word_t val = ata_get_word(buf, 83); | |
133 | return val & (1 << 0); | |
134 | } | |
135 | ||
136 | static inline bool ata_get_ata_identify_response_incomplete(const unsigned char *buf) { | |
137 | ata_word_t val = ata_get_word(buf, 0); | |
138 | return val & (1 << 2); | |
139 | } | |
140 | ||
141 | static inline bool ata_get_ata_identify_sct_feature_control_supported(const unsigned char *buf) { | |
142 | ata_word_t val = ata_get_word(buf, 206); | |
143 | return val & (1 << 4); | |
144 | } | |
145 | ||
146 | static inline bool ata_get_ata_identify_puis_supported(const unsigned char *buf) { | |
147 | ata_word_t val = ata_get_word(buf, 83); | |
148 | return val & (1 << 5); | |
149 | } | |
150 | ||
151 | static inline bool ata_get_ata_identify_supports_read_log_dma_ext_as_read_log_dma(const unsigned char *buf) { | |
152 | ata_word_t val = ata_get_word(buf, 76); | |
153 | return val & (1 << 15); | |
154 | } | |
155 | ||
156 | static inline void ata_get_ata_identify_serial_number(const unsigned char *buf, char *out) { | |
157 | ata_get_string(buf, 10, 19, out); | |
158 | } | |
159 | ||
160 | static inline bool ata_get_ata_identify_supports_host_automatic_partial_to_slumber(const unsigned char *buf) { | |
161 | ata_word_t val = ata_get_word(buf, 76); | |
162 | return val & (1 << 13); | |
163 | } | |
164 | ||
165 | static inline bool ata_get_ata_identify_cfa_supported(const unsigned char *buf) { | |
166 | ata_word_t val = ata_get_word(buf, 83); | |
167 | return val & (1 << 2); | |
168 | } | |
169 | ||
170 | static inline bool ata_get_ata_identify_sata_in_order_data_delivery_enabled(const unsigned char *buf) { | |
171 | ata_word_t val = ata_get_word(buf, 79); | |
172 | return val & (1 << 4); | |
173 | } | |
174 | ||
175 | static inline bool ata_get_ata_identify_major_version_acs_2(const unsigned char *buf) { | |
176 | ata_word_t val = ata_get_word(buf, 80); | |
177 | return val & (1 << 9); | |
178 | } | |
179 | ||
180 | static inline void ata_get_ata_identify_additional_product_identifier(const unsigned char *buf, char *out) { | |
181 | ata_get_string(buf, 170, 173, out); | |
182 | } | |
183 | ||
184 | static inline bool ata_get_ata_identify_volatile_write_cache_supported(const unsigned char *buf) { | |
185 | ata_word_t val = ata_get_word(buf, 82); | |
186 | return val & (1 << 5); | |
187 | } | |
188 | ||
189 | static inline bool ata_get_ata_identify_smart_supported(const unsigned char *buf) { | |
190 | ata_word_t val = ata_get_word(buf, 82); | |
191 | return val & (1 << 0); | |
192 | } | |
193 | ||
194 | static inline bool ata_get_ata_identify_sct_data_tables_supported(const unsigned char *buf) { | |
195 | ata_word_t val = ata_get_word(buf, 206); | |
196 | return val & (1 << 5); | |
197 | } | |
198 | ||
199 | static inline bool ata_get_ata_identify_supports_dev_automatic_partial_to_slumber(const unsigned char *buf) { | |
200 | ata_word_t val = ata_get_word(buf, 76); | |
201 | return val & (1 << 14); | |
202 | } | |
203 | ||
204 | static inline unsigned ata_get_ata_identify_current_negotiated_link_speed(const unsigned char *buf) { | |
205 | ata_word_t val = ata_get_word(buf, 77); | |
206 | return (val >> 1) & ((1<<(3 - 1 + 1)) - 1); | |
207 | } | |
208 | ||
209 | static inline bool ata_get_ata_identify_supports_sata_gen2_3gbps(const unsigned char *buf) { | |
210 | ata_word_t val = ata_get_word(buf, 76); | |
211 | return val & (1 << 2); | |
212 | } | |
213 | ||
214 | static inline bool ata_get_ata_identify_read_look_ahead_supported(const unsigned char *buf) { | |
215 | ata_word_t val = ata_get_word(buf, 82); | |
216 | return val & (1 << 6); | |
217 | } | |
218 | ||
219 | static inline bool ata_get_ata_identify_read_buffer_supported(const unsigned char *buf) { | |
220 | ata_word_t val = ata_get_word(buf, 82); | |
221 | return val & (1 << 13); | |
222 | } | |
223 | ||
224 | static inline bool ata_get_ata_identify_cfast_supported(const unsigned char *buf) { | |
225 | ata_word_t val = ata_get_word(buf, 69); | |
226 | return val & (1 << 15); | |
227 | } | |
228 | ||
229 | static inline bool ata_get_ata_identify_lps_misalignment_reporting_supported(const unsigned char *buf) { | |
230 | ata_word_t val = ata_get_word(buf, 69); | |
231 | return val & (1 << 13); | |
232 | } | |
233 | ||
234 | static inline bool ata_get_ata_identify_supports_ncq_priority(const unsigned char *buf) { | |
235 | ata_word_t val = ata_get_word(buf, 76); | |
236 | return val & (1 << 12); | |
237 | } | |
238 | ||
239 | static inline bool ata_get_ata_identify_address_48bit_supported(const unsigned char *buf) { | |
240 | ata_word_t val = ata_get_word(buf, 83); | |
80 | 241 | return val & (1 << 10); |
81 | 242 | } |
82 | 243 | |
83 | static inline bool ata_get_ata_identify_major_version_ata_atapi_6(const char *buf) { | |
244 | static inline bool ata_get_ata_identify_set_max_set_password_dma_and_set_max_unlock_dma_supported(const unsigned char *buf) { | |
245 | ata_word_t val = ata_get_word(buf, 69); | |
246 | return val & (1 << 9); | |
247 | } | |
248 | ||
249 | static inline bool ata_get_ata_identify_apm_supported(const unsigned char *buf) { | |
250 | ata_word_t val = ata_get_word(buf, 83); | |
251 | return val & (1 << 3); | |
252 | } | |
253 | ||
254 | static inline bool ata_get_ata_identify_sata_dma_setup_auto_activation_enabled(const unsigned char *buf) { | |
255 | ata_word_t val = ata_get_word(buf, 79); | |
256 | return val & (1 << 2); | |
257 | } | |
258 | ||
259 | static inline bool ata_get_ata_identify_major_version_ata_atapi_7(const unsigned char *buf) { | |
84 | 260 | ata_word_t val = ata_get_word(buf, 80); |
85 | return val & (1 << 6); | |
86 | } | |
87 | ||
88 | static inline bool ata_get_ata_identify_major_version_ata_atapi_5(const char *buf) { | |
261 | return val & (1 << 7); | |
262 | } | |
263 | ||
264 | static inline bool ata_get_ata_identify_major_version_ata_atapi_6(const unsigned char *buf) { | |
89 | 265 | ata_word_t val = ata_get_word(buf, 80); |
90 | return val & (1 << 5); | |
91 | } | |
92 | ||
93 | static inline bool ata_get_ata_identify_sct_error_recovery_control_supported(const char *buf) { | |
266 | return val & (1 << 6); | |
267 | } | |
268 | ||
269 | static inline bool ata_get_ata_identify_major_version_ata_atapi_5(const unsigned char *buf) { | |
270 | ata_word_t val = ata_get_word(buf, 80); | |
271 | return val & (1 << 5); | |
272 | } | |
273 | ||
274 | static inline bool ata_get_ata_identify_sct_error_recovery_control_supported(const unsigned char *buf) { | |
94 | 275 | ata_word_t val = ata_get_word(buf, 206); |
95 | 276 | return val & (1 << 3); |
96 | 277 | } |
97 | 278 | |
98 | static inline bool ata_get_ata_identify_block_erase_supported(const char *buf) { | |
279 | static inline bool ata_get_ata_identify_block_erase_supported(const unsigned char *buf) { | |
99 | 280 | ata_word_t val = ata_get_word(buf, 59); |
100 | 281 | return val & (1 << 15); |
101 | 282 | } |
102 | 283 | |
103 | static inline bool ata_get_ata_identify_sata_software_settings_preservation_enabled(const char *buf) { | |
104 | ata_word_t val = ata_get_word(buf, 79); | |
105 | return val & (1 << 6); | |
106 | } | |
107 | ||
108 | static inline bool ata_get_ata_identify_dma_supported(const char *buf) { | |
284 | static inline bool ata_get_ata_identify_gpl_supported(const unsigned char *buf) { | |
285 | ata_word_t val = ata_get_word(buf, 84); | |
286 | return val & (1 << 5); | |
287 | } | |
288 | ||
289 | static inline bool ata_get_ata_identify_dma_supported(const unsigned char *buf) { | |
109 | 290 | ata_word_t val = ata_get_word(buf, 49); |
110 | 291 | return val & (1 << 8); |
111 | 292 | } |
112 | 293 | |
113 | static inline bool ata_get_ata_identify_write_uncorrectable_enabled(const char *buf) { | |
114 | ata_word_t val = ata_get_word(buf, 120); | |
115 | return val & (1 << 2); | |
116 | } | |
117 | ||
118 | static inline bool ata_get_ata_identify_sct_command_transport_supported(const char *buf) { | |
119 | ata_word_t val = ata_get_word(buf, 206); | |
120 | return val & (1 << 0); | |
121 | } | |
122 | ||
123 | static inline bool ata_get_ata_identify_not_ata_device(const char *buf) { | |
294 | static inline unsigned ata_get_ata_identify_rotational_rate(const unsigned char *buf) { | |
295 | ata_word_t val = ata_get_word(buf, 216); | |
296 | return (val >> 0) & ((1<<(15 - 0 + 1)) - 1); | |
297 | } | |
298 | ||
299 | static inline bool ata_get_ata_identify_not_ata_device(const unsigned char *buf) { | |
124 | 300 | ata_word_t val = ata_get_word(buf, 0); |
125 | 301 | return val & (1 << 15); |
126 | 302 | } |
127 | 303 | |
128 | static inline bool ata_get_ata_identify_read_buffer_supported(const char *buf) { | |
129 | ata_word_t val = ata_get_word(buf, 82); | |
130 | return val & (1 << 13); | |
131 | } | |
132 | ||
133 | static inline bool ata_get_ata_identify_read_buffer_dma_supported(const char *buf) { | |
304 | static inline bool ata_get_ata_identify_spin_up_supported(const unsigned char *buf) { | |
305 | ata_word_t val = ata_get_word(buf, 83); | |
306 | return val & (1 << 6); | |
307 | } | |
308 | ||
309 | static inline bool ata_get_ata_identify_read_buffer_dma_supported(const unsigned char *buf) { | |
134 | 310 | ata_word_t val = ata_get_word(buf, 69); |
135 | 311 | return val & (1 << 11); |
136 | 312 | } |
137 | 313 | |
138 | static inline bool ata_get_ata_identify_address_28bit_supported(const char *buf) { | |
139 | ata_word_t val = ata_get_word(buf, 69); | |
140 | return val & (1 << 6); | |
141 | } | |
142 | ||
143 | static inline bool ata_get_ata_identify_download_microcode_dma_supported(const char *buf) { | |
314 | static inline bool ata_get_ata_identify_address_28bit_supported(const unsigned char *buf) { | |
315 | ata_word_t val = ata_get_word(buf, 69); | |
316 | return val & (1 << 6); | |
317 | } | |
318 | ||
319 | static inline bool ata_get_ata_identify_supports_sata_gen3_6gbps(const unsigned char *buf) { | |
320 | ata_word_t val = ata_get_word(buf, 76); | |
321 | return val & (1 << 3); | |
322 | } | |
323 | ||
324 | static inline bool ata_get_ata_identify_download_microcode_dma_supported(const unsigned char *buf) { | |
144 | 325 | ata_word_t val = ata_get_word(buf, 69); |
145 | 326 | return val & (1 << 8); |
146 | 327 | } |
147 | 328 | |
148 | static inline bool ata_get_ata_identify_mandatory_power_management_supported(const char *buf) { | |
149 | ata_word_t val = ata_get_word(buf, 82); | |
150 | return val & (1 << 3); | |
151 | } | |
152 | ||
153 | static inline bool ata_get_ata_identify_fields_valid_word_88(const char *buf) { | |
329 | static inline bool ata_get_ata_identify_mandatory_power_management_supported(const unsigned char *buf) { | |
330 | ata_word_t val = ata_get_word(buf, 82); | |
331 | return val & (1 << 3); | |
332 | } | |
333 | ||
334 | static inline bool ata_get_ata_identify_fields_valid_word_88(const unsigned char *buf) { | |
154 | 335 | ata_word_t val = ata_get_word(buf, 53); |
155 | 336 | return val & (1 << 2); |
156 | 337 | } |
157 | 338 | |
158 | static inline bool ata_get_ata_identify_packet_feature_set_supported(const char *buf) { | |
159 | ata_word_t val = ata_get_word(buf, 82); | |
160 | return val & (1 << 4); | |
161 | } | |
162 | ||
163 | static inline bool ata_get_ata_identify_smart_self_test_supported(const char *buf) { | |
164 | ata_word_t val = ata_get_word(buf, 84); | |
339 | static inline bool ata_get_ata_identify_packet_feature_set_supported(const unsigned char *buf) { | |
340 | ata_word_t val = ata_get_word(buf, 82); | |
341 | return val & (1 << 4); | |
342 | } | |
343 | ||
344 | static inline bool ata_get_ata_identify_nop_supported(const unsigned char *buf) { | |
345 | ata_word_t val = ata_get_word(buf, 82); | |
346 | return val & (1 << 14); | |
347 | } | |
348 | ||
349 | static inline bool ata_get_ata_identify_supports_ncq_queue_management_commands(const unsigned char *buf) { | |
350 | ata_word_t val = ata_get_word(buf, 77); | |
351 | return val & (1 << 5); | |
352 | } | |
353 | ||
354 | static inline bool ata_get_ata_identify_write_uncorrectable_supported(const unsigned char *buf) { | |
355 | ata_word_t val = ata_get_word(buf, 119); | |
356 | return val & (1 << 2); | |
357 | } | |
358 | ||
359 | static inline bool ata_get_ata_identify_supports_sata_phy_event_counters_log(const unsigned char *buf) { | |
360 | ata_word_t val = ata_get_word(buf, 76); | |
361 | return val & (1 << 10); | |
362 | } | |
363 | ||
364 | static inline bool ata_get_ata_identify_supports_ncq(const unsigned char *buf) { | |
365 | ata_word_t val = ata_get_word(buf, 76); | |
366 | return val & (1 << 8); | |
367 | } | |
368 | ||
369 | static inline bool ata_get_ata_identify_supports_ncq_streaming(const unsigned char *buf) { | |
370 | ata_word_t val = ata_get_word(buf, 77); | |
371 | return val & (1 << 4); | |
372 | } | |
373 | ||
374 | static inline bool ata_get_ata_identify_sata_automatic_partial_to_slumber_transitions_enabled(const unsigned char *buf) { | |
375 | ata_word_t val = ata_get_word(buf, 79); | |
376 | return val & (1 << 7); | |
377 | } | |
378 | ||
379 | static inline void ata_get_ata_identify_current_media_serial(const unsigned char *buf, char *out) { | |
380 | ata_get_string(buf, 176, 205, out); | |
381 | } | |
382 | ||
383 | static inline bool ata_get_ata_identify_major_version_ata_8_acs(const unsigned char *buf) { | |
384 | ata_word_t val = ata_get_word(buf, 80); | |
385 | return val & (1 << 8); | |
386 | } | |
387 | ||
388 | static inline ata_longword_t ata_get_ata_identify_wwn_low(const unsigned char *buf) { | |
389 | return ata_get_longword(buf, 110); | |
390 | } | |
391 | ||
392 | static inline bool ata_get_ata_identify_trusted_computing_supported(const unsigned char *buf) { | |
393 | ata_word_t val = ata_get_word(buf, 48); | |
394 | return val & (1 << 0); | |
395 | } | |
396 | ||
397 | static inline bool ata_get_ata_identify_sata_non_zero_buffer_offsets_enabled(const unsigned char *buf) { | |
398 | ata_word_t val = ata_get_word(buf, 79); | |
165 | 399 | return val & (1 << 1); |
166 | 400 | } |
167 | 401 | |
168 | static inline bool ata_get_ata_identify_sata_in_order_data_delivery_enabled(const char *buf) { | |
169 | ata_word_t val = ata_get_word(buf, 79); | |
170 | return val & (1 << 4); | |
171 | } | |
172 | ||
173 | static inline bool ata_get_ata_identify_major_version_acs_2(const char *buf) { | |
174 | ata_word_t val = ata_get_word(buf, 80); | |
175 | return val & (1 << 9); | |
176 | } | |
177 | ||
178 | static inline bool ata_get_ata_identify_encrypt_all_supported(const char *buf) { | |
179 | ata_word_t val = ata_get_word(buf, 69); | |
180 | return val & (1 << 4); | |
181 | } | |
182 | ||
183 | static inline bool ata_get_ata_identify_iordy_supported(const char *buf) { | |
402 | static inline bool ata_get_ata_identify_non_volatile_cache(const unsigned char *buf) { | |
403 | ata_word_t val = ata_get_word(buf, 69); | |
404 | return val & (1 << 2); | |
405 | } | |
406 | ||
407 | static inline bool ata_get_ata_identify_iordy_supported(const unsigned char *buf) { | |
184 | 408 | ata_word_t val = ata_get_word(buf, 49); |
185 | 409 | return val & (1 << 11); |
186 | 410 | } |
187 | 411 | |
188 | static inline bool ata_get_ata_identify_nop_supported(const char *buf) { | |
189 | ata_word_t val = ata_get_word(buf, 82); | |
190 | return val & (1 << 14); | |
191 | } | |
192 | ||
193 | static inline bool ata_get_ata_identify_sata_device_initiated_power_management_enabled(const char *buf) { | |
194 | ata_word_t val = ata_get_word(buf, 79); | |
195 | return val & (1 << 3); | |
196 | } | |
197 | ||
198 | static inline bool ata_get_ata_identify_response_incomplete(const char *buf) { | |
199 | ata_word_t val = ata_get_word(buf, 0); | |
200 | return val & (1 << 2); | |
201 | } | |
202 | ||
203 | static inline bool ata_get_ata_identify_sata_automatic_partial_to_slumber_transitions_enabled(const char *buf) { | |
204 | ata_word_t val = ata_get_word(buf, 79); | |
205 | return val & (1 << 7); | |
206 | } | |
207 | ||
208 | static inline bool ata_get_ata_identify_sct_feature_control_supported(const char *buf) { | |
209 | ata_word_t val = ata_get_word(buf, 206); | |
210 | return val & (1 << 4); | |
211 | } | |
212 | ||
213 | static inline bool ata_get_ata_identify_major_version_ata_8_acs(const char *buf) { | |
214 | ata_word_t val = ata_get_word(buf, 80); | |
215 | return val & (1 << 8); | |
216 | } | |
217 | ||
218 | static inline bool ata_get_ata_identify_trusted_computing_supported(const char *buf) { | |
219 | ata_word_t val = ata_get_word(buf, 48); | |
220 | return val & (1 << 0); | |
221 | } | |
222 | ||
223 | static inline bool ata_get_ata_identify_sanitize_supported(const char *buf) { | |
412 | static inline bool ata_get_ata_identify_sata_hardware_feature_control_enabled(const unsigned char *buf) { | |
413 | ata_word_t val = ata_get_word(buf, 79); | |
414 | return val & (1 << 5); | |
415 | } | |
416 | ||
417 | static inline bool ata_get_ata_identify_supports_unload_while_ncq_outstanding(const unsigned char *buf) { | |
418 | ata_word_t val = ata_get_word(buf, 76); | |
419 | return val & (1 << 11); | |
420 | } | |
421 | ||
422 | static inline bool ata_get_ata_identify_security_feature_set_supported(const unsigned char *buf) { | |
423 | ata_word_t val = ata_get_word(buf, 82); | |
424 | return val & (1 << 1); | |
425 | } | |
426 | ||
427 | static inline bool ata_get_ata_identify_smart_error_logging_supported(const unsigned char *buf) { | |
428 | ata_word_t val = ata_get_word(buf, 84); | |
429 | return val & (1 << 0); | |
430 | } | |
431 | ||
432 | static inline bool ata_get_ata_identify_sense_data_enabled(const unsigned char *buf) { | |
433 | ata_word_t val = ata_get_word(buf, 120); | |
434 | return val & (1 << 6); | |
435 | } | |
436 | ||
437 | static inline bool ata_get_ata_identify_iordy_disable_supported(const unsigned char *buf) { | |
438 | ata_word_t val = ata_get_word(buf, 49); | |
439 | return val & (1 << 10); | |
440 | } | |
441 | ||
442 | static inline bool ata_get_ata_identify_sanitize_supported(const unsigned char *buf) { | |
224 | 443 | ata_word_t val = ata_get_word(buf, 59); |
225 | 444 | return val & (1 << 12); |
226 | 445 | } |
227 | 446 | |
228 | static inline bool ata_get_ata_identify_non_volatile_cache(const char *buf) { | |
229 | ata_word_t val = ata_get_word(buf, 69); | |
230 | return val & (1 << 2); | |
231 | } | |
232 | ||
233 | static inline void ata_get_ata_identify_serial_number(const char *buf, char *out) { | |
234 | ata_get_string(buf, 10, 19, out); | |
235 | } | |
236 | ||
237 | static inline ata_longword_t ata_get_ata_identify_total_addressable_sectors_28bit(const char *buf) { | |
447 | static inline void ata_get_ata_identify_model(const unsigned char *buf, char *out) { | |
448 | ata_get_string(buf, 27, 46, out); | |
449 | } | |
450 | ||
451 | static inline bool ata_get_ata_identify_drat_supported(const unsigned char *buf) { | |
452 | ata_word_t val = ata_get_word(buf, 69); | |
453 | return val & (1 << 14); | |
454 | } | |
455 | ||
456 | static inline ata_longword_t ata_get_ata_identify_total_addressable_sectors_28bit(const unsigned char *buf) { | |
238 | 457 | return ata_get_longword(buf, 60); |
239 | 458 | } |
240 | 459 | |
241 | static inline void ata_get_ata_identify_model(const char *buf, char *out) { | |
242 | ata_get_string(buf, 27, 46, out); | |
243 | } | |
244 | ||
245 | static inline bool ata_get_ata_identify_overwrite_supported(const char *buf) { | |
246 | ata_word_t val = ata_get_word(buf, 59); | |
247 | return val & (1 << 14); | |
248 | } | |
249 | ||
250 | static inline bool ata_get_ata_identify_write_uncorrectable_supported(const char *buf) { | |
251 | ata_word_t val = ata_get_word(buf, 119); | |
252 | return val & (1 << 2); | |
253 | } | |
254 | ||
255 | static inline bool ata_get_ata_identify_smart_error_logging_supported(const char *buf) { | |
256 | ata_word_t val = ata_get_word(buf, 84); | |
257 | return val & (1 << 0); | |
258 | } | |
259 | ||
260 | static inline bool ata_get_ata_identify_sense_data_enabled(const char *buf) { | |
261 | ata_word_t val = ata_get_word(buf, 120); | |
262 | return val & (1 << 6); | |
263 | } | |
264 | ||
265 | static inline bool ata_get_ata_identify_smart_supported(const char *buf) { | |
266 | ata_word_t val = ata_get_word(buf, 82); | |
267 | return val & (1 << 0); | |
268 | } | |
269 | ||
270 | static inline bool ata_get_ata_identify_sct_data_tables_supported(const char *buf) { | |
271 | ata_word_t val = ata_get_word(buf, 206); | |
272 | return val & (1 << 5); | |
273 | } | |
274 | ||
275 | static inline bool ata_get_ata_identify_major_version_ata_atapi_7(const char *buf) { | |
276 | ata_word_t val = ata_get_word(buf, 80); | |
277 | return val & (1 << 7); | |
278 | } | |
279 | ||
280 | static inline bool ata_get_ata_identify_iordy_disable_supported(const char *buf) { | |
281 | ata_word_t val = ata_get_word(buf, 49); | |
282 | return val & (1 << 10); | |
283 | } | |
284 | ||
285 | static inline bool ata_get_ata_identify_sata_non_zero_buffer_offsets_enabled(const char *buf) { | |
286 | ata_word_t val = ata_get_word(buf, 79); | |
287 | return val & (1 << 1); | |
288 | } | |
289 | ||
290 | static inline bool ata_get_ata_identify_sata_hardware_feature_control_enabled(const char *buf) { | |
291 | ata_word_t val = ata_get_word(buf, 79); | |
292 | return val & (1 << 5); | |
293 | } | |
294 | ||
295 | static inline bool ata_get_ata_identify_write_buffer_supported(const char *buf) { | |
296 | ata_word_t val = ata_get_word(buf, 82); | |
297 | return val & (1 << 12); | |
298 | } | |
299 | ||
300 | static inline bool ata_get_ata_identify_drat_supported(const char *buf) { | |
301 | ata_word_t val = ata_get_word(buf, 69); | |
302 | return val & (1 << 14); | |
303 | } | |
304 | ||
305 | static inline bool ata_get_ata_identify_read_look_ahead_supported(const char *buf) { | |
306 | ata_word_t val = ata_get_word(buf, 82); | |
307 | return val & (1 << 6); | |
308 | } | |
309 | ||
310 | static inline bool ata_get_ata_identify_security_feature_set_supported(const char *buf) { | |
311 | ata_word_t val = ata_get_word(buf, 82); | |
312 | return val & (1 << 1); | |
313 | } | |
314 | ||
315 | 460 | #endif |
0 | /* Copyright 2015 Baruch Even | |
1 | * | |
2 | * Licensed under the Apache License, Version 2.0 (the "License"); | |
3 | * you may not use this file except in compliance with the License. | |
4 | * You may obtain a copy of the License at | |
5 | * | |
6 | * http://www.apache.org/licenses/LICENSE-2.0 | |
7 | * | |
8 | * Unless required by applicable law or agreed to in writing, software | |
9 | * distributed under the License is distributed on an "AS IS" BASIS, | |
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
11 | * See the License for the specific language governing permissions and | |
12 | * limitations under the License. | |
13 | * | |
14 | */ | |
15 | ||
16 | #ifndef LIBSCSICMD_EXTENDED_INQUIRY_H | |
17 | #define LIBSCSICMD_EXTENDED_INQUIRY_H | |
18 | ||
19 | #include <stdint.h> | |
20 | ||
21 | #define EVPD_MIN_LEN 4 | |
22 | ||
23 | static inline uint8_t evpd_peripheral_qualifier(uint8_t *data) | |
24 | { | |
25 | return data[0] >> 5; | |
26 | } | |
27 | ||
28 | static inline uint8_t evpd_peripheral_device_type(uint8_t *data) | |
29 | { | |
30 | return data[0] & 0x1F; | |
31 | } | |
32 | ||
33 | static inline uint8_t evpd_page_code(uint8_t *data) | |
34 | { | |
35 | return data[1]; | |
36 | } | |
37 | ||
38 | static inline uint16_t evpd_page_len(uint8_t *data) | |
39 | { | |
40 | return (data[2] << 8) | data[3]; | |
41 | } | |
42 | ||
43 | static inline uint8_t *evpd_page_data(uint8_t *data) | |
44 | { | |
45 | return data + EVPD_MIN_LEN; | |
46 | } | |
47 | ||
48 | static inline bool evpd_is_ascii_page(uint8_t page_code) | |
49 | { | |
50 | return 0x01 <= page_code && page_code <= 0x7F; | |
51 | } | |
52 | ||
53 | /* This should be called with the body of the EVPD data and not the full (i.e. with the output of evpd_page_data()) */ | |
54 | static inline uint16_t evpd_ascii_len(uint8_t *evpd_body) | |
55 | { | |
56 | return (evpd_body[0] << 8) | evpd_body[1]; | |
57 | } | |
58 | ||
59 | static inline uint8_t *evpd_ascii_data(uint8_t *evpd_body) | |
60 | { | |
61 | return evpd_body + 2; | |
62 | } | |
63 | ||
64 | static inline uint8_t *evpd_ascii_post_data(uint8_t *evpd_body) | |
65 | { | |
66 | return evpd_body + 2 + evpd_ascii_len(evpd_body); | |
67 | } | |
68 | ||
69 | static inline unsigned evpd_ascii_post_data_len(uint8_t *evpd_body, unsigned full_data_len) | |
70 | { | |
71 | return full_data_len - EVPD_MIN_LEN - 2 - evpd_ascii_len(evpd_body); | |
72 | } | |
73 | ||
74 | static inline bool evpd_is_valid(uint8_t *data, unsigned data_len) | |
75 | { | |
76 | if (data_len < EVPD_MIN_LEN) | |
77 | return false; | |
78 | ||
79 | if (evpd_page_len(data) > data_len) | |
80 | return false; | |
81 | ||
82 | return true; | |
83 | } | |
84 | ||
85 | #endif |
0 | /* Copyright 2015 Baruch Even | |
1 | * | |
2 | * Licensed under the Apache License, Version 2.0 (the "License"); | |
3 | * you may not use this file except in compliance with the License. | |
4 | * You may obtain a copy of the License at | |
5 | * | |
6 | * http://www.apache.org/licenses/LICENSE-2.0 | |
7 | * | |
8 | * Unless required by applicable law or agreed to in writing, software | |
9 | * distributed under the License is distributed on an "AS IS" BASIS, | |
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
11 | * See the License for the specific language governing permissions and | |
12 | * limitations under the License. | |
13 | * | |
14 | */ | |
15 | ||
16 | #ifndef LIBSCSICMD_LOG_SENSE_H | |
17 | #define LIBSCSICMD_LOG_SENSE_H | |
18 | ||
19 | #include "scsicmd_utils.h" | |
20 | #include <stdint.h> | |
21 | #include <stdbool.h> | |
22 | ||
23 | /* Log Sense Header decode */ | |
24 | ||
25 | #define LOG_SENSE_MIN_LEN 4 | |
26 | ||
27 | static inline uint8_t log_sense_page_code(uint8_t *data) | |
28 | { | |
29 | return data[0] & 0x3F; | |
30 | } | |
31 | ||
32 | static inline bool log_sense_subpage_format(uint8_t *data) | |
33 | { | |
34 | return data[0] & 0x40; | |
35 | } | |
36 | ||
37 | static inline bool log_sense_data_saved(uint8_t *data) | |
38 | { | |
39 | return data[0] & 0x80; | |
40 | } | |
41 | ||
42 | static inline uint8_t log_sense_subpage_code(uint8_t *data) | |
43 | { | |
44 | return data[1]; | |
45 | } | |
46 | ||
47 | static inline unsigned log_sense_data_len(uint8_t *data) | |
48 | { | |
49 | return get_uint16(data, 2); | |
50 | } | |
51 | ||
52 | static inline uint8_t *log_sense_data(uint8_t *data) | |
53 | { | |
54 | return data + LOG_SENSE_MIN_LEN; | |
55 | } | |
56 | ||
57 | static inline uint8_t *log_sense_data_end(uint8_t *data, unsigned data_len) | |
58 | { | |
59 | return data + safe_len(data, data_len, log_sense_data(data), log_sense_data_len(data)); | |
60 | } | |
61 | ||
62 | static inline bool log_sense_is_valid(uint8_t *data, unsigned data_len) | |
63 | { | |
64 | if (data_len < LOG_SENSE_MIN_LEN) | |
65 | return false; | |
66 | if (!log_sense_subpage_format(data) && log_sense_subpage_code(data) != 0) | |
67 | return false; | |
68 | if (log_sense_data_len(data) + LOG_SENSE_MIN_LEN < data_len) | |
69 | return false; | |
70 | return true; | |
71 | } | |
72 | ||
73 | /* Log Sense Parameter decode */ | |
74 | #define LOG_SENSE_MIN_PARAM_LEN 4 | |
75 | ||
76 | #define LOG_PARAM_FLAG_DU 0x80 | |
77 | #define LOG_PARAM_FLAG_TSD 0x20 | |
78 | #define LOG_PARAM_FLAG_ETC 0x10 | |
79 | #define LOG_PARAM_FLAG_TMC_MASK 0x0C | |
80 | #define LOG_PARAM_FLAG_FMT_MASK 0x03 | |
81 | ||
82 | #define LOG_PARAM_TMC_EVERY_UPDATE 0 | |
83 | #define LOG_PARAM_TMC_EQUAL 1 | |
84 | #define LOG_PARAM_TMC_NOT_EQUAL 2 | |
85 | #define LOG_PARAM_TMC_GREATER 3 | |
86 | ||
87 | #define LOG_PARAM_FMT_COUNTER_STOP 0 | |
88 | #define LOG_PARAM_FMT_ASCII 1 | |
89 | #define LOG_PARAM_FMT_COUNTER_ROLLOVER 2 | |
90 | #define LOG_PARAM_FMT_BINARY 2 | |
91 | ||
92 | static inline uint16_t log_sense_param_code(uint8_t *param) | |
93 | { | |
94 | return get_uint16(param, 0); | |
95 | } | |
96 | ||
97 | inline static uint8_t log_sense_param_flags(uint8_t *param) | |
98 | { | |
99 | return param[2]; | |
100 | } | |
101 | ||
102 | inline static uint8_t log_sense_param_tmc(uint8_t *param) | |
103 | { | |
104 | return (log_sense_param_flags(param) & LOG_PARAM_FLAG_TMC_MASK) >> 2; | |
105 | } | |
106 | ||
107 | inline static uint8_t log_sense_param_fmt(uint8_t *param) | |
108 | { | |
109 | return log_sense_param_flags(param) & LOG_PARAM_FLAG_FMT_MASK; | |
110 | } | |
111 | ||
112 | static inline unsigned log_sense_param_len(uint8_t *param) | |
113 | { | |
114 | return param[3]; | |
115 | } | |
116 | ||
117 | static inline uint8_t *log_sense_param_data(uint8_t *param) | |
118 | { | |
119 | return param + LOG_SENSE_MIN_PARAM_LEN; | |
120 | } | |
121 | ||
122 | static inline bool log_sense_param_is_valid(uint8_t *data, unsigned data_len, uint8_t *param) | |
123 | { | |
124 | if (param < data) | |
125 | return false; | |
126 | ||
127 | const unsigned param_offset = param - data; | |
128 | if (param_offset > data_len) | |
129 | return false; | |
130 | ||
131 | if (param_offset + LOG_SENSE_MIN_PARAM_LEN > data_len) | |
132 | return false; | |
133 | ||
134 | if (param_offset + LOG_SENSE_MIN_PARAM_LEN + log_sense_param_len(param) > data_len) | |
135 | return false; | |
136 | ||
137 | return true; | |
138 | } | |
139 | ||
140 | #define for_all_log_sense_params(data, data_len, param) \ | |
141 | for (param = log_sense_data(data); \ | |
142 | log_sense_param_is_valid(data, data_len, param); \ | |
143 | param = param + LOG_SENSE_MIN_PARAM_LEN + log_sense_param_len(param)) | |
144 | ||
145 | #define for_all_log_sense_pg_0_supported_pages(data, data_len, supported_page) \ | |
146 | uint8_t *__tmp; \ | |
147 | for (__tmp = log_sense_data(data), supported_page = __tmp[0]; __tmp < log_sense_data_end(data, data_len); __tmp++, supported_page = __tmp[0]) | |
148 | ||
149 | #define for_all_log_sense_pg_0_supported_subpages(data, data_len, supported_page, supported_subpage) \ | |
150 | uint8_t *__tmp; \ | |
151 | for (__tmp = log_sense_data(data), supported_page = __tmp[0], supported_subpage = __tmp[1]; __tmp + 1 < log_sense_data_end(data, data_len); __tmp+=2, supported_page = __tmp[0], supported_subpage = __tmp[1]) | |
152 | ||
153 | bool log_sense_page_informational_exceptions(uint8_t *page, unsigned page_len, uint8_t *asc, uint8_t *ascq, uint8_t *temperature); | |
154 | ||
155 | #endif |
0 | /* Copyright 2015 Baruch Even | |
1 | * | |
2 | * Licensed under the Apache License, Version 2.0 (the "License"); | |
3 | * you may not use this file except in compliance with the License. | |
4 | * You may obtain a copy of the License at | |
5 | * | |
6 | * http://www.apache.org/licenses/LICENSE-2.0 | |
7 | * | |
8 | * Unless required by applicable law or agreed to in writing, software | |
9 | * distributed under the License is distributed on an "AS IS" BASIS, | |
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
11 | * See the License for the specific language governing permissions and | |
12 | * limitations under the License. | |
13 | * | |
14 | */ | |
15 | ||
16 | #ifndef LIBSCSICMD_MODE_SENSE_H | |
17 | #define LIBSCSICMD_MODE_SENSE_H | |
18 | ||
19 | #include "scsicmd_utils.h" | |
20 | ||
21 | /* Mode parameter header for the MODE SENSE 6 */ | |
22 | #define MODE_SENSE_6_MIN_LEN 4u | |
23 | ||
24 | static inline unsigned mode_sense_6_data_len(uint8_t *data) | |
25 | { | |
26 | return data[0]; | |
27 | } | |
28 | ||
29 | static inline uint8_t mode_sense_6_medium_type(uint8_t *data) | |
30 | { | |
31 | return data[1]; | |
32 | } | |
33 | ||
34 | static inline uint8_t mode_sense_6_device_specific_param(uint8_t *data) | |
35 | { | |
36 | return data[2]; | |
37 | } | |
38 | ||
39 | static inline uint8_t mode_sense_6_block_descriptor_length(uint8_t *data) | |
40 | { | |
41 | return data[3]; | |
42 | } | |
43 | ||
44 | static inline uint8_t *mode_sense_6_block_descriptor_data(uint8_t *data) | |
45 | { | |
46 | return data + MODE_SENSE_6_MIN_LEN; | |
47 | } | |
48 | ||
49 | static inline uint8_t *mode_sense_6_mode_data(uint8_t *data) | |
50 | { | |
51 | return data + MODE_SENSE_6_MIN_LEN + mode_sense_6_block_descriptor_length(data); | |
52 | } | |
53 | ||
54 | static inline unsigned mode_sense_6_expected_length(uint8_t *data) | |
55 | { | |
56 | return 1 + mode_sense_6_data_len(data); // Add the first byte that is not part of the mode data length | |
57 | } | |
58 | ||
59 | static inline unsigned mode_sense_6_mode_data_len(uint8_t *data) | |
60 | { | |
61 | return mode_sense_6_expected_length(data) - MODE_SENSE_6_MIN_LEN - mode_sense_6_block_descriptor_length(data); | |
62 | } | |
63 | ||
64 | static inline bool mode_sense_6_is_valid_header(uint8_t *data, unsigned data_len) | |
65 | { | |
66 | if (mode_sense_6_data_len(data) < MODE_SENSE_6_MIN_LEN-1) | |
67 | return false; | |
68 | if (data_len < (unsigned)(mode_sense_6_data_len(data)) + 1) | |
69 | return false; | |
70 | if (mode_sense_6_block_descriptor_length(data) != 0 && | |
71 | mode_sense_6_block_descriptor_length(data) != 8) | |
72 | { | |
73 | return false; | |
74 | } | |
75 | if (mode_sense_6_data_len(data) < mode_sense_6_block_descriptor_length(data)) | |
76 | return false; | |
77 | return true; | |
78 | } | |
79 | ||
80 | /* Mode parameter header for the MODE SENSE 10 */ | |
81 | #define MODE_SENSE_10_MIN_LEN 8u | |
82 | ||
83 | static inline unsigned mode_sense_10_data_len(uint8_t *data) | |
84 | { | |
85 | return get_uint16(data, 0); | |
86 | } | |
87 | ||
88 | static inline uint8_t mode_sense_10_medium_type(uint8_t *data) | |
89 | { | |
90 | return data[2]; | |
91 | } | |
92 | ||
93 | static inline uint8_t mode_sense_10_device_specific_param(uint8_t *data) | |
94 | { | |
95 | return data[3]; | |
96 | } | |
97 | ||
98 | static inline bool mode_sense_10_long_lba(uint8_t *data) | |
99 | { | |
100 | return data[4] & 1; | |
101 | } | |
102 | ||
103 | /* SPC4 says length is times 8 without long lba and times 16 with it but it seems the value is taken verbatim */ | |
104 | static inline unsigned mode_sense_10_block_descriptor_length(uint8_t *data) | |
105 | { | |
106 | return get_uint16(data, 6); | |
107 | } | |
108 | ||
109 | static inline uint8_t *mode_sense_10_block_descriptor_data(uint8_t *data) | |
110 | { | |
111 | if (mode_sense_10_block_descriptor_length(data) > 0) | |
112 | return data + MODE_SENSE_10_MIN_LEN; | |
113 | else | |
114 | return NULL; | |
115 | } | |
116 | ||
117 | static inline uint8_t *mode_sense_10_mode_data(uint8_t *data) | |
118 | { | |
119 | return data + MODE_SENSE_10_MIN_LEN + mode_sense_10_block_descriptor_length(data); | |
120 | } | |
121 | ||
122 | static inline unsigned mode_sense_10_expected_length(uint8_t *data) | |
123 | { | |
124 | return 2 + mode_sense_10_data_len(data); // Add the first two bytes that are not part of the mode data length | |
125 | } | |
126 | ||
127 | static inline unsigned mode_sense_10_mode_data_len(uint8_t *data) | |
128 | { | |
129 | return mode_sense_10_expected_length(data) - MODE_SENSE_10_MIN_LEN - mode_sense_10_block_descriptor_length(data); | |
130 | } | |
131 | ||
132 | static inline bool mode_sense_10_is_valid_header(uint8_t *data, unsigned data_len) | |
133 | { | |
134 | if (mode_sense_10_data_len(data) < MODE_SENSE_10_MIN_LEN-2) | |
135 | return false; | |
136 | if (data_len < (unsigned)(mode_sense_10_data_len(data)) + 2) | |
137 | return false; | |
138 | if (mode_sense_10_block_descriptor_length(data) != 0 && | |
139 | mode_sense_10_block_descriptor_length(data) != 8) | |
140 | { | |
141 | return false; | |
142 | } | |
143 | return true; | |
144 | } | |
145 | ||
146 | /* Regular block descriptor (as opposed to long) */ | |
147 | #define BLOCK_DESCRIPTOR_LENGTH 8 | |
148 | #define BLOCK_DESCRIPTOR_NUM_BLOCKS_OVERFLOW 0xFFFFFF | |
149 | ||
150 | static inline uint8_t block_descriptor_density_code(uint8_t *data) | |
151 | { | |
152 | return data[0]; | |
153 | } | |
154 | ||
155 | static inline uint32_t block_descriptor_num_blocks(uint8_t *data) | |
156 | { | |
157 | return get_uint24(data, 1); | |
158 | } | |
159 | ||
160 | static inline uint32_t block_descriptor_block_length(uint8_t *data) | |
161 | { | |
162 | return get_uint24(data, 5); | |
163 | } | |
164 | ||
165 | /* Mode Sense page data */ | |
166 | static inline uint8_t mode_sense_data_page_code(uint8_t *data) | |
167 | { | |
168 | return data[0] & 0x3F; | |
169 | } | |
170 | ||
171 | static inline bool mode_sense_data_subpage_format(uint8_t *data) | |
172 | { | |
173 | return data[0] & 0x40; | |
174 | } | |
175 | ||
176 | static inline bool mode_sense_data_parameter_saveable(uint8_t *data) | |
177 | { | |
178 | return data[0] & 0x80; | |
179 | } | |
180 | ||
181 | /* Caller is required to know if this is a subpage format page or not */ | |
182 | static inline uint8_t mode_sense_data_subpage_code(uint8_t *data) | |
183 | { | |
184 | return data[1]; | |
185 | } | |
186 | ||
187 | static inline unsigned mode_sense_data_page_len(uint8_t *data) | |
188 | { | |
189 | return mode_sense_data_subpage_format(data) ? 3 + (unsigned)(get_uint16(data, 2)) : 2 + (unsigned)(data[1]); | |
190 | } | |
191 | ||
192 | static inline unsigned mode_sense_data_param_len(uint8_t *data) | |
193 | { | |
194 | return mode_sense_data_subpage_format(data) ? get_uint16(data, 2) : data[1]; | |
195 | } | |
196 | ||
197 | static inline uint8_t *mode_sense_data_param(uint8_t *data) | |
198 | { | |
199 | return mode_sense_data_subpage_format(data) ? data + 4 : data + 2; | |
200 | } | |
201 | ||
202 | static inline bool mode_sense_data_param_is_valid(uint8_t *data, unsigned data_len) | |
203 | { | |
204 | if (data_len < 2) | |
205 | return false; | |
206 | if (mode_sense_data_page_code(data) == 0) | |
207 | return false; | |
208 | if (mode_sense_data_subpage_format(data) && data_len < 4) | |
209 | return false; | |
210 | if (data_len < mode_sense_data_page_len(data)) | |
211 | return false; | |
212 | return true; | |
213 | } | |
214 | ||
215 | ||
216 | #define for_all_mode_sense_pages(data, data_len, mode_data, mode_data_len, page, remaining_len) \ | |
217 | for (remaining_len = mode_data - data + safe_len(data, data_len, mode_data, mode_data_len), page = mode_data; \ | |
218 | remaining_len >= 3 && mode_sense_data_param_is_valid(page, remaining_len); \ | |
219 | remaining_len += mode_sense_data_param_len(page), page += mode_sense_data_page_len(page)) | |
220 | ||
221 | #define for_all_mode_sense_6_pages(data, data_len, page, remaining_len) \ | |
222 | for_all_mode_sense_pages(data, data_len, mode_sense_6_mode_data(data), mode_sense_6_mode_data_len(data), page, remaining_len) | |
223 | ||
224 | #define for_all_mode_sense_10_pages(data, data_len, page, remaining_len) \ | |
225 | for_all_mode_sense_pages(data, data_len, mode_sense_10_mode_data(data), mode_sense_10_mode_data_len(data), page, remaining_len) | |
226 | ||
227 | #endif |
0 | /* Copyright 2015 Baruch Even | |
1 | * | |
2 | * Licensed under the Apache License, Version 2.0 (the "License"); | |
3 | * you may not use this file except in compliance with the License. | |
4 | * You may obtain a copy of the License at | |
5 | * | |
6 | * http://www.apache.org/licenses/LICENSE-2.0 | |
7 | * | |
8 | * Unless required by applicable law or agreed to in writing, software | |
9 | * distributed under the License is distributed on an "AS IS" BASIS, | |
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
11 | * See the License for the specific language governing permissions and | |
12 | * limitations under the License. | |
13 | * | |
14 | */ | |
15 | ||
16 | #ifndef LIBSCSICMD_READ_DEFECT_DATA_H | |
17 | #define LIBSCSICMD_READ_DEFECT_DATA_H | |
18 | ||
19 | #include "scsicmd_utils.h" | |
20 | #include "scsicmd.h" | |
21 | #include <stdbool.h> | |
22 | #include <stdint.h> | |
23 | ||
24 | const char *read_defect_data_format_to_str(uint8_t fmt); | |
25 | ||
26 | /* READ DEFECT DATA 10 */ | |
27 | ||
28 | #define READ_DEFECT_DATA_10_MIN_LEN 4 | |
29 | ||
30 | static inline bool read_defect_data_10_is_plist_valid(uint8_t *data) | |
31 | { | |
32 | return data[1] & 0x10; | |
33 | } | |
34 | ||
35 | static inline bool read_defect_data_10_is_glist_valid(uint8_t *data) | |
36 | { | |
37 | return data[1] & 0x08; | |
38 | } | |
39 | ||
40 | static inline uint8_t read_defect_data_10_list_format(uint8_t *data) | |
41 | { | |
42 | return data[1] & 0x07; | |
43 | } | |
44 | ||
45 | static inline uint16_t read_defect_data_10_len(uint8_t *data) | |
46 | { | |
47 | return get_uint16(data, 2); | |
48 | } | |
49 | ||
50 | /* For READ DEFECT DATA 10 the user may ask for only the header and the data is never really transfered, allow for this seperation in the checks. */ | |
51 | static inline bool read_defect_data_10_hdr_is_valid(uint8_t *data, unsigned data_len) | |
52 | { | |
53 | if (data_len < READ_DEFECT_DATA_10_MIN_LEN) | |
54 | return false; | |
55 | if ((read_defect_data_10_len(data) % 4) != 0) | |
56 | return false; | |
57 | return true; | |
58 | } | |
59 | ||
60 | static inline bool read_defect_data_10_is_valid(uint8_t *data, unsigned data_len) | |
61 | { | |
62 | if (!read_defect_data_10_hdr_is_valid(data, data_len)) | |
63 | return false; | |
64 | if ((unsigned)read_defect_data_10_len(data) + READ_DEFECT_DATA_10_MIN_LEN < data_len) | |
65 | return false; | |
66 | return true; | |
67 | } | |
68 | ||
69 | static inline uint8_t *read_defect_data_10_data(uint8_t *data) | |
70 | { | |
71 | return data + READ_DEFECT_DATA_10_MIN_LEN; | |
72 | } | |
73 | ||
74 | /* READ DEFECT DATA 10 */ | |
75 | ||
76 | #define READ_DEFECT_DATA_12_MIN_LEN 8 | |
77 | ||
78 | static inline bool read_defect_data_12_is_plist_valid(uint8_t *data) | |
79 | { | |
80 | return data[1] & 0x10; | |
81 | } | |
82 | ||
83 | static inline bool read_defect_data_12_is_glist_valid(uint8_t *data) | |
84 | { | |
85 | return data[1] & 0x08; | |
86 | } | |
87 | ||
88 | static inline uint8_t read_defect_data_12_list_format(uint8_t *data) | |
89 | { | |
90 | return data[1] & 0x07; | |
91 | } | |
92 | ||
93 | static inline uint32_t read_defect_data_12_len(uint8_t *data) | |
94 | { | |
95 | return get_uint32(data, 4); | |
96 | } | |
97 | ||
98 | /* For READ DEFECT DATA 10 the user may ask for only the header and the data is never really transfered, allow for this seperation in the checks. */ | |
99 | static inline bool read_defect_data_12_hdr_is_valid(uint8_t *data, unsigned data_len) | |
100 | { | |
101 | if (data_len < READ_DEFECT_DATA_12_MIN_LEN) | |
102 | return false; | |
103 | if ((read_defect_data_12_len(data) % 4) != 0) | |
104 | return false; | |
105 | return true; | |
106 | } | |
107 | ||
108 | static inline bool read_defect_data_12_is_valid(uint8_t *data, unsigned data_len) | |
109 | { | |
110 | if (!read_defect_data_12_hdr_is_valid(data, data_len)) | |
111 | return false; | |
112 | if (read_defect_data_12_len(data) + READ_DEFECT_DATA_12_MIN_LEN < data_len) | |
113 | return false; | |
114 | return true; | |
115 | } | |
116 | ||
117 | static inline uint8_t *read_defect_data_12_data(uint8_t *data) | |
118 | { | |
119 | return data + READ_DEFECT_DATA_12_MIN_LEN; | |
120 | } | |
121 | ||
122 | /* Formats */ | |
123 | ||
124 | /* Short format */ | |
125 | #define FORMAT_ADDRESS_SHORT_LEN 4 | |
126 | static inline uint32_t format_address_short_lba(uint8_t *data) | |
127 | { | |
128 | return get_uint32(data, 0); | |
129 | } | |
130 | ||
131 | /* Long format */ | |
132 | #define FORMAT_ADDRESS_LONG_LEN 8 | |
133 | static inline uint32_t format_address_long_lba(uint8_t *data) | |
134 | { | |
135 | return get_uint64(data, 0); | |
136 | } | |
137 | ||
138 | /* Byte from index */ | |
139 | #define FORMAT_ADDRESS_BYTE_FROM_INDEX_LEN 8 | |
140 | static inline uint32_t format_address_byte_from_index_cylinder(uint8_t *data) | |
141 | { | |
142 | return get_uint24(data, 0); | |
143 | } | |
144 | ||
145 | static inline uint8_t format_address_byte_from_index_head(uint8_t *data) | |
146 | { | |
147 | return data[3]; | |
148 | } | |
149 | ||
150 | static inline uint32_t format_address_byte_from_index_bytes(uint8_t *data) | |
151 | { | |
152 | return get_uint32(data, 4); | |
153 | } | |
154 | #define FORMAT_ADDRESS_BYTE_FROM_INDEX_ALL_TRACK 0xFFFFFFFF | |
155 | ||
156 | /* Physical sector format */ | |
157 | #define FORMAT_ADDRESS_PHYSICAL_LEN 8 | |
158 | static inline uint32_t format_address_physical_cylinder(uint8_t *data) | |
159 | { | |
160 | return get_uint24(data, 0); | |
161 | } | |
162 | ||
163 | static inline uint8_t format_address_physical_head(uint8_t *data) | |
164 | { | |
165 | return data[3]; | |
166 | } | |
167 | ||
168 | static inline uint32_t format_address_physical_sector(uint8_t *data) | |
169 | { | |
170 | return get_uint32(data, 4); | |
171 | } | |
172 | #define FORMAT_ADDRESS_PHYSICAL_ALL_TRACK 0xFFFFFFFF | |
173 | ||
174 | static inline unsigned read_defect_data_fmt_len(address_desc_format_e fmt) | |
175 | { | |
176 | switch (fmt) { | |
177 | case ADDRESS_FORMAT_SHORT: return FORMAT_ADDRESS_SHORT_LEN; | |
178 | case ADDRESS_FORMAT_LONG: return FORMAT_ADDRESS_LONG_LEN; | |
179 | case ADDRESS_FORMAT_INDEX_OFFSET: return FORMAT_ADDRESS_BYTE_FROM_INDEX_LEN; | |
180 | case ADDRESS_FORMAT_PHYSICAL: return FORMAT_ADDRESS_PHYSICAL_LEN; | |
181 | case ADDRESS_FORMAT_VENDOR: return 4; | |
182 | default: return 0; | |
183 | } | |
184 | } | |
185 | ||
186 | #endif |
0 | /* Copyright 2015 Baruch Even | |
1 | * | |
2 | * Licensed under the Apache License, Version 2.0 (the "License"); | |
3 | * you may not use this file except in compliance with the License. | |
4 | * You may obtain a copy of the License at | |
5 | * | |
6 | * http://www.apache.org/licenses/LICENSE-2.0 | |
7 | * | |
8 | * Unless required by applicable law or agreed to in writing, software | |
9 | * distributed under the License is distributed on an "AS IS" BASIS, | |
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
11 | * See the License for the specific language governing permissions and | |
12 | * limitations under the License. | |
13 | * | |
14 | */ | |
15 | ||
16 | #ifndef LIBSCSICMD_RECEIVE_DIAGNOSTICS_H | |
17 | #define LIBSCSICMD_RECEIVE_DIAGNOSTICS_H | |
18 | ||
19 | #include "scsicmd_utils.h" | |
20 | #include <stdint.h> | |
21 | #include <memory.h> | |
22 | ||
23 | #define RECV_DIAG_MIN_LEN 4 | |
24 | ||
25 | static inline uint8_t recv_diag_get_page_code(uint8_t *data) | |
26 | { | |
27 | return data[0]; | |
28 | } | |
29 | ||
30 | static inline uint8_t recv_diag_get_page_code_specific(uint8_t *data) | |
31 | { | |
32 | return data[1]; | |
33 | } | |
34 | ||
35 | static inline uint16_t recv_diag_get_len(uint8_t *data) | |
36 | { | |
37 | return (data[2] << 8) | data[3]; | |
38 | } | |
39 | ||
40 | static inline uint8_t *recv_diag_data(uint8_t *data) | |
41 | { | |
42 | return data + RECV_DIAG_MIN_LEN; | |
43 | } | |
44 | ||
45 | static inline bool recv_diag_is_valid(uint8_t *data, unsigned data_len) | |
46 | { | |
47 | if (data_len < RECV_DIAG_MIN_LEN) | |
48 | return false; | |
49 | if ((unsigned)recv_diag_get_len(data) + RECV_DIAG_MIN_LEN > data_len) | |
50 | return false; | |
51 | return true; | |
52 | } | |
53 | ||
54 | /* SES Page 1 Configuration */ | |
55 | ||
56 | static inline bool ses_config_is_valid(uint8_t *data, unsigned data_len) | |
57 | { | |
58 | if (data_len < 8) | |
59 | return false; | |
60 | if (recv_diag_get_len(data) < 4) | |
61 | return false; | |
62 | return true; | |
63 | } | |
64 | ||
65 | static inline uint8_t ses_config_num_sub_enclosures(uint8_t *data) | |
66 | { | |
67 | return data[1] + 1; // +1 for primary | |
68 | } | |
69 | ||
70 | static inline uint32_t ses_config_generation(uint8_t *data) | |
71 | { | |
72 | return get_uint32(data, 4); | |
73 | } | |
74 | ||
75 | static inline uint8_t *ses_config_sub_enclosure(uint8_t *data) | |
76 | { | |
77 | return data + 8; | |
78 | } | |
79 | ||
80 | /* Enclosure Descriptor */ | |
81 | static inline uint8_t ses_config_enclosure_descriptor_process_identifier(uint8_t *data) | |
82 | { | |
83 | return (data[0] >> 4) & 0x7; | |
84 | } | |
85 | ||
86 | static inline uint8_t ses_config_enclosure_descriptor_num_processes(uint8_t *data) | |
87 | { | |
88 | return data[0] & 0x7; | |
89 | } | |
90 | ||
91 | static inline uint8_t ses_config_enclosure_descriptor_subenclosure_identifier(uint8_t *data) | |
92 | { | |
93 | return data[1]; | |
94 | } | |
95 | ||
96 | static inline uint8_t ses_config_enclosure_descriptor_num_type_descriptors(uint8_t *data) | |
97 | { | |
98 | return data[2]; | |
99 | } | |
100 | ||
101 | static inline uint8_t ses_config_enclosure_descriptor_len(uint8_t *data) | |
102 | { | |
103 | return data[3]; | |
104 | } | |
105 | ||
106 | static inline uint64_t ses_config_enclosure_descriptor_logical_identifier(uint8_t *data) | |
107 | { | |
108 | return get_uint64(data, 4); | |
109 | } | |
110 | ||
111 | static inline bool ses_config_enclosure_descriptor_is_valid(uint8_t *data, unsigned data_len) | |
112 | { | |
113 | if (data_len < 12) | |
114 | return false; | |
115 | if (ses_config_enclosure_descriptor_len(data) < 36 || | |
116 | ses_config_enclosure_descriptor_len(data) > 252 || | |
117 | ses_config_enclosure_descriptor_len(data) > data_len) | |
118 | { | |
119 | return false; | |
120 | } | |
121 | return true; | |
122 | } | |
123 | ||
124 | static inline void _ses_str_cpy(uint8_t *src, unsigned src_len, char *s, unsigned slen) | |
125 | { | |
126 | if (slen > src_len) | |
127 | slen = src_len; | |
128 | else | |
129 | slen--; | |
130 | ||
131 | memcpy(s, src, slen); | |
132 | s[slen] = 0; | |
133 | } | |
134 | ||
135 | static inline void ses_config_enclosure_descriptor_vendor_identifier(uint8_t *data, char *s, unsigned slen) | |
136 | { | |
137 | _ses_str_cpy(data+12, 8, s, slen); | |
138 | } | |
139 | ||
140 | static inline void ses_config_enclosure_descriptor_product_identifier(uint8_t *data, char *s, unsigned slen) | |
141 | { | |
142 | _ses_str_cpy(data+20, 16, s, slen); | |
143 | } | |
144 | ||
145 | static inline void ses_config_enclosure_descriptor_revision_level(uint8_t *data, char *s, unsigned slen) | |
146 | { | |
147 | _ses_str_cpy(data+36, 4, s, slen); | |
148 | } | |
149 | ||
150 | static inline uint8_t *ses_config_enclosure_descriptor_vendor_info(uint8_t *data) | |
151 | { | |
152 | return data + 40; | |
153 | } | |
154 | ||
155 | static inline uint8_t ses_config_enclosure_descriptor_vendor_len(uint8_t *data) | |
156 | { | |
157 | return ses_config_enclosure_descriptor_len(data) + 4 - 40; | |
158 | } | |
159 | ||
160 | #endif |
87 | 87 | |
88 | 88 | const char *scsi_device_type_name(scsi_device_type_e dev_type); |
89 | 89 | |
90 | #define SCSI_PROTOCOL_IDENTIFIER_LIST \ | |
91 | X(FC, 0, "Fibre Channel") \ | |
92 | X(PARALLEL_SCSI, 1, "Parallel SCSI") \ | |
93 | X(SSA, 2, "SSA") \ | |
94 | X(IEEE1394, 3, "IEEE 1394") \ | |
95 | X(SRP, 4, "SCSI Remote DMA") \ | |
96 | X(ISCSI, 5, "iSCSI") \ | |
97 | X(SAS, 6, "SAS") \ | |
98 | X(ADT, 7, "Automation Drive Interface") \ | |
99 | X(ATA, 8, "ATA/ATAPI") \ | |
100 | X(RESERVED_9, 9, "Reserved9") \ | |
101 | X(RESERVED_A, 10, "Reserved10") \ | |
102 | X(RESERVED_B, 11, "Reserved11") \ | |
103 | X(RESERVED_C, 12, "Reserved12") \ | |
104 | X(RESERVED_D, 13, "Reserved13") \ | |
105 | X(RESERVED_E, 14, "Reserved14") \ | |
106 | X(NONE, 15, "No Specific Protocol") | |
107 | ||
108 | #undef X | |
109 | #define X(name, val, str) SCSI_PROTOCOL_IDENTIFIER_ ## name, | |
110 | typedef enum scsi_protocol_identifier_e { | |
111 | SCSI_PROTOCOL_IDENTIFIER_LIST | |
112 | } scsi_protocol_identifier_e; | |
113 | #undef X | |
114 | ||
90 | 115 | typedef struct ata_status_t { |
91 | 116 | uint8_t extend; |
92 | 117 | uint8_t error; |
141 | 166 | bool scsi_parse_sense(unsigned char *sense, int sense_len, sense_info_t *info); |
142 | 167 | |
143 | 168 | /* inquiry */ |
169 | ||
170 | /** Build a CDB from the inquiry command. | |
171 | */ | |
144 | 172 | int cdb_inquiry(unsigned char *cdb, bool evpd, char page_code, uint16_t alloc_len); |
173 | ||
174 | /** Build a CDB from the simple inquiry command that returns the basic information. | |
175 | * The size can be up to 256 bytes but in order to be able to handle older SCSI devices it is recommended to use the size of 96 bytes. | |
176 | */ | |
145 | 177 | static inline int cdb_inquiry_simple(unsigned char *cdb, uint16_t alloc_len) { return cdb_inquiry(cdb, 0, 0, alloc_len); } |
178 | ||
179 | /** Parse the simple inquiry page data. */ | |
146 | 180 | bool parse_inquiry(unsigned char *buf, unsigned buf_len, int *device_type, scsi_vendor_t vendor, |
147 | 181 | scsi_model_t model, scsi_fw_revision_t rev, scsi_serial_t serial); |
148 | 182 | |
149 | 183 | /* read capacity */ |
184 | ||
185 | // READ CAPACITY 10 expects a buffer of 8 bytes | |
150 | 186 | int cdb_read_capacity_10(unsigned char *cdb); |
151 | 187 | bool parse_read_capacity_10(unsigned char *buf, unsigned buf_len, uint32_t *max_lba, uint32_t *block_size); |
188 | ||
189 | // READ CAPACITY 16 allows to set the receive buffer size but it should be at least 32 bytes | |
152 | 190 | int cdb_read_capacity_16(unsigned char *cdb, uint32_t alloc_len); |
153 | 191 | bool parse_read_capacity_16(unsigned char *buf, unsigned buf_len, uint64_t *max_lba, uint32_t *block_size, bool *prot_enable, |
154 | 192 | unsigned *p_type, unsigned *p_i_exponent, unsigned *logical_blocks_per_physical_block_exponent, |
167 | 205 | /* log sense */ |
168 | 206 | int cdb_log_sense(unsigned char *cdb, uint8_t page_code, uint8_t subpage_code, uint16_t alloc_len); |
169 | 207 | |
208 | /* mode sense */ | |
209 | typedef enum { | |
210 | PAGE_CONTROL_CURRENT = 0, | |
211 | PAGE_CONTROL_CHANGEABLE = 1, | |
212 | PAGE_CONTROL_DEFAULT = 2, | |
213 | PAGE_CONTROL_SAVED = 3, | |
214 | } page_control_e; | |
215 | int cdb_mode_sense_6(unsigned char *cdb, bool disable_block_descriptor, page_control_e page_control, uint8_t page_code, uint8_t subpage_code, uint8_t alloc_len); | |
216 | int cdb_mode_sense_10(unsigned char *cdb, bool long_lba_accepted, bool disable_block_descriptor, page_control_e page_control, uint8_t page_code, uint8_t subpage_code, uint16_t alloc_len); | |
217 | ||
218 | /* send/receive diagnostics */ | |
219 | int cdb_receive_diagnostics(unsigned char *cdb, bool page_code_valid, uint8_t page_code, uint16_t alloc_len); | |
220 | ||
221 | typedef enum { | |
222 | SELF_TEST_ZERO = 0, | |
223 | SELF_TEST_BACKGROUND_SHORT = 1, | |
224 | SELF_TEST_BACKGROUND_EXTENDED = 2, | |
225 | SELF_TEST_RESERVED1 = 3, | |
226 | SELF_TEST_BACKGROUND_ABORT = 4, | |
227 | SELF_TEST_FOREGROUND_SHORT = 5, | |
228 | SELF_TEST_FOREGROUND_EXTENDED = 6, | |
229 | SELF_TEST_RESERVED2 = 7, | |
230 | } self_test_code_e; | |
231 | int cdb_send_diagnostics(unsigned char *cdb, self_test_code_e self_test, uint16_t param_len); | |
232 | ||
233 | /* read defect data */ | |
234 | typedef enum { | |
235 | ADDRESS_FORMAT_SHORT = 0, | |
236 | ADDRESS_FORMAT_RESERVED_1 = 1, | |
237 | ADDRESS_FORMAT_RESERVED_2 = 2, | |
238 | ADDRESS_FORMAT_LONG = 3, | |
239 | ADDRESS_FORMAT_INDEX_OFFSET = 4, | |
240 | ADDRESS_FORMAT_PHYSICAL = 5, | |
241 | ADDRESS_FORMAT_VENDOR = 6, | |
242 | ADDRESS_FORMAT_RESERVED_3 = 7, | |
243 | } address_desc_format_e; | |
244 | ||
245 | int cdb_read_defect_data_10(unsigned char *cdb, bool plist, bool glist, address_desc_format_e format, uint16_t alloc_len); | |
246 | int cdb_read_defect_data_12(unsigned char *cdb, bool plist, bool glist, address_desc_format_e format, uint32_t alloc_len); | |
247 | ||
170 | 248 | #endif |
0 | /* Copyright 2015 Baruch Even | |
1 | * | |
2 | * Licensed under the Apache License, Version 2.0 (the "License"); | |
3 | * you may not use this file except in compliance with the License. | |
4 | * You may obtain a copy of the License at | |
5 | * | |
6 | * http://www.apache.org/licenses/LICENSE-2.0 | |
7 | * | |
8 | * Unless required by applicable law or agreed to in writing, software | |
9 | * distributed under the License is distributed on an "AS IS" BASIS, | |
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
11 | * See the License for the specific language governing permissions and | |
12 | * limitations under the License. | |
13 | * | |
14 | */ | |
15 | ||
16 | #ifndef LIBSCSICMD_UTILS_H | |
17 | #define LIBSCSICMD_UTILS_H | |
18 | ||
19 | #include <stdint.h> | |
20 | ||
21 | static inline uint16_t get_uint16(unsigned char *buf, int start) | |
22 | { | |
23 | return (uint16_t)buf[start] << 8 | | |
24 | (uint16_t)buf[start+1]; | |
25 | } | |
26 | ||
27 | static inline uint32_t get_uint24(unsigned char *buf, int start) | |
28 | { | |
29 | return (uint32_t)buf[start] << 16 | | |
30 | (uint32_t)buf[start+1] << 8 | | |
31 | (uint32_t)buf[start+2]; | |
32 | } | |
33 | ||
34 | static inline uint32_t get_uint32(unsigned char *buf, int start) | |
35 | { | |
36 | return (uint32_t)buf[start] << 24 | | |
37 | (uint32_t)buf[start+1] << 16 | | |
38 | (uint32_t)buf[start+2] << 8 | | |
39 | (uint32_t)buf[start+3]; | |
40 | } | |
41 | ||
42 | static inline uint64_t get_uint64(unsigned char *buf, int start) | |
43 | { | |
44 | return (uint64_t)buf[start] << 56 | | |
45 | (uint64_t)buf[start+1] << 48 | | |
46 | (uint64_t)buf[start+2] << 40 | | |
47 | (uint64_t)buf[start+3] << 32 | | |
48 | (uint64_t)buf[start+4] << 24 | | |
49 | (uint64_t)buf[start+5] << 16 | | |
50 | (uint64_t)buf[start+6] << 8 | | |
51 | (uint64_t)buf[start+7]; | |
52 | } | |
53 | ||
54 | static inline unsigned safe_len(uint8_t *start, unsigned len, uint8_t *subbuf, unsigned subbuf_len) | |
55 | { | |
56 | const int start_offset = subbuf - start; | |
57 | ||
58 | if (start_offset < 0 || (unsigned)start_offset > len) | |
59 | return 0; | |
60 | ||
61 | if (subbuf_len + start_offset > len) | |
62 | return len - start_offset; | |
63 | else | |
64 | return subbuf_len; | |
65 | } | |
66 | ||
67 | #endif |
0 | add_library(scsicmd STATIC ata.c ata_smart.c cdb.c parse_inquiry.c parse_read_cap.c parse_sense.c str_map.c smartdb/smartdb.c smartdb/smartdb_gen.c) | |
0 | add_library(scsicmd STATIC ata.c ata_smart.c cdb.c parse_inquiry.c parse_read_cap.c parse_sense.c log_sense.c parse.c str_map.c smartdb/smartdb.c smartdb/smartdb_gen.c) |
17 | 17 | #include <assert.h> |
18 | 18 | #include <memory.h> |
19 | 19 | |
20 | /* | |
21 | bool ata_inq_checksum(unsigned char *buf, int buf_len) | |
20 | ||
21 | bool ata_inquiry_checksum_verify(const unsigned char *buf, int buf_len) | |
22 | 22 | { |
23 | char sum; | |
24 | int idx; | |
23 | if (buf_len != 512) | |
24 | return false; | |
25 | 25 | |
26 | 26 | if (buf[511] != 0xA5) { |
27 | 27 | // Checksum isn't claimed to be valid, nothing to check here |
28 | return 1; | |
28 | return true; | |
29 | 29 | } |
30 | 30 | |
31 | for (idx = 0, sum = 0; idx < buf_len; idx++) { | |
32 | sum += buf[idx]; | |
33 | } | |
34 | ||
35 | return sum == 0; | |
31 | return ata_checksum_verify(buf); | |
36 | 32 | } |
37 | */ | |
38 | 33 | |
39 | 34 | bool ata_status_from_scsi_sense(unsigned char *sense, int sense_len, ata_status_t *status) |
40 | 35 | { |
75 | 70 | |
76 | 71 | uint16_t ata_get_ata_smart_read_data_version(const unsigned char *buf) |
77 | 72 | { |
78 | return ata_get_word((const char *)buf, 0); | |
73 | return ata_get_word(buf, 0); | |
79 | 74 | } |
80 | 75 | |
81 | 76 | int ata_parse_ata_smart_read_data(const unsigned char *buf, ata_smart_attr_t *attrs, int max_attrs) |
83 | 78 | if (!ata_check_ata_smart_read_data_checksum(buf)) |
84 | 79 | return -1; |
85 | 80 | |
81 | /* // Some disks do not return this expected value (Ticket #55) | |
86 | 82 | if (ata_get_ata_smart_read_data_version(buf) != 0x0010) |
87 | 83 | return -1; |
84 | */ | |
88 | 85 | |
89 | 86 | int i, j; |
90 | 87 | |
116 | 113 | if (!ata_check_ata_smart_read_data_checksum(buf)) |
117 | 114 | return -1; |
118 | 115 | |
116 | /* // Some disks do not return this expected value (Ticket #55) | |
119 | 117 | if (ata_get_ata_smart_read_data_version(buf) != 0x0010) |
120 | 118 | return -1; |
119 | */ | |
121 | 120 | |
122 | 121 | int i, j; |
123 | 122 |
139 | 139 | set_uint16(cdb, 7, alloc_len); |
140 | 140 | return LEN; |
141 | 141 | } |
142 | ||
143 | int cdb_receive_diagnostics(unsigned char *cdb, bool page_code_valid, uint8_t page_code, uint16_t alloc_len) | |
144 | { | |
145 | const int LEN = 6; | |
146 | cdb[0] = 0x1C; | |
147 | cdb[1] = page_code_valid ? 1 : 0; | |
148 | cdb[2] = page_code; | |
149 | set_uint16(cdb, 3, alloc_len); | |
150 | cdb[5] = 0; | |
151 | return LEN; | |
152 | } | |
153 | ||
154 | int cdb_send_diagnostics(unsigned char *cdb, self_test_code_e self_test, uint16_t param_len) | |
155 | { | |
156 | const int LEN = 6; | |
157 | cdb[0] = 0x1D; | |
158 | cdb[1] = self_test << 5; | |
159 | cdb[2] = 0; | |
160 | set_uint16(cdb, 3, param_len); | |
161 | cdb[5] = 0; | |
162 | return LEN; | |
163 | } | |
164 | ||
165 | int cdb_mode_sense_6(unsigned char *cdb, bool disable_block_descriptor, page_control_e page_control, uint8_t page_code, uint8_t subpage_code, uint8_t alloc_len) | |
166 | { | |
167 | const int LEN = 6; | |
168 | cdb[0] = 0x1A; | |
169 | cdb[1] = disable_block_descriptor ? (1<<3) : 0; | |
170 | cdb[2] = (page_control << 6) | page_code; | |
171 | cdb[3] = subpage_code; | |
172 | cdb[4] = alloc_len; | |
173 | cdb[5] = 0; | |
174 | return LEN; | |
175 | } | |
176 | ||
177 | int cdb_mode_sense_10(unsigned char *cdb, bool long_lba_accepted, bool disable_block_descriptor, page_control_e page_control, uint8_t page_code, uint8_t subpage_code, uint16_t alloc_len) | |
178 | { | |
179 | const int LEN = 10; | |
180 | cdb[0] = 0x5A; | |
181 | cdb[1] = (long_lba_accepted ? 1<<4 : 0) | (disable_block_descriptor ? 1<<3 : 0); | |
182 | cdb[2] = (page_control << 6) | page_code; | |
183 | cdb[3] = subpage_code; | |
184 | cdb[4] = 0; | |
185 | cdb[5] = 0; | |
186 | cdb[6] = 0; | |
187 | set_uint16(cdb, 7, alloc_len); | |
188 | cdb[9] = 0; | |
189 | return LEN; | |
190 | } | |
191 | ||
192 | int cdb_read_defect_data_10(unsigned char *cdb, bool plist, bool glist, address_desc_format_e format, uint16_t alloc_len) | |
193 | { | |
194 | const int LEN = 10; | |
195 | cdb[0] = 0x37; | |
196 | cdb[1] = 0; | |
197 | cdb[2] = (plist ? 0x10 : 0) | (glist ? 0x08 : 0) | format; | |
198 | cdb[3] = cdb[4] = cdb[5] = cdb[6] = 0; | |
199 | set_uint16(cdb, 7, alloc_len); | |
200 | cdb[9] = 0; | |
201 | return LEN; | |
202 | } | |
203 | ||
204 | int cdb_read_defect_data_12(unsigned char *cdb, bool plist, bool glist, address_desc_format_e format, uint32_t alloc_len) | |
205 | { | |
206 | const int LEN = 12; | |
207 | cdb[0] = 0xB7; | |
208 | cdb[1] = (plist ? 0x10 : 0) | (glist ? 0x08 : 0) | format; | |
209 | cdb[2] = cdb[3] = cdb[4] = cdb[5] = 0; | |
210 | set_uint32(cdb, 6, alloc_len); | |
211 | cdb[10] = 0; | |
212 | cdb[11] = 0; | |
213 | return LEN; | |
214 | } |
0 | #include "parse_log_sense.h" | |
1 | ||
2 | bool log_sense_page_informational_exceptions(uint8_t *page, unsigned page_len, uint8_t *asc, uint8_t *ascq, uint8_t *temperature) | |
3 | { | |
4 | if (!log_sense_is_valid(page, page_len)) | |
5 | return false; | |
6 | if (log_sense_page_code(page) != 0x2F) | |
7 | return false; | |
8 | if (log_sense_subpage_format(page) && log_sense_subpage_code(page) != 0) | |
9 | return false; | |
10 | ||
11 | uint8_t *param; | |
12 | for_all_log_sense_params(page, page_len, param) { | |
13 | if (log_sense_param_code(param) == 0) { | |
14 | uint8_t *param_data = log_sense_param_data(param); | |
15 | *asc = param_data[0]; | |
16 | *ascq = param_data[1]; | |
17 | *temperature = param_data[2]; | |
18 | return true; | |
19 | } | |
20 | } | |
21 | ||
22 | return false; | |
23 | } | |
24 | ||
25 |
0 | #include "parse_read_defect_data.h" | |
1 | ||
2 | static const char *defect_data_format_str[] = { | |
3 | "Short", | |
4 | "Reserved (1)", | |
5 | "Reserved (2)", | |
6 | "Long", | |
7 | "Index", | |
8 | "Physical", | |
9 | "Vendor", | |
10 | "Reserved (7)", | |
11 | }; | |
12 | ||
13 | const char *read_defect_data_format_to_str(uint8_t fmt) | |
14 | { | |
15 | if (fmt > 7) | |
16 | return "Unknown"; | |
17 | return defect_data_format_str[fmt]; | |
18 | } |
31 | 31 | return false; |
32 | 32 | |
33 | 33 | unsigned char fmt = buf[3] & 0xf; |
34 | if (fmt != 2 && fmt != 1) { | |
35 | fprintf(stderr, "Data not in standard format (%d but expected 2)\n", fmt); | |
36 | return false; | |
37 | } | |
38 | 34 | |
39 | 35 | int valid_len = buf[4] + 4; |
40 | 36 |
14 | 14 | */ |
15 | 15 | |
16 | 16 | #include "scsicmd.h" |
17 | #include "scsicmd_utils.h" | |
17 | 18 | |
18 | 19 | #include <stdio.h> |
19 | 20 | #include <string.h> |
20 | ||
21 | static inline void get_uint32(unsigned char *buf, int start, uint32_t *val) | |
22 | { | |
23 | *val = (uint32_t)buf[start] << 24 | | |
24 | (uint32_t)buf[start+1] << 16 | | |
25 | (uint32_t)buf[start+2] << 8 | | |
26 | (uint32_t)buf[start+3]; | |
27 | } | |
28 | ||
29 | static inline void get_uint64(unsigned char *buf, int start, uint64_t *val) | |
30 | { | |
31 | *val = (uint64_t)buf[start] << 56 | | |
32 | (uint64_t)buf[start+1] << 48 | | |
33 | (uint64_t)buf[start+2] << 40 | | |
34 | (uint64_t)buf[start+3] << 32 | | |
35 | (uint64_t)buf[start+4] << 24 | | |
36 | (uint64_t)buf[start+5] << 16 | | |
37 | (uint64_t)buf[start+6] << 8 | | |
38 | (uint64_t)buf[start+7]; | |
39 | } | |
40 | 21 | |
41 | 22 | bool parse_read_capacity_10(unsigned char *buf, unsigned buf_len, uint32_t *max_lba, uint32_t *block_size) |
42 | 23 | { |
44 | 25 | return false; |
45 | 26 | |
46 | 27 | if (max_lba) |
47 | get_uint32(buf, 0, max_lba); | |
28 | *max_lba = get_uint32(buf, 0); | |
48 | 29 | if (block_size) |
49 | get_uint32(buf, 4, block_size); | |
30 | *block_size = get_uint32(buf, 4); | |
50 | 31 | return true; |
51 | 32 | } |
52 | 33 | |
58 | 39 | return false; |
59 | 40 | |
60 | 41 | if (max_lba) |
61 | get_uint64(buf, 0, max_lba); | |
42 | *max_lba = get_uint64(buf, 0); | |
62 | 43 | if (block_size) |
63 | get_uint32(buf, 8, block_size); | |
44 | *block_size = get_uint32(buf, 8); | |
64 | 45 | if (prot_enable) |
65 | 46 | *prot_enable = buf[12] & 1; |
66 | 47 | if (p_type) |
0 | 0 | #include "scsicmd.h" |
1 | #include "scsicmd_utils.h" | |
1 | 2 | |
2 | 3 | #include <memory.h> |
3 | ||
4 | static inline uint16_t scsi_get_16(unsigned char *buf, int idx) | |
5 | { | |
6 | return (buf[idx+0] << 8) | | |
7 | (buf[idx+1]); | |
8 | } | |
9 | ||
10 | static inline uint32_t scsi_get_24(unsigned char *buf, int idx) | |
11 | { | |
12 | return (buf[idx+0] << 16) | | |
13 | (buf[idx+1] << 8) | | |
14 | (buf[idx+2]); | |
15 | } | |
16 | ||
17 | static inline uint32_t scsi_get_32(unsigned char *buf, int idx) | |
18 | { | |
19 | return (buf[idx+0] << 24) | | |
20 | (buf[idx+1] << 16) | | |
21 | (buf[idx+2] << 8) | | |
22 | (buf[idx+3]); | |
23 | } | |
24 | ||
25 | static inline uint64_t scsi_get_64(unsigned char *buf, int idx) | |
26 | { | |
27 | return ((uint64_t)buf[idx+0] << 56) | | |
28 | ((uint64_t)buf[idx+1] << 48) | | |
29 | ((uint64_t)buf[idx+2] << 40) | | |
30 | ((uint64_t)buf[idx+3] << 32) | | |
31 | ((uint64_t)buf[idx+4] << 24) | | |
32 | ((uint64_t)buf[idx+5] << 16) | | |
33 | ((uint64_t)buf[idx+6] << 8) | | |
34 | ((uint64_t)buf[idx+7]); | |
35 | } | |
36 | 4 | |
37 | 5 | static void parse_sense_key_specific(unsigned char *sks, sense_info_t *info) |
38 | 6 | { |
39 | 7 | info->sense_key_specific_valid = sks[0] & 0x80; |
40 | 8 | if (info->sense_key_specific_valid) |
41 | 9 | { |
42 | uint32_t sense_key_specific = scsi_get_24(sks, 0) & 0x007FFFFF; | |
10 | uint32_t sense_key_specific = get_uint24(sks, 0) & 0x007FFFFF; | |
43 | 11 | switch (info->sense_key) { |
44 | 12 | case SENSE_KEY_ILLEGAL_REQUEST: |
45 | 13 | info->sense_key_specific.illegal_request.command_error = sense_key_specific & 0x400000; |
46 | 14 | info->sense_key_specific.illegal_request.bit_pointer_valid = sense_key_specific & 0x080000; |
47 | 15 | info->sense_key_specific.illegal_request.bit_pointer = (sense_key_specific & 0x070000) >> 16; |
48 | info->sense_key_specific.illegal_request.command_error = sense_key_specific & 0xFFFF; | |
16 | info->sense_key_specific.illegal_request.field_pointer = sense_key_specific & 0xFFFF; | |
49 | 17 | break; |
50 | 18 | case SENSE_KEY_HARDWARE_ERROR: |
51 | 19 | case SENSE_KEY_MEDIUM_ERROR: |
79 | 47 | |
80 | 48 | info->information_valid = sense[0] & 0x80; |
81 | 49 | if (info->information_valid) |
82 | info->information = scsi_get_32(sense, 3); | |
50 | info->information = get_uint32(sense, 3); | |
83 | 51 | |
84 | 52 | info->incorrect_len_indicator = sense[2] & 0x20; |
85 | 53 | info->sense_key = sense[2] & 0xF; |
87 | 55 | info->ascq = sense[13]; |
88 | 56 | |
89 | 57 | info->cmd_specific_valid = true; |
90 | info->cmd_specific = scsi_get_32(sense, 8); | |
58 | info->cmd_specific = get_uint32(sense, 8); | |
91 | 59 | |
92 | 60 | info->fru_code_valid = true; |
93 | 61 | info->fru_code = sense[14]; |
95 | 63 | parse_sense_key_specific(sense + 15, info); |
96 | 64 | |
97 | 65 | if (sense_len >= 21) |
98 | info->vendor_unique_error = scsi_get_16(sense, 20); | |
66 | info->vendor_unique_error = get_uint16(sense, 20); | |
99 | 67 | |
100 | 68 | //uint8_t additional_sense_len = sense[7]; |
101 | 69 | |
102 | 70 | return true; |
103 | 71 | } |
104 | 72 | |
105 | static bool parse_sense_descriptor(unsigned char *sense, int sense_len, sense_info_t *info) | |
73 | static bool parse_sense_descriptor(unsigned char *sense, unsigned sense_len, sense_info_t *info) | |
106 | 74 | { |
107 | 75 | if (sense_len < 8) |
108 | 76 | return false; |
111 | 79 | info->asc = sense[2]; |
112 | 80 | info->ascq = sense[3]; |
113 | 81 | |
114 | uint8_t additional_sense_length = sense[7]; | |
82 | unsigned additional_sense_length = sense[7]; | |
115 | 83 | if (sense_len > additional_sense_length + 8) |
116 | 84 | sense_len = additional_sense_length + 8; |
117 | 85 | |
118 | uint8_t idx; | |
119 | uint8_t desc_len; | |
86 | unsigned idx; | |
87 | unsigned desc_len; | |
120 | 88 | |
121 | 89 | for (idx = 8; idx < sense_len; idx += desc_len+2) { |
122 | 90 | uint8_t desc_type = sense[idx]; |
129 | 97 | case 0x00: // Information |
130 | 98 | if (desc_len == 0x0A) { |
131 | 99 | info->information_valid = sense[idx+2] & 0x80; |
132 | info->information = scsi_get_64(sense, idx+4); | |
100 | info->information = get_uint64(sense, idx+4); | |
133 | 101 | } |
134 | 102 | break; |
135 | 103 | case 0x01: // Command specific information |
136 | 104 | if (desc_len == 0x0A) { |
137 | 105 | info->cmd_specific_valid = true; |
138 | info->cmd_specific = scsi_get_64(sense, idx+4); | |
106 | info->cmd_specific = get_uint64(sense, idx+4); | |
139 | 107 | } |
140 | 108 | break; |
141 | 109 | case 0x02: // Sense key specific |
190 | 158 | break; |
191 | 159 | case 0x80: // Vendor Unique Unit Error |
192 | 160 | if (desc_len == 0x02) { |
193 | info->vendor_unique_error = scsi_get_16(sense, idx+2); | |
161 | info->vendor_unique_error = get_uint16(sense, idx+2); | |
194 | 162 | } |
195 | 163 | break; |
196 | 164 | } |
73 | 73 | non_volatile_cache: |
74 | 74 | bit: [69, 2] |
75 | 75 | |
76 | # queue_depth: | |
77 | # bits: [75, 0, 4] | |
76 | queue_depth: | |
77 | bits: [75, 0, 4] | |
78 | ||
79 | supports_read_log_dma_ext_as_read_log_dma: | |
80 | bit: [76, 15] | |
81 | supports_dev_automatic_partial_to_slumber: | |
82 | bit: [76, 14] | |
83 | supports_host_automatic_partial_to_slumber: | |
84 | bit: [76, 13] | |
85 | supports_ncq_priority: | |
86 | bit: [76, 12] | |
87 | supports_unload_while_ncq_outstanding: | |
88 | bit: [76, 11] | |
89 | supports_sata_phy_event_counters_log: | |
90 | bit: [76, 10] | |
91 | supports_receipt_of_host_initiated_power_management_requests: | |
92 | bit: [76, 9] | |
93 | supports_ncq: | |
94 | bit: [76, 8] | |
95 | supports_sata_gen3_6gbps: | |
96 | bit: [76, 3] | |
97 | supports_sata_gen2_3gbps: | |
98 | bit: [76, 2] | |
99 | supports_sata_gen1_1_5gbps: | |
100 | bit: [76, 1] | |
101 | ||
102 | supports_receive_fpdma_queued: | |
103 | bit: [77, 6] | |
104 | supports_ncq_queue_management_commands: | |
105 | bit: [77, 5] | |
106 | supports_ncq_streaming: | |
107 | bit: [77, 4] | |
108 | current_negotiated_link_speed: | |
109 | bits: [77, 1, 3] | |
78 | 110 | |
79 | 111 | sata_automatic_partial_to_slumber_transitions_enabled: |
80 | 112 | bit: [79, 7] |
126 | 158 | |
127 | 159 | address_48bit_supported: |
128 | 160 | bit: [83, 10] |
129 | ||
161 | spin_up_supported: | |
162 | bit: [83, 6] | |
163 | puis_supported: | |
164 | bit: [83, 5] | |
165 | apm_supported: | |
166 | bit: [83, 3] | |
167 | cfa_supported: | |
168 | bit: [83, 2] | |
169 | download_microcode_supported: | |
170 | bit: [83, 0] | |
171 | ||
172 | wwn_64bit_supported: | |
173 | bit: [84, 8] | |
174 | gpl_supported: | |
175 | bit: [84, 5] | |
176 | streaming_supported: | |
177 | bit: [84, 4] | |
130 | 178 | smart_self_test_supported: |
131 | 179 | bit: [84, 1] |
132 | ||
133 | 180 | smart_error_logging_supported: |
134 | 181 | bit: [84, 0] |
135 | 182 | |
160 | 207 | sct_command_transport_supported: |
161 | 208 | bit: [206, 0] |
162 | 209 | |
210 | rotational_rate: | |
211 | bits: [216, 0, 15] | |
212 | ||
213 | wwn_high: | |
214 | longword: 108 | |
215 | wwn_low: | |
216 | longword: 110 | |
217 | ||
218 | additional_product_identifier: | |
219 | string: [170, 173] | |
220 | current_media_serial: | |
221 | string: [176, 205] | |
222 | ||
223 | extended_num_user_addressable_sectors: | |
224 | qword: 230 | |
225 | ||
163 | 226 | # vim:set et ts=4 sw=4: |
14 | 14 | print('printf("%%-40s: %%s\\n", "%(field)s", outbuf);' % bit_params) |
15 | 15 | print('}') |
16 | 16 | |
17 | def emit_func_bits(name, field, params): | |
18 | bit_params = dict(name=name, field=field, word_start=int(params[0])) | |
19 | print('printf("%%-40s: %%u\\n", "%(field)s", ata_get_%(name)s_%(field)s(buf));' % bit_params) | |
20 | ||
17 | 21 | def emit_func_longword(name, field, params): |
18 | 22 | bit_params = dict(name=name, field=field, word_start=int(params)) |
19 | 23 | print('printf("%%-40s: %%u\\n", "%(field)s", ata_get_%(name)s_%(field)s(buf));' % bit_params) |
20 | 24 | |
25 | def emit_func_qword(name, field, params): | |
26 | bit_params = dict(name=name, field=field, word_start=int(params)) | |
27 | print('printf("%%-40s: %%"PRIu64"\\n", "%(field)s", ata_get_%(name)s_%(field)s(buf));' % bit_params) | |
28 | ||
21 | 29 | kinds = { |
22 | 'bit': emit_func_bit, | |
30 | 'bit': emit_func_bit, | |
31 | 'bits': emit_func_bits, | |
23 | 32 | 'string': emit_func_string, |
24 | 33 | 'longword': emit_func_longword, |
34 | 'qword': emit_func_qword, | |
25 | 35 | } |
26 | 36 | |
27 | 37 | def emit_header_single(name, struct): |
39 | 49 | |
40 | 50 | def emit_header(structs): |
41 | 51 | for name, struct in list(structs.items()): |
42 | print('void dump_%s(const char *buf)' % name) | |
52 | print('void dump_%s(const unsigned char *buf)' % name) | |
43 | 53 | print('{') |
44 | 54 | emit_header_single(name, struct) |
45 | 55 | print('}') |
49 | 59 | print('#include "ata_parse.h"') |
50 | 60 | print('#include "ata_identify_dump.h"') |
51 | 61 | print('#include <stdio.h>') |
62 | print('#include <inttypes.h>') | |
52 | 63 | |
53 | 64 | def emit_suffix(): |
54 | 65 | print('') |
4 | 4 | |
5 | 5 | def emit_func_bit(name, field, params): |
6 | 6 | bit_params = dict(name=name, field=field, word=int(params[0]), bit=int(params[1])) |
7 | print("""static inline bool ata_get_%(name)s_%(field)s(const char *buf) { | |
7 | print("""static inline bool ata_get_%(name)s_%(field)s(const unsigned char *buf) { | |
8 | 8 | ata_word_t val = ata_get_word(buf, %(word)d); |
9 | 9 | return val & (1 << %(bit)d); |
10 | 10 | } |
11 | 11 | """ % bit_params) |
12 | 12 | |
13 | def emit_func_bits(name, field, params): | |
14 | bit_params = dict(name=name, field=field, word=int(params[0]), start_bit=int(params[1]), end_bit=int(params[2])) | |
15 | print("""static inline unsigned ata_get_%(name)s_%(field)s(const unsigned char *buf) { | |
16 | ata_word_t val = ata_get_word(buf, %(word)d); | |
17 | return (val >> %(start_bit)d) & ((1<<(%(end_bit)d - %(start_bit)d + 1)) - 1); | |
18 | } | |
19 | """ % bit_params) | |
20 | ||
13 | 21 | def emit_func_string(name, field, params): |
14 | 22 | bit_params = dict(name=name, field=field, word_start=int(params[0]), word_end=int(params[1])) |
15 | print("""static inline void ata_get_%(name)s_%(field)s(const char *buf, char *out) { | |
23 | print("""static inline void ata_get_%(name)s_%(field)s(const unsigned char *buf, char *out) { | |
16 | 24 | ata_get_string(buf, %(word_start)d, %(word_end)d, out); |
17 | 25 | } |
18 | 26 | """ % bit_params) |
19 | 27 | |
20 | 28 | def emit_func_longword(name, field, params): |
21 | 29 | bit_params = dict(name=name, field=field, word_start=int(params)) |
22 | print("""static inline ata_longword_t ata_get_%(name)s_%(field)s(const char *buf) { | |
30 | print("""static inline ata_longword_t ata_get_%(name)s_%(field)s(const unsigned char *buf) { | |
23 | 31 | return ata_get_longword(buf, %(word_start)d); |
32 | } | |
33 | """ % bit_params) | |
34 | ||
35 | def emit_func_qword(name, field, params): | |
36 | bit_params = dict(name=name, field=field, word_start=int(params)) | |
37 | print("""static inline ata_qword_t ata_get_%(name)s_%(field)s(const unsigned char *buf) { | |
38 | return ata_get_qword(buf, %(word_start)d); | |
24 | 39 | } |
25 | 40 | """ % bit_params) |
26 | 41 | |
27 | 42 | kinds = { |
28 | 43 | 'bit': emit_func_bit, |
44 | 'bits': emit_func_bits, | |
29 | 45 | 'string': emit_func_string, |
30 | 46 | 'longword': emit_func_longword, |
47 | 'qword': emit_func_qword, | |
31 | 48 | } |
32 | 49 | |
33 | 50 | def emit_header_single(name, struct): |
4 | 4 | |
5 | 5 | def emit_header(structs): |
6 | 6 | for name, struct in list(structs.items()): |
7 | print('void dump_%s(const char *buf);' % name) | |
7 | print('void dump_%s(const unsigned char *buf);' % name) | |
8 | 8 | |
9 | 9 | def emit_prefix(): |
10 | 10 | print('#ifndef _DUMP_H_') |
23 | 23 | add_executable(scsi_log_sense scsi_log_sense.c) |
24 | 24 | target_link_libraries(scsi_log_sense testlib scsicmd) |
25 | 25 | |
26 | add_executable(parse_scsi parse_scsi.c) | |
27 | target_link_libraries(parse_scsi testlib scsicmd) | |
28 | ||
29 | add_executable(scsi_mode_sense scsi_mode_sense.c) | |
30 | target_link_libraries(scsi_mode_sense testlib scsicmd) | |
31 | ||
32 | add_executable(scsi_receive_diagnostics scsi_receive_diagnostics.c) | |
33 | target_link_libraries(scsi_receive_diagnostics testlib scsicmd) | |
34 | ||
26 | 35 | add_executable(scsi_read_capacity_10 scsi_read_capacity_10.c) |
27 | 36 | target_link_libraries(scsi_read_capacity_10 testlib scsicmd) |
28 | 37 | |
31 | 40 | |
32 | 41 | add_executable(sense_decode sense_decode.c) |
33 | 42 | target_link_libraries(sense_decode testlib scsicmd) |
43 | ||
44 | add_executable(collect_raw_data collect_raw_data.c) | |
45 | target_link_libraries(collect_raw_data testlib scsicmd) |
53 | 53 | } |
54 | 54 | |
55 | 55 | if (!sense) |
56 | dump_ata_identify((char *)buf); | |
56 | dump_ata_identify(buf); | |
57 | 57 | else |
58 | 58 | printf("error while reading ATA IDENTIFY, nothing to show\n"); |
59 | 59 | } |
16 | 16 | #include "ata.h" |
17 | 17 | #include "ata_parse.h" |
18 | 18 | #include "ata_smart.h" |
19 | #include "sense_dump.h" | |
19 | 20 | #include "main.h" |
20 | 21 | #include "smartdb.h" |
21 | 22 | #include <stdio.h> |
46 | 47 | response_dump(buf, sizeof(buf)); |
47 | 48 | |
48 | 49 | printf("Page checksum read: %02X\n", ata_get_ata_smart_read_data_checksum(buf)); |
49 | printf("Page checksum calc: %02X\n", ata_calc_ata_smart_read_data_checksum(buf)); | |
50 | printf("Page checksum calc: %02X\n", ata_calc_checksum(buf)); | |
50 | 51 | printf("Page checksum matches: %s\n", ata_check_ata_smart_read_data_checksum(buf) ? "true" : "false"); |
51 | 52 | printf("Page version: %04Xh\n", ata_get_ata_smart_read_data_version(buf)); |
52 | 53 | if (ata_get_ata_smart_read_data_version(buf) != 0x10) { |
81 | 82 | response_dump(buf, sizeof(buf)); |
82 | 83 | |
83 | 84 | printf("Page checksum read: %02X\n", ata_get_ata_smart_read_data_checksum(buf)); |
84 | printf("Page checksum calc: %02X\n", ata_calc_ata_smart_read_data_checksum(buf)); | |
85 | printf("Page checksum calc: %02X\n", ata_calc_checksum(buf)); | |
85 | 86 | printf("Page checksum matches: %s\n", ata_check_ata_smart_read_data_checksum(buf) ? "true" : "false"); |
86 | 87 | printf("Page version: %04Xh\n", ata_get_ata_smart_read_data_version(buf)); |
87 | 88 | if (ata_get_ata_smart_read_data_version(buf) != 0x10) { |
0 | /* Copyright 2013 Baruch Even | |
1 | * | |
2 | * Licensed under the Apache License, Version 2.0 (the "License"); | |
3 | * you may not use this file except in compliance with the License. | |
4 | * You may obtain a copy of the License at | |
5 | * | |
6 | * http://www.apache.org/licenses/LICENSE-2.0 | |
7 | * | |
8 | * Unless required by applicable law or agreed to in writing, software | |
9 | * distributed under the License is distributed on an "AS IS" BASIS, | |
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
11 | * See the License for the specific language governing permissions and | |
12 | * limitations under the License. | |
13 | * | |
14 | */ | |
15 | ||
16 | #include "scsicmd.h" | |
17 | #include "ata.h" | |
18 | ||
19 | #include "main.h" | |
20 | #include "sense_dump.h" | |
21 | #include "scsicmd_utils.h" | |
22 | #include "parse_extended_inquiry.h" | |
23 | #include "parse_receive_diagnostics.h" | |
24 | #include "parse_log_sense.h" | |
25 | #include <stdio.h> | |
26 | #include <memory.h> | |
27 | #include <errno.h> | |
28 | #include <unistd.h> | |
29 | #include <sys/types.h> | |
30 | #include <sys/stat.h> | |
31 | #include <fcntl.h> | |
32 | #include <scsi/sg.h> | |
33 | #include <inttypes.h> | |
34 | #include <ctype.h> | |
35 | ||
36 | static bool is_ata; | |
37 | ||
38 | static void hex_dump(uint8_t *data, uint16_t len) | |
39 | { | |
40 | uint16_t i; | |
41 | ||
42 | if (data == NULL || len == 0) | |
43 | return; | |
44 | ||
45 | printf("%02x", data[0]); | |
46 | for (i = 1; i < len; i++) { | |
47 | printf(" %02x", data[i]); | |
48 | } | |
49 | } | |
50 | ||
51 | static void emit_data_csv(uint8_t *cdb, uint8_t cdb_len, uint8_t *sense, uint8_t sense_len, uint8_t *buf, uint16_t buf_len) | |
52 | { | |
53 | putchar(','); | |
54 | hex_dump(cdb, cdb_len); | |
55 | putchar(','); | |
56 | hex_dump(sense, sense_len); | |
57 | putchar(','); | |
58 | hex_dump(buf, buf_len); | |
59 | putchar('\n'); | |
60 | } | |
61 | ||
62 | static int simple_command(int fd, uint8_t *cdb, unsigned cdb_len, uint8_t *buf, unsigned buf_len) | |
63 | { | |
64 | memset(buf, 0, buf_len); | |
65 | ||
66 | bool ret = submit_cmd(fd, cdb, cdb_len, buf, buf_len, buf_len ? SG_DXFER_FROM_DEV : SG_DXFER_NONE); | |
67 | if (!ret) { | |
68 | printf("Failed to submit command,\n"); | |
69 | return -1; | |
70 | } | |
71 | ||
72 | unsigned char *sense = NULL; | |
73 | unsigned sense_len = 0; | |
74 | ret = read_response_buf(fd, &sense, &sense_len, &buf_len); | |
75 | ||
76 | emit_data_csv(cdb, cdb_len, sense, sense_len, buf, buf_len); | |
77 | ||
78 | if (sense_len > 0) { | |
79 | sense_info_t sense_info; | |
80 | bool sense_parsed = scsi_parse_sense(sense, sense_len, &sense_info); | |
81 | if (sense_parsed && sense_info.sense_key == SENSE_KEY_RECOVERED_ERROR) | |
82 | return buf_len; | |
83 | return -1; | |
84 | } | |
85 | return buf_len; | |
86 | } | |
87 | ||
88 | static void do_simple_inquiry(int fd) | |
89 | { | |
90 | unsigned char cdb[32]; | |
91 | unsigned char buf[128]; | |
92 | unsigned cdb_len = cdb_inquiry_simple(cdb, 96); | |
93 | int buf_len; | |
94 | ||
95 | buf_len = simple_command(fd, cdb, cdb_len, buf, sizeof(buf)); | |
96 | ||
97 | int device_type; | |
98 | scsi_vendor_t vendor; | |
99 | scsi_model_t model; | |
100 | scsi_fw_revision_t rev; | |
101 | scsi_serial_t serial; | |
102 | if (parse_inquiry(buf, buf_len, &device_type, vendor, model, rev, serial) && | |
103 | strncmp(vendor, "ATA", 3) == 0) | |
104 | { | |
105 | is_ata = true; | |
106 | } | |
107 | } | |
108 | ||
109 | static void dump_evpd(int fd, uint8_t evpd_page) | |
110 | { | |
111 | unsigned char cdb[32]; | |
112 | unsigned char buf[512]; | |
113 | unsigned cdb_len = cdb_inquiry(cdb, true, evpd_page, sizeof(buf)); | |
114 | ||
115 | simple_command(fd, cdb, cdb_len, buf, sizeof(buf)); | |
116 | } | |
117 | ||
118 | static void do_extended_inquiry(int fd) | |
119 | { | |
120 | unsigned char cdb[32]; | |
121 | unsigned char buf[512]; | |
122 | unsigned cdb_len = cdb_inquiry(cdb, true, 0, sizeof(buf)); | |
123 | int buf_len; | |
124 | ||
125 | buf_len = simple_command(fd, cdb, cdb_len, buf, sizeof(buf)); | |
126 | ||
127 | if (buf_len > 0 && evpd_is_valid(buf, buf_len)) { | |
128 | uint16_t max_page_idx = evpd_page_len(buf) + 4; | |
129 | uint16_t i; | |
130 | for (i = 4; i < max_page_idx; i++) | |
131 | dump_evpd(fd, buf[i]); | |
132 | } | |
133 | } | |
134 | ||
135 | static void dump_log_sense(int fd, uint8_t page, uint8_t subpage) | |
136 | { | |
137 | unsigned char cdb[32]; | |
138 | unsigned char buf[16*1024]; | |
139 | unsigned cdb_len = cdb_log_sense(cdb, page, subpage, sizeof(buf)); | |
140 | ||
141 | simple_command(fd, cdb, cdb_len, buf, sizeof(buf)); | |
142 | } | |
143 | ||
144 | static void do_log_sense(int fd) | |
145 | { | |
146 | unsigned char cdb[32]; | |
147 | unsigned char buf[16*1024]; | |
148 | unsigned cdb_len = cdb_log_sense(cdb, 0, 0, sizeof(buf)); | |
149 | int buf_len; | |
150 | ||
151 | buf_len = simple_command(fd, cdb, cdb_len, buf, sizeof(buf)); | |
152 | ||
153 | if (buf_len < 0) { | |
154 | printf("error while reading log sense list, nothing to show\n"); | |
155 | return; | |
156 | } | |
157 | ||
158 | if (!log_sense_is_valid(buf, buf_len)) { | |
159 | printf("log sense page is invalid\n"); | |
160 | return; | |
161 | } | |
162 | ||
163 | if (buf[0] != 0 || buf[1] != 0) { | |
164 | printf("expected to receive log page 0 subpage 0\n"); | |
165 | return; | |
166 | } | |
167 | ||
168 | uint16_t num_pages = get_uint16(buf, 2); | |
169 | uint16_t i; | |
170 | for (i = 0; i < num_pages; i++) { | |
171 | dump_log_sense(fd, buf[4 + i], 0); | |
172 | } | |
173 | ||
174 | cdb_len = cdb_log_sense(cdb, 0, 0xff, sizeof(buf)); | |
175 | buf_len = simple_command(fd, cdb, cdb_len, buf, sizeof(buf)); | |
176 | ||
177 | if (buf_len < 0) { | |
178 | printf("error while reading list of log subpages, nothing to show\n"); | |
179 | return; | |
180 | } | |
181 | ||
182 | if (!log_sense_is_valid(buf, buf_len)) { | |
183 | printf("log sense list must have at least 4 bytes\n"); | |
184 | return; | |
185 | } | |
186 | ||
187 | if (buf[0] != 0x40 || buf[1] != 0xFF) { | |
188 | printf("expected to receive log page 0 (spf=1) subpage 0xFF\n"); | |
189 | return; | |
190 | } | |
191 | ||
192 | num_pages = get_uint16(buf, 2); | |
193 | for (i = 0; i < num_pages; i++) { | |
194 | uint8_t page = buf[4 + i*2] & 0x3F; | |
195 | uint8_t subpage = buf[4 + i*2 + 1]; | |
196 | if (subpage == 0) { | |
197 | printf("Skipping page %02X subpage %02X since subpage is 00 it was already retrieved above\n", page, subpage); | |
198 | continue; | |
199 | } | |
200 | dump_log_sense(fd, page, subpage); | |
201 | } | |
202 | } | |
203 | ||
204 | static void do_mode_sense_10_type(int fd, bool long_lba, bool disable_block_desc, page_control_e page_control) | |
205 | { | |
206 | unsigned char cdb[32]; | |
207 | unsigned char buf[4096]; | |
208 | unsigned cdb_len = cdb_mode_sense_10(cdb, long_lba, disable_block_desc, page_control, 0x3F, 0xFF, sizeof(buf)); | |
209 | ||
210 | simple_command(fd, cdb, cdb_len, buf, sizeof(buf)); | |
211 | } | |
212 | ||
213 | static void do_mode_sense_10(int fd) | |
214 | { | |
215 | do_mode_sense_10_type(fd, true, true, PAGE_CONTROL_CURRENT); | |
216 | do_mode_sense_10_type(fd, true, true, PAGE_CONTROL_CHANGEABLE); | |
217 | do_mode_sense_10_type(fd, true, true, PAGE_CONTROL_DEFAULT); | |
218 | do_mode_sense_10_type(fd, true, true, PAGE_CONTROL_SAVED); | |
219 | ||
220 | do_mode_sense_10_type(fd, false, true, PAGE_CONTROL_CURRENT); | |
221 | do_mode_sense_10_type(fd, false, true, PAGE_CONTROL_CHANGEABLE); | |
222 | do_mode_sense_10_type(fd, false, true, PAGE_CONTROL_DEFAULT); | |
223 | do_mode_sense_10_type(fd, false, true, PAGE_CONTROL_SAVED); | |
224 | ||
225 | do_mode_sense_10_type(fd, false, false, PAGE_CONTROL_CURRENT); | |
226 | do_mode_sense_10_type(fd, false, false, PAGE_CONTROL_CHANGEABLE); | |
227 | do_mode_sense_10_type(fd, false, false, PAGE_CONTROL_DEFAULT); | |
228 | do_mode_sense_10_type(fd, false, false, PAGE_CONTROL_SAVED); | |
229 | ||
230 | do_mode_sense_10_type(fd, true, false, PAGE_CONTROL_CURRENT); | |
231 | do_mode_sense_10_type(fd, true, false, PAGE_CONTROL_CHANGEABLE); | |
232 | do_mode_sense_10_type(fd, true, false, PAGE_CONTROL_DEFAULT); | |
233 | do_mode_sense_10_type(fd, true, false, PAGE_CONTROL_SAVED); | |
234 | } | |
235 | ||
236 | static void do_mode_sense_6_type(int fd, bool disable_block_desc, page_control_e page_control) | |
237 | { | |
238 | unsigned char cdb[32]; | |
239 | unsigned char buf[255]; | |
240 | unsigned cdb_len = cdb_mode_sense_6(cdb, disable_block_desc, page_control, 0x3F, 0xFF, sizeof(buf)); | |
241 | ||
242 | simple_command(fd, cdb, cdb_len, buf, sizeof(buf)); | |
243 | } | |
244 | ||
245 | static void do_mode_sense_6(int fd) | |
246 | { | |
247 | do_mode_sense_6_type(fd, true, PAGE_CONTROL_CURRENT); | |
248 | do_mode_sense_6_type(fd, true, PAGE_CONTROL_CHANGEABLE); | |
249 | do_mode_sense_6_type(fd, true, PAGE_CONTROL_DEFAULT); | |
250 | do_mode_sense_6_type(fd, true, PAGE_CONTROL_SAVED); | |
251 | ||
252 | do_mode_sense_6_type(fd, false, PAGE_CONTROL_CURRENT); | |
253 | do_mode_sense_6_type(fd, false, PAGE_CONTROL_CHANGEABLE); | |
254 | do_mode_sense_6_type(fd, false, PAGE_CONTROL_DEFAULT); | |
255 | do_mode_sense_6_type(fd, false, PAGE_CONTROL_SAVED); | |
256 | } | |
257 | ||
258 | static void do_mode_sense(int fd) | |
259 | { | |
260 | do_mode_sense_10(fd); | |
261 | do_mode_sense_6(fd); | |
262 | } | |
263 | ||
264 | static void dump_rcv_diag_page(int fd, uint8_t page) | |
265 | { | |
266 | unsigned char cdb[32]; | |
267 | unsigned char buf[16*1024]; | |
268 | unsigned cdb_len = cdb_receive_diagnostics(cdb, true, page, sizeof(buf)); | |
269 | ||
270 | simple_command(fd, cdb, cdb_len, buf, sizeof(buf)); | |
271 | } | |
272 | ||
273 | static void do_receive_diagnostic(int fd) | |
274 | { | |
275 | unsigned char cdb[32]; | |
276 | unsigned char buf[16*1024]; | |
277 | unsigned cdb_len = cdb_receive_diagnostics(cdb, true, 0, sizeof(buf)); | |
278 | int buf_len; | |
279 | ||
280 | buf_len = simple_command(fd, cdb, cdb_len, buf, sizeof(buf)); | |
281 | ||
282 | if (buf_len < 0) { | |
283 | printf("error while reading response buffer, nothing to show\n"); | |
284 | return; | |
285 | } | |
286 | ||
287 | if (recv_diag_is_valid(buf, buf_len)) { | |
288 | printf("receive diagnostics list must have at least 4 bytes\n"); | |
289 | return; | |
290 | } | |
291 | ||
292 | if (recv_diag_get_page_code(buf) != 0) { | |
293 | printf("expected to receive receive diagnostics page 0\n"); | |
294 | return; | |
295 | } | |
296 | ||
297 | uint16_t num_pages = recv_diag_get_len(buf); | |
298 | uint16_t i; | |
299 | for (i = 0; i < num_pages; i++) { | |
300 | dump_rcv_diag_page(fd, buf[4 + i]); | |
301 | } | |
302 | } | |
303 | ||
304 | static void do_read_capacity_10(int fd) | |
305 | { | |
306 | unsigned char cdb[32]; | |
307 | unsigned char buf[8]; | |
308 | unsigned cdb_len = cdb_read_capacity_10(cdb); | |
309 | ||
310 | simple_command(fd, cdb, cdb_len, buf, sizeof(buf)); | |
311 | } | |
312 | ||
313 | static void do_read_capacity_16(int fd) | |
314 | { | |
315 | unsigned char cdb[32]; | |
316 | unsigned char buf[512]; | |
317 | unsigned cdb_len = cdb_read_capacity_16(cdb, sizeof(buf)); | |
318 | ||
319 | simple_command(fd, cdb, cdb_len, buf, sizeof(buf)); | |
320 | } | |
321 | ||
322 | static void do_read_capacity(int fd) | |
323 | { | |
324 | do_read_capacity_10(fd); | |
325 | do_read_capacity_16(fd); | |
326 | } | |
327 | ||
328 | static void do_read_defect_data_10(int fd, bool plist, bool glist, uint8_t format, bool count_only) | |
329 | { | |
330 | unsigned char cdb[32]; | |
331 | unsigned char buf[512]; | |
332 | unsigned cdb_len = cdb_read_defect_data_10(cdb, plist, glist, format, count_only ? 8 : sizeof(buf)); | |
333 | ||
334 | simple_command(fd, cdb, cdb_len, buf, sizeof(buf)); | |
335 | } | |
336 | ||
337 | static void do_read_defect_data_10_all(int fd, uint8_t format) | |
338 | { | |
339 | do_read_defect_data_10(fd, true, false, format, true); | |
340 | do_read_defect_data_10(fd, true, false, format, false); | |
341 | do_read_defect_data_10(fd, false, true, format, true); | |
342 | do_read_defect_data_10(fd, false, true, format, false); | |
343 | } | |
344 | ||
345 | static void do_read_defect_data_12(int fd, bool plist, bool glist, uint8_t format, bool count_only) | |
346 | { | |
347 | unsigned char cdb[32]; | |
348 | unsigned char buf[512]; | |
349 | unsigned cdb_len = cdb_read_defect_data_12(cdb, plist, glist, format, count_only ? 8 : sizeof(buf)); | |
350 | ||
351 | simple_command(fd, cdb, cdb_len, buf, sizeof(buf)); | |
352 | } | |
353 | ||
354 | static void do_read_defect_data_12_all(int fd, uint8_t format) | |
355 | { | |
356 | do_read_defect_data_12(fd, true, false, format, true); | |
357 | do_read_defect_data_12(fd, true, false, format, false); | |
358 | do_read_defect_data_12(fd, false, true, format, true); | |
359 | do_read_defect_data_12(fd, false, true, format, false); | |
360 | } | |
361 | ||
362 | static void do_read_defect_data(int fd) | |
363 | { | |
364 | uint8_t format; | |
365 | ||
366 | for (format = 0; format < 8; format++) | |
367 | do_read_defect_data_10_all(fd, format); | |
368 | ||
369 | for (format = 0; format < 8; format++) | |
370 | do_read_defect_data_12_all(fd, format); | |
371 | } | |
372 | ||
373 | static void do_ata_identify(int fd) | |
374 | { | |
375 | uint8_t cdb[32]; | |
376 | int cdb_len; | |
377 | uint8_t buf[512]; | |
378 | ||
379 | cdb_len = cdb_ata_identify(cdb); | |
380 | ||
381 | simple_command(fd, cdb, cdb_len, buf, sizeof(buf)); | |
382 | } | |
383 | ||
384 | static void do_ata_identify_16(int fd) | |
385 | { | |
386 | uint8_t cdb[32]; | |
387 | int cdb_len; | |
388 | uint8_t buf[512]; | |
389 | ||
390 | cdb_len = cdb_ata_identify_16(cdb); | |
391 | ||
392 | simple_command(fd, cdb, cdb_len, buf, sizeof(buf)); | |
393 | } | |
394 | ||
395 | static void do_ata_smart_return_status(int fd) | |
396 | { | |
397 | uint8_t cdb[32]; | |
398 | int cdb_len; | |
399 | uint8_t buf[512]; | |
400 | ||
401 | cdb_len = cdb_ata_smart_return_status(cdb); | |
402 | ||
403 | simple_command(fd, cdb, cdb_len, buf, sizeof(buf)); | |
404 | } | |
405 | ||
406 | static void do_ata_smart_read_data(int fd) | |
407 | { | |
408 | uint8_t cdb[32]; | |
409 | int cdb_len; | |
410 | uint8_t buf[512]; | |
411 | ||
412 | cdb_len = cdb_ata_smart_read_data(cdb); | |
413 | ||
414 | simple_command(fd, cdb, cdb_len, buf, sizeof(buf)); | |
415 | } | |
416 | ||
417 | static void do_ata_smart_read_threshold(int fd) | |
418 | { | |
419 | uint8_t cdb[32]; | |
420 | int cdb_len; | |
421 | uint8_t buf[512]; | |
422 | ||
423 | cdb_len = cdb_ata_smart_read_threshold(cdb); | |
424 | ||
425 | simple_command(fd, cdb, cdb_len, buf, sizeof(buf)); | |
426 | } | |
427 | ||
428 | static int do_ata_read_log_ext_page(int fd, uint8_t *buf, unsigned buf_sz, unsigned log_addr, unsigned page) | |
429 | { | |
430 | uint8_t cdb[32]; | |
431 | int cdb_len; | |
432 | ||
433 | cdb_len = cdb_ata_read_log_ext(cdb, 1, page, log_addr); | |
434 | return simple_command(fd, cdb, cdb_len, buf, buf_sz); | |
435 | } | |
436 | ||
437 | static void do_ata_read_log_ext(int fd) | |
438 | { | |
439 | uint8_t __attribute__((aligned(512))) buf[512]; | |
440 | uint8_t __attribute__((aligned(512))) buf_data[512]; | |
441 | unsigned log_addr; | |
442 | ||
443 | do_ata_read_log_ext_page(fd, buf, sizeof(buf), 0, 0); | |
444 | ||
445 | // Validate the page is valid | |
446 | if (buf[0] != 1 || buf[1] != 0) | |
447 | return; | |
448 | ||
449 | for (log_addr = 1; log_addr < sizeof(buf)/2; log_addr++) { | |
450 | unsigned num_pages = ata_get_word(buf, log_addr); | |
451 | if (num_pages) { | |
452 | unsigned page; | |
453 | for (page = 0; page < num_pages; page++) { | |
454 | printf("READ LOG EXT log addr %02X page %u/%u\n", log_addr, page, num_pages); | |
455 | int ret = do_ata_read_log_ext_page(fd, buf_data, sizeof(buf_data), log_addr, page); | |
456 | if (ret < 0) | |
457 | break; | |
458 | } | |
459 | } | |
460 | } | |
461 | } | |
462 | ||
463 | static int do_ata_smart_read_log_addr(int fd, unsigned char *buf, unsigned buf_sz, uint8_t log_addr, uint8_t block_count) | |
464 | { | |
465 | uint8_t cdb[32]; | |
466 | int cdb_len; | |
467 | ||
468 | cdb_len = cdb_ata_smart_read_log(cdb, log_addr, block_count); | |
469 | return simple_command(fd, cdb, cdb_len, buf, buf_sz); | |
470 | } | |
471 | ||
472 | static void do_ata_smart_read_log(int fd) | |
473 | { | |
474 | unsigned log_addr; | |
475 | uint8_t __attribute__((aligned(512))) buf[512]; | |
476 | uint8_t __attribute__((aligned(512))) buf_data[512*256]; | |
477 | ||
478 | int ret = do_ata_smart_read_log_addr(fd, buf, sizeof(buf), 0, 1); | |
479 | if (ret < (int)sizeof(buf)) | |
480 | return; | |
481 | ||
482 | // Validate the page is valid | |
483 | if (buf[0] != 1 || buf[1] != 0) | |
484 | return; | |
485 | ||
486 | for (log_addr = 1; log_addr < 255; log_addr++) { | |
487 | unsigned num_pages = buf[log_addr*2]; | |
488 | if (num_pages > 0) { | |
489 | printf("SMART READ LOG log addr %02X pages %u\n", log_addr, num_pages); | |
490 | fflush(stdout); | |
491 | do_ata_smart_read_log_addr(fd, buf_data, 512*num_pages, log_addr, num_pages); | |
492 | } | |
493 | } | |
494 | } | |
495 | ||
496 | static void do_ata_check_power_mode(int fd) | |
497 | { | |
498 | uint8_t cdb[32]; | |
499 | int cdb_len; | |
500 | ||
501 | printf("Check power mode\n"); | |
502 | cdb_len = cdb_ata_check_power_mode(cdb); | |
503 | simple_command(fd, cdb, cdb_len, NULL, 0); | |
504 | } | |
505 | ||
506 | void do_command(int fd) | |
507 | { | |
508 | debug = 0; | |
509 | is_ata = false; | |
510 | ||
511 | printf("msg,cdb,sense,data\n"); | |
512 | do_read_capacity(fd); | |
513 | do_simple_inquiry(fd); | |
514 | do_extended_inquiry(fd); | |
515 | do_log_sense(fd); | |
516 | do_mode_sense(fd); | |
517 | do_receive_diagnostic(fd); | |
518 | do_read_defect_data(fd); | |
519 | ||
520 | if (is_ata) { | |
521 | do_ata_identify(fd); | |
522 | do_ata_identify_16(fd); | |
523 | do_ata_check_power_mode(fd); | |
524 | do_ata_smart_return_status(fd); | |
525 | do_ata_smart_read_data(fd); | |
526 | do_ata_smart_read_threshold(fd); | |
527 | do_ata_read_log_ext(fd); | |
528 | do_ata_smart_read_log(fd); | |
529 | } | |
530 | } |
28 | 28 | |
29 | 29 | static unsigned char sense[128]; |
30 | 30 | |
31 | int debug = 1; | |
32 | ||
31 | 33 | bool submit_cmd(int fd, unsigned char *cdb, unsigned cdb_len, unsigned char *buf, unsigned buf_len, int dxfer_dir) |
32 | 34 | { |
33 | 35 | sg_io_hdr_t hdr; |
36 | ||
37 | if (debug) | |
38 | cdb_dump(cdb, cdb_len); | |
34 | 39 | |
35 | 40 | memset(&hdr, 0, sizeof(hdr)); |
36 | 41 | |
46 | 51 | hdr.flags = SG_FLAG_LUN_INHIBIT; |
47 | 52 | hdr.pack_id = 0; |
48 | 53 | hdr.usr_ptr = 0; |
49 | ||
50 | printf("sbp: %p\n", hdr.sbp); | |
51 | 54 | |
52 | 55 | ssize_t ret = write(fd, &hdr, sizeof(hdr)); |
53 | 56 | return ret == sizeof(hdr); |
76 | 79 | *sensep = sense; |
77 | 80 | *sense_len = hdr.sb_len_wr; |
78 | 81 | |
79 | printf("sense data:\n"); | |
80 | sense_dump(sense, hdr.sb_len_wr); | |
82 | if (debug) { | |
83 | printf("sense data:\n"); | |
84 | sense_dump(sense, hdr.sb_len_wr); | |
85 | } | |
81 | 86 | } |
82 | 87 | if (buf_read) |
83 | 88 | *buf_read = hdr.dxfer_len - hdr.resid; |
1 | 1 | #define LIBSCSICMD_TEST_H |
2 | 2 | |
3 | 3 | #include <stdio.h> |
4 | ||
5 | extern int debug; | |
4 | 6 | |
5 | 7 | /** Do the command that we want to test on the open disk interface. */ |
6 | 8 | void do_command(int fd); |
12 | 14 | return read_response_buf(fd, sense, sense_len, NULL); |
13 | 15 | } |
14 | 16 | |
15 | void response_dump(unsigned char *buf, int buf_len); | |
16 | ||
17 | 17 | #endif |
0 | #include <stdio.h> | |
1 | #include <ctype.h> | |
2 | #include <stdbool.h> | |
3 | #include <unistd.h> | |
4 | #include <string.h> | |
5 | #include <stdlib.h> | |
6 | ||
7 | #include "parse_log_sense.h" | |
8 | #include "parse_mode_sense.h" | |
9 | #include "parse_extended_inquiry.h" | |
10 | #include "parse_read_defect_data.h" | |
11 | #include "parse_receive_diagnostics.h" | |
12 | #include "scsicmd.h" | |
13 | #include "sense_dump.h" | |
14 | ||
15 | #ifndef __AFL_LOOP | |
16 | #define __AFL_LOOP(count) 1 | |
17 | #endif | |
18 | ||
19 | static char *csvtok_last; | |
20 | ||
21 | static void csvtok_reset(void) | |
22 | { | |
23 | csvtok_last = NULL; | |
24 | } | |
25 | ||
26 | static char *csvtok(char *start) | |
27 | { | |
28 | if (start) | |
29 | csvtok_last = start; | |
30 | ||
31 | if (!csvtok_last) | |
32 | return NULL; | |
33 | ||
34 | char *ret = csvtok_last; | |
35 | for (; *csvtok_last && *csvtok_last != ','; csvtok_last++) | |
36 | ; | |
37 | if (*csvtok_last) { | |
38 | *csvtok_last = 0; | |
39 | csvtok_last++; | |
40 | } | |
41 | else | |
42 | csvtok_last = NULL; | |
43 | return ret; | |
44 | } | |
45 | ||
46 | static unsigned char char2val(unsigned char ch) | |
47 | { | |
48 | if (ch >= '0' && ch <= '9') | |
49 | return ch - '0'; | |
50 | else if (ch >= 'a' && ch <= 'f') | |
51 | return ch - 'a' + 10; | |
52 | else if (ch >= 'A' && ch <= 'F') | |
53 | return ch - 'A' + 10; | |
54 | else | |
55 | return 0; | |
56 | } | |
57 | ||
58 | static void print_hex(uint8_t *buf, unsigned buf_len) | |
59 | { | |
60 | unsigned i; | |
61 | for (i = 0; i < buf_len; i++) { | |
62 | printf("%02x ", buf[i]); | |
63 | } | |
64 | printf("\n"); | |
65 | } | |
66 | ||
67 | static unsigned char *parse_hex(char *str, int *len_out) | |
68 | { | |
69 | char buf[64*1024]; | |
70 | const unsigned buf_size = sizeof(buf); | |
71 | unsigned char ch; | |
72 | unsigned len = 0; | |
73 | bool top_char = true; | |
74 | ||
75 | *len_out = -1; | |
76 | ||
77 | for (; *str && len < buf_size; str++) { | |
78 | if (isspace(*str)) { | |
79 | if (!top_char) { | |
80 | printf("Leftover character\n"); | |
81 | return NULL; | |
82 | } | |
83 | } else if (isxdigit(*str)) { | |
84 | if (top_char) { | |
85 | ch = char2val(*str); | |
86 | top_char = false; | |
87 | } else { | |
88 | buf[len++] = (ch<<4) | char2val(*str); | |
89 | top_char = true; | |
90 | } | |
91 | } else { | |
92 | printf("Unknown character '%c'\n", *str); | |
93 | return NULL; | |
94 | } | |
95 | } | |
96 | ||
97 | // For valgrind and AFL, copy the data to a malloc buffer to easily detect out of bounds accesses | |
98 | unsigned char *out = malloc(len); | |
99 | memcpy(out, buf, len); | |
100 | *len_out = len; | |
101 | return out; | |
102 | } | |
103 | ||
104 | static inline const char *yes_no(bool val) | |
105 | { | |
106 | return val ? "yes" : "no"; | |
107 | } | |
108 | ||
109 | static void unparsed_data(uint8_t *buf, unsigned buf_len, uint8_t *start, unsigned total_len) | |
110 | { | |
111 | const unsigned len = safe_len(start, total_len, buf, buf_len); | |
112 | printf("Unparsed data: "); | |
113 | print_hex(buf, len); | |
114 | } | |
115 | ||
116 | static void parse_log_sense_param_informational_exceptions(uint16_t param_code, uint8_t *param, uint8_t param_len) | |
117 | { | |
118 | switch (param_code) { | |
119 | case 0: | |
120 | printf("Information Exceptions ASC: %02X\n", param[0]); | |
121 | printf("Information Exceptions ASCQ: %02X\n", param[1]); | |
122 | printf("Temperature: %u\n", param[2]); | |
123 | if (param_len > 3) | |
124 | unparsed_data(param+3, param_len-3, param, param_len); | |
125 | break; | |
126 | default: | |
127 | unparsed_data(param, param_len, param, param_len); | |
128 | } | |
129 | } | |
130 | ||
131 | static void parse_log_sense_param_ascii(uint8_t *param, unsigned param_len) | |
132 | { | |
133 | uint8_t *ascii = log_sense_param_data(param); | |
134 | unsigned ascii_len = log_sense_param_len(param); | |
135 | ascii_len = safe_len(param, param_len, ascii, ascii_len); | |
136 | ||
137 | printf("ASCII (%u): '", ascii_len); | |
138 | for (; ascii_len > 0; ascii_len--, ascii++) | |
139 | putchar(*ascii); | |
140 | printf("'\n"); | |
141 | } | |
142 | ||
143 | static void parse_log_sense_param_counter(uint8_t *param, unsigned param_len) | |
144 | { | |
145 | uint8_t *data = log_sense_param_data(param); | |
146 | unsigned data_len = log_sense_param_len(param); | |
147 | ||
148 | switch (data_len) { | |
149 | case 2: | |
150 | printf("Counter 16bit: %u\n", get_uint16(data, 0)); | |
151 | break; | |
152 | case 4: | |
153 | printf("Counter 32bit: %u\n", get_uint32(data, 0)); | |
154 | break; | |
155 | case 8: | |
156 | printf("Counter 64bit: %lu\n", get_uint64(data, 0)); | |
157 | break; | |
158 | default: | |
159 | printf("Counter %d bytes\n", data_len); | |
160 | unparsed_data(data, data_len, param, param_len); | |
161 | break; | |
162 | } | |
163 | } | |
164 | ||
165 | static void parse_log_sense_param(uint8_t page, uint8_t subpage, uint16_t param_code, uint8_t *param, uint8_t param_len) | |
166 | { | |
167 | (void)subpage; | |
168 | ||
169 | switch (page) { | |
170 | case 0x2F: parse_log_sense_param_informational_exceptions(param_code, log_sense_param_data(param), log_sense_param_len(param)); break; | |
171 | /* TODO: parse more LOG SENSE pages */ | |
172 | default: | |
173 | switch (log_sense_param_fmt(param)) { | |
174 | case LOG_PARAM_FMT_COUNTER_STOP: | |
175 | case LOG_PARAM_FMT_COUNTER_ROLLOVER: | |
176 | parse_log_sense_param_counter(param, param_len); | |
177 | break; | |
178 | case LOG_PARAM_FMT_ASCII: | |
179 | parse_log_sense_param_ascii(param, param_len); | |
180 | break; | |
181 | default: | |
182 | unparsed_data(param, param_len, param, param_len); | |
183 | break; | |
184 | } | |
185 | break; | |
186 | } | |
187 | } | |
188 | ||
189 | static int parse_log_sense(unsigned char *data, unsigned data_len) | |
190 | { | |
191 | printf("Log Sense\n"); | |
192 | if (data_len < LOG_SENSE_MIN_LEN) { | |
193 | printf("Insufficient data in log sense to begin parsing\n"); | |
194 | return 1; | |
195 | } | |
196 | printf("Log Sense Page Code: 0x%02x\n", log_sense_page_code(data)); | |
197 | printf("Log Sense Subpage format: %s\n", yes_no(log_sense_subpage_format(data))); | |
198 | if (log_sense_subpage_format(data)) | |
199 | printf("Log Sense Subpage: 0x%02x\n", log_sense_subpage_code(data)); | |
200 | printf("Log Sense Data Saved: %s\n", yes_no(log_sense_data_saved(data))); | |
201 | printf("Log Sense Data Length: %u\n", log_sense_data_len(data)); | |
202 | ||
203 | if (log_sense_page_code(data) == 0) { | |
204 | if (!log_sense_subpage_format(data)) { | |
205 | printf("Supported Log Pages:\n"); | |
206 | uint8_t supported_page; | |
207 | for_all_log_sense_pg_0_supported_pages(data, data_len, supported_page) { | |
208 | printf("\t%02X\n", supported_page & 0x3F); | |
209 | } | |
210 | } else if (log_sense_subpage_code(data) == 0xFF) { | |
211 | printf("Supported Log Subpages:\n"); | |
212 | uint8_t supported_page, supported_subpage; | |
213 | for_all_log_sense_pg_0_supported_subpages(data, data_len, supported_page, supported_subpage) { | |
214 | printf("\t%02X %02X\n", supported_page & 0x3F, supported_subpage); | |
215 | } | |
216 | } else { | |
217 | printf("Unknown supported log page combination"); | |
218 | unparsed_data(log_sense_data(data), log_sense_data_len(data), data, data_len); | |
219 | } | |
220 | } else { | |
221 | uint8_t *param; | |
222 | for_all_log_sense_params(data, data_len, param) { | |
223 | putchar('\n'); | |
224 | printf("Log Sense Param Code: 0x%04x\n", log_sense_param_code(param)); | |
225 | printf("Log Sense Param Len: %u\n", log_sense_param_len(param)); | |
226 | printf("Log Sense Param format: %u\n", log_sense_param_fmt(param)); | |
227 | parse_log_sense_param(log_sense_page_code(data), log_sense_subpage_code(data), log_sense_param_code(param), param, log_sense_param_len(param) + 4); | |
228 | } | |
229 | } | |
230 | ||
231 | return 0; | |
232 | } | |
233 | ||
234 | static int parse_read_cap_10(unsigned char *data, unsigned data_len) | |
235 | { | |
236 | uint32_t max_lba; | |
237 | uint32_t block_size; | |
238 | bool parsed = parse_read_capacity_10(data, data_len, &max_lba, &block_size); | |
239 | ||
240 | printf("Read Capacity 10\n"); | |
241 | if (!parsed) { | |
242 | unparsed_data(data, data_len, data, data_len); | |
243 | return 1; | |
244 | } | |
245 | ||
246 | printf("Max LBA: %u\n", max_lba); | |
247 | printf("Block Size: %u\n", block_size); | |
248 | ||
249 | if (data_len > 8) | |
250 | unparsed_data(data+8, data_len-8, data, data_len); | |
251 | return 0; | |
252 | } | |
253 | ||
254 | static int parse_read_cap_16(unsigned char *data, unsigned data_len) | |
255 | { | |
256 | uint64_t max_lba; | |
257 | uint32_t block_size; | |
258 | bool prot_enable, thin_provisioning_enabled, thin_provisioning_zero; | |
259 | unsigned p_type, p_i_exponent, logical_blocks_per_physical_block_exponent, lowest_aligned_lba; | |
260 | ||
261 | printf("Read Capacity 16\n"); | |
262 | ||
263 | bool parsed = parse_read_capacity_16(data, data_len, &max_lba, &block_size, &prot_enable, | |
264 | &p_type, &p_i_exponent, &logical_blocks_per_physical_block_exponent, | |
265 | &thin_provisioning_enabled, &thin_provisioning_zero, &lowest_aligned_lba); | |
266 | ||
267 | if (!parsed) { | |
268 | unparsed_data(data, data_len, data, data_len); | |
269 | return 1; | |
270 | } | |
271 | ||
272 | printf("Max LBA: %lu\n", max_lba); | |
273 | printf("Block Size: %u\n", block_size); | |
274 | printf("Protection enabled: %s\n", yes_no(prot_enable)); | |
275 | printf("Thin Provisioning enabled: %s\n", yes_no(thin_provisioning_enabled)); | |
276 | printf("Thin Provisioning zero: %s\n", yes_no(thin_provisioning_zero)); | |
277 | printf("P Type: %u\n", p_type); | |
278 | printf("Pi Exponent: %u\n", p_i_exponent); | |
279 | printf("Logical blocks per physical block exponent: %u\n", logical_blocks_per_physical_block_exponent); | |
280 | printf("Lowest aligned LBA: %u\n", lowest_aligned_lba); | |
281 | ||
282 | return 0; | |
283 | } | |
284 | ||
285 | static int parse_extended_inquiry_data(uint8_t *data, unsigned data_len) | |
286 | { | |
287 | printf("Extended Inquiry\n"); | |
288 | ||
289 | if (data_len < EVPD_MIN_LEN) { | |
290 | printf("Not enough data for EVPD header\n"); | |
291 | unparsed_data(data, data_len, data, data_len); | |
292 | return 1; | |
293 | } | |
294 | ||
295 | printf("Peripheral Qualifier: %d\n", evpd_peripheral_qualifier(data)); | |
296 | printf("Peripheral Device Type: %d\n", evpd_peripheral_device_type(data)); | |
297 | printf("EVPD page code: 0x%02X\n", evpd_page_code(data)); | |
298 | printf("EVPD data len: %u\n", evpd_page_len(data)); | |
299 | ||
300 | if (!evpd_is_valid(data, data_len)) | |
301 | return 0; | |
302 | ||
303 | uint8_t *page_data = evpd_page_data(data); | |
304 | ||
305 | if (evpd_is_ascii_page(evpd_page_code(data))) { | |
306 | printf("ASCII len: %u\n", evpd_ascii_len(page_data)); | |
307 | printf("ASCII string: '%*s'\n", evpd_ascii_len(page_data), evpd_ascii_data(page_data)); | |
308 | if (evpd_ascii_post_data_len(page_data, data_len) > 0) | |
309 | unparsed_data(evpd_ascii_post_data(page_data), evpd_ascii_post_data_len(page_data, data_len), data, data_len); | |
310 | } else { | |
311 | /* TODO: parse more of the extended inquiry pages */ | |
312 | unparsed_data(page_data, evpd_page_len(data), data, data_len); | |
313 | } | |
314 | return 0; | |
315 | } | |
316 | ||
317 | static int parse_simple_inquiry_data(uint8_t *data, unsigned data_len) | |
318 | { | |
319 | int device_type; | |
320 | scsi_vendor_t vendor; | |
321 | scsi_model_t model; | |
322 | scsi_fw_revision_t rev; | |
323 | scsi_serial_t serial; | |
324 | bool parsed = parse_inquiry(data, data_len, &device_type, vendor, model, rev, serial); | |
325 | ||
326 | printf("Simple Inquiry\n"); | |
327 | ||
328 | if (!parsed) { | |
329 | unparsed_data(data, data_len, data, data_len); | |
330 | return 1; | |
331 | } | |
332 | ||
333 | printf("Device Type: %d\n", device_type); | |
334 | printf("Vendor: %s\n", vendor); | |
335 | printf("Model: %s\n", model); | |
336 | printf("FW Revision: %s\n", rev); | |
337 | printf("Serial: %s\n", serial); | |
338 | return 0; | |
339 | } | |
340 | ||
341 | static int parse_inquiry_data(uint8_t *cdb, unsigned cdb_len, uint8_t *data, unsigned data_len) | |
342 | { | |
343 | if (cdb_len < 6) | |
344 | return 1; | |
345 | ||
346 | if (cdb[1] & 1) | |
347 | return parse_extended_inquiry_data(data, data_len); | |
348 | else | |
349 | return parse_simple_inquiry_data(data, data_len); | |
350 | } | |
351 | ||
352 | static void parse_mode_sense_block_descriptor(uint8_t *data, unsigned data_len) | |
353 | { | |
354 | if (data_len != BLOCK_DESCRIPTOR_LENGTH) { | |
355 | printf("Unknown block descriptor\n"); | |
356 | unparsed_data(data, data_len, data, data_len); | |
357 | return; | |
358 | } | |
359 | ||
360 | printf("Density code: %u\n", block_descriptor_density_code(data)); | |
361 | printf("Num blocks: %u\n", block_descriptor_num_blocks(data)); | |
362 | printf("Block length: %u\n", block_descriptor_block_length(data)); | |
363 | } | |
364 | ||
365 | static void parse_mode_sense_data_page(uint8_t *data, unsigned data_len) | |
366 | { | |
367 | bool subpage_format = mode_sense_data_subpage_format(data); | |
368 | printf("\nPage code: 0x%02x\n", mode_sense_data_page_code(data)); | |
369 | ||
370 | if (subpage_format) | |
371 | printf("Subpage code: 0x%02x\n", mode_sense_data_subpage_code(data)); | |
372 | printf("Page Saveable: %s\n", yes_no(mode_sense_data_parameter_saveable(data))); | |
373 | ||
374 | printf("Page len: %u\n", mode_sense_data_param_len(data)); | |
375 | /* TODO: Parse the mode sense data */ | |
376 | unparsed_data(mode_sense_data_param(data), mode_sense_data_param_len(data), data, data_len); | |
377 | } | |
378 | ||
379 | static int parse_mode_sense_10(uint8_t *data, unsigned data_len) | |
380 | { | |
381 | printf("Mode Sense 10\n"); | |
382 | ||
383 | if (data_len < MODE_SENSE_10_MIN_LEN) { | |
384 | printf("Not enough data for MODE SENSE header\n"); | |
385 | unparsed_data(data, data_len, data, data_len); | |
386 | return 1; | |
387 | } | |
388 | ||
389 | printf("Mode Sense 10 data length: %u\n", mode_sense_10_data_len(data)); | |
390 | printf("Mode Sense 10 medium type: %u\n", mode_sense_10_medium_type(data)); | |
391 | printf("Mode Sense 10 Device specific param: %u\n", mode_sense_10_device_specific_param(data)); | |
392 | printf("Mode Sense 10 Long LBA: %s\n", yes_no(mode_sense_10_long_lba(data))); | |
393 | printf("Mode Sense 10 Block descriptor length: %u\n", mode_sense_10_block_descriptor_length(data)); | |
394 | ||
395 | if (data_len < mode_sense_10_expected_length(data)) { | |
396 | printf("Not enough data to parse full data\n"); | |
397 | unparsed_data(data + MODE_SENSE_10_MIN_LEN, data_len - MODE_SENSE_10_MIN_LEN, data, data_len); | |
398 | return 1; | |
399 | } | |
400 | ||
401 | if (mode_sense_10_block_descriptor_length(data) > 0) { | |
402 | const unsigned safe_desc_len = safe_len(data, data_len, mode_sense_10_block_descriptor_data(data), mode_sense_10_block_descriptor_length(data)); | |
403 | parse_mode_sense_block_descriptor(mode_sense_10_block_descriptor_data(data), safe_desc_len); | |
404 | } | |
405 | ||
406 | unsigned remaining_len; | |
407 | uint8_t *mode_page; | |
408 | for_all_mode_sense_10_pages(data, data_len, mode_page, remaining_len) { | |
409 | printf("\nRemaining len: %u\n", remaining_len); | |
410 | parse_mode_sense_data_page(mode_page, remaining_len); | |
411 | } | |
412 | return 0; | |
413 | } | |
414 | ||
415 | static int parse_mode_sense_6(uint8_t *data, unsigned data_len) | |
416 | { | |
417 | printf("Mode Sense 6\n"); | |
418 | ||
419 | if (data_len < MODE_SENSE_6_MIN_LEN) { | |
420 | printf("Not enough data for MODE SENSE 6 header\n"); | |
421 | unparsed_data(data, data_len, data, data_len); | |
422 | return 1; | |
423 | } | |
424 | ||
425 | printf("Mode Sense 6 data length: %u\n", mode_sense_6_data_len(data)); | |
426 | printf("Mode Sense 6 medium type: %u\n", mode_sense_6_medium_type(data)); | |
427 | printf("Mode Sense 6 Device specific param: %u\n", mode_sense_6_device_specific_param(data)); | |
428 | printf("Mode Sense 6 Block descriptor length: %u\n", mode_sense_6_block_descriptor_length(data)); | |
429 | ||
430 | if (data_len < mode_sense_6_expected_length(data)) { | |
431 | printf("Not enough data to parse full data\n"); | |
432 | unparsed_data(data + MODE_SENSE_6_MIN_LEN, data_len - MODE_SENSE_6_MIN_LEN, data, data_len); | |
433 | return 1; | |
434 | } | |
435 | ||
436 | if (!mode_sense_6_is_valid_header(data, data_len)) { | |
437 | printf("Bad data in mode sense header\n"); | |
438 | return 1; | |
439 | } | |
440 | ||
441 | if (mode_sense_6_block_descriptor_length(data) > 0) { | |
442 | unsigned safe_desc_len = safe_len(data, data_len, mode_sense_6_block_descriptor_data(data), mode_sense_6_block_descriptor_length(data)); | |
443 | parse_mode_sense_block_descriptor(mode_sense_6_block_descriptor_data(data), safe_desc_len); | |
444 | } | |
445 | ||
446 | unsigned remaining_len; | |
447 | uint8_t *mode_page; | |
448 | for_all_mode_sense_6_pages(data, data_len, mode_page, remaining_len) { | |
449 | printf("Remaining len: %u\n", remaining_len); | |
450 | parse_mode_sense_data_page(mode_page, remaining_len); | |
451 | } | |
452 | return 0; | |
453 | } | |
454 | ||
455 | static void read_defect_data_format(address_desc_format_e fmt, uint8_t *data, unsigned len) | |
456 | { | |
457 | const unsigned fmt_len = read_defect_data_fmt_len(fmt); | |
458 | if (fmt_len == 0) { | |
459 | printf("Unknown format to decode\n"); | |
460 | unparsed_data(data, len, data, len); | |
461 | return; | |
462 | } | |
463 | for (; len > fmt_len; data += fmt_len, len -= fmt_len) { | |
464 | switch (fmt) { | |
465 | case ADDRESS_FORMAT_SHORT: | |
466 | printf("\t%u\n", get_uint32(data, 0)); | |
467 | break; | |
468 | case ADDRESS_FORMAT_LONG: | |
469 | printf("\t%lu\n", get_uint64(data, 0)); | |
470 | break; | |
471 | case ADDRESS_FORMAT_INDEX_OFFSET: | |
472 | printf("\tC=%u H=%u B=%u\n", | |
473 | format_address_byte_from_index_cylinder(data), | |
474 | format_address_byte_from_index_head(data), | |
475 | format_address_byte_from_index_bytes(data)); | |
476 | break; | |
477 | case ADDRESS_FORMAT_PHYSICAL: | |
478 | printf("\tC=%u H=%u S=%u\n", | |
479 | format_address_physical_cylinder(data), | |
480 | format_address_physical_head(data), | |
481 | format_address_physical_sector(data)); | |
482 | break; | |
483 | case ADDRESS_FORMAT_VENDOR: | |
484 | printf("\t%08x\n", get_uint32(data, 0)); | |
485 | break; | |
486 | default: | |
487 | break; | |
488 | } | |
489 | } | |
490 | } | |
491 | ||
492 | static int parse_read_defect_data_10(uint8_t *data, unsigned data_len) | |
493 | { | |
494 | printf("Read Defect Data 10\n"); | |
495 | ||
496 | if (!read_defect_data_10_hdr_is_valid(data, data_len)) { | |
497 | printf("Header is not valid\n"); | |
498 | unparsed_data(data, data_len, data, data_len); | |
499 | return 1; | |
500 | } | |
501 | ||
502 | printf("Plist: %s\n", yes_no(read_defect_data_10_is_plist_valid(data))); | |
503 | printf("Glist: %s\n", yes_no(read_defect_data_10_is_glist_valid(data))); | |
504 | printf("Format: %s\n", read_defect_data_format_to_str(read_defect_data_10_list_format(data))); | |
505 | printf("Len: %u\n", read_defect_data_10_len(data)); | |
506 | ||
507 | if (!read_defect_data_10_is_valid(data, data_len)) | |
508 | return 0; | |
509 | ||
510 | if (data_len > 0) { | |
511 | const unsigned len = safe_len(data, data_len, read_defect_data_10_data(data), read_defect_data_10_len(data)); | |
512 | read_defect_data_format(read_defect_data_10_list_format(data), read_defect_data_10_data(data), len); | |
513 | } | |
514 | return 0; | |
515 | } | |
516 | ||
517 | static int parse_read_defect_data_12(uint8_t *data, unsigned data_len) | |
518 | { | |
519 | printf("Read Defect Data 12\n"); | |
520 | ||
521 | if (!read_defect_data_12_hdr_is_valid(data, data_len)) { | |
522 | printf("Header is not valid\n"); | |
523 | unparsed_data(data, data_len, data, data_len); | |
524 | return 1; | |
525 | } | |
526 | ||
527 | printf("Plist: %s\n", yes_no(read_defect_data_12_is_plist_valid(data))); | |
528 | printf("Glist: %s\n", yes_no(read_defect_data_12_is_glist_valid(data))); | |
529 | printf("Format: %s\n", read_defect_data_format_to_str(read_defect_data_12_list_format(data))); | |
530 | printf("Len: %u\n", read_defect_data_12_len(data)); | |
531 | ||
532 | if (!read_defect_data_12_is_valid(data, data_len)) | |
533 | return 0; | |
534 | ||
535 | if (data_len > 0) { | |
536 | const unsigned len = safe_len(data, data_len, read_defect_data_10_data(data), read_defect_data_10_len(data)); | |
537 | read_defect_data_format(read_defect_data_12_list_format(data), read_defect_data_12_data(data), len); | |
538 | } | |
539 | return 0; | |
540 | } | |
541 | ||
542 | static void parse_receive_diagnostic_results_pg_0(uint8_t *data, unsigned data_len) | |
543 | { | |
544 | printf("Supported Receive Diagnostic Results pages:\n"); | |
545 | for (; data_len > 0; data_len--, data++) | |
546 | printf("\t0x%02x\n", data[0]); | |
547 | } | |
548 | ||
549 | static unsigned parse_enclosure_descriptor(uint8_t *data, unsigned data_len) | |
550 | { | |
551 | char name[16]; | |
552 | ||
553 | if (!ses_config_enclosure_descriptor_is_valid(data, data_len)) | |
554 | return data_len; | |
555 | ||
556 | printf("\nProcess identifier: %u\n", ses_config_enclosure_descriptor_process_identifier(data)); | |
557 | printf("Num processes: %u\n", ses_config_enclosure_descriptor_num_processes(data)); | |
558 | printf("Subenclosure identifier: %u\n", ses_config_enclosure_descriptor_subenclosure_identifier(data)); | |
559 | printf("Num Type Descriptors: %u\n", ses_config_enclosure_descriptor_num_type_descriptors(data)); | |
560 | printf("Enclosure descriptor len: %u\n", ses_config_enclosure_descriptor_len(data)); | |
561 | printf("Logical identified: %016lx\n", ses_config_enclosure_descriptor_logical_identifier(data)); | |
562 | ||
563 | ses_config_enclosure_descriptor_vendor_identifier(data, name, sizeof(name)); | |
564 | printf("Vendor identifier: %s\n", name); | |
565 | ||
566 | ses_config_enclosure_descriptor_product_identifier(data, name, sizeof(name)); | |
567 | printf("Product identifier: %s\n", name); | |
568 | ||
569 | ses_config_enclosure_descriptor_revision_level(data, name, sizeof(name)); | |
570 | printf("Revision level: %s\n", name); | |
571 | ||
572 | printf("Vendor info len: %u\n", ses_config_enclosure_descriptor_vendor_len(data)); | |
573 | if (ses_config_enclosure_descriptor_vendor_len(data) > 0) | |
574 | unparsed_data(ses_config_enclosure_descriptor_vendor_info(data), ses_config_enclosure_descriptor_vendor_len(data), data, data_len); | |
575 | ||
576 | return ses_config_enclosure_descriptor_len(data) + 4; | |
577 | } | |
578 | ||
579 | static void parse_receive_diagnostic_results_pg_1(uint8_t *data, unsigned data_len) | |
580 | { | |
581 | unsigned parsed_len = 8; | |
582 | unsigned num_enclosures; | |
583 | ||
584 | if (!ses_config_is_valid(data, data_len)) | |
585 | return; | |
586 | ||
587 | printf("SES config page:\n"); | |
588 | num_enclosures = ses_config_num_sub_enclosures(data); | |
589 | printf("Num subenclosures: %u\n", num_enclosures); | |
590 | printf("Generation code: %u\n", ses_config_generation(data)); | |
591 | ||
592 | for (; num_enclosures > 0 && parsed_len < data_len; num_enclosures--) | |
593 | parsed_len += parse_enclosure_descriptor(ses_config_sub_enclosure(data), data_len-parsed_len); | |
594 | ||
595 | /* TODO: There can be additional enclosures and type descriptors and strings */ | |
596 | unparsed_data(data + parsed_len, data_len - parsed_len, data, data_len); | |
597 | } | |
598 | ||
599 | static int parse_receive_diagnostic_results(uint8_t *data, unsigned data_len) | |
600 | { | |
601 | printf("Receive Diagnostic Results\n"); | |
602 | ||
603 | if (!recv_diag_is_valid(data, data_len)) { | |
604 | printf("Data is not valid\n"); | |
605 | return 1; | |
606 | } | |
607 | ||
608 | printf("Page code: 0x%02X\n", recv_diag_get_page_code(data)); | |
609 | printf("Page code specific: 0x%02x\n", recv_diag_get_page_code_specific(data)); | |
610 | printf("Len: %u\n", recv_diag_get_len(data)); | |
611 | ||
612 | switch (recv_diag_get_page_code(data)) { | |
613 | case 0: | |
614 | parse_receive_diagnostic_results_pg_0(recv_diag_data(data), safe_len(data, data_len, recv_diag_data(data), recv_diag_get_len(data))); | |
615 | break; | |
616 | case 1: | |
617 | parse_receive_diagnostic_results_pg_1(data, data_len); | |
618 | break; | |
619 | default: | |
620 | unparsed_data(recv_diag_data(data), recv_diag_get_len(data), data, data_len); /* TODO: parse SES pages */ | |
621 | break; | |
622 | } | |
623 | return 0; | |
624 | } | |
625 | ||
626 | static void process_data(char *cdb_src, char *sense_src, char *data_src) | |
627 | { | |
628 | unsigned char *cdb = NULL; | |
629 | unsigned char *sense = NULL; | |
630 | unsigned char *data = NULL; | |
631 | int cdb_len, sense_len, data_len; | |
632 | ||
633 | printf("CDB: %s\n", cdb_src); | |
634 | printf("Sense: %s\n", sense_src); | |
635 | printf("Data: %s\n", data_src); | |
636 | ||
637 | if (cdb_src == NULL || sense_src == NULL || data_src == NULL) { | |
638 | printf("Input csv is invalid\n"); | |
639 | return; | |
640 | } | |
641 | ||
642 | cdb = parse_hex(cdb_src, &cdb_len); | |
643 | sense = parse_hex(sense_src, &sense_len); | |
644 | data = parse_hex(data_src, &data_len); | |
645 | ||
646 | printf("CDB Len: %d\n", cdb_len); | |
647 | printf("Sense Len: %d\n", sense_len); | |
648 | printf("Data Len: %d\n", data_len); | |
649 | ||
650 | if (cdb_len < 0) { | |
651 | printf("Failed to parse CDB\n"); | |
652 | goto Exit; | |
653 | } | |
654 | if (sense_len < 0) { | |
655 | printf("Failed to parse SENSE\n"); | |
656 | goto Exit; | |
657 | } | |
658 | if (data_len < 0) { | |
659 | printf("Failed to parse DATA\n"); | |
660 | goto Exit; | |
661 | } | |
662 | ||
663 | if (sense_len > 0) { | |
664 | printf("Sense data indicates an error, not parsing data\n"); | |
665 | sense_dump(sense, sense_len); | |
666 | goto Exit; | |
667 | } | |
668 | ||
669 | switch (cdb[0]) { | |
670 | case 0x4D: parse_log_sense(data, data_len); break; | |
671 | case 0x25: parse_read_cap_10(data, data_len); break; | |
672 | case 0x9E: parse_read_cap_16(data, data_len); break; | |
673 | case 0x12: parse_inquiry_data(cdb, cdb_len, data, data_len); break; | |
674 | case 0x5A: parse_mode_sense_10(data, data_len); break; | |
675 | case 0x1A: parse_mode_sense_6(data, data_len); break; | |
676 | case 0x1C: parse_receive_diagnostic_results(data, data_len); break; | |
677 | case 0x37: parse_read_defect_data_10(data, data_len); break; | |
678 | case 0xB7: parse_read_defect_data_12(data, data_len); break; | |
679 | default: | |
680 | printf("Unsupported CDB opcode %02X\n", cdb[0]); | |
681 | unparsed_data(data, data_len, data, data_len); | |
682 | break; | |
683 | } | |
684 | ||
685 | Exit: | |
686 | free(cdb); | |
687 | free(sense); | |
688 | free(data); | |
689 | } | |
690 | ||
691 | static ssize_t read_newline(char *buf, size_t buf_sz) | |
692 | { | |
693 | ssize_t data_read = 0; | |
694 | ||
695 | while (data_read < (ssize_t)buf_sz) { | |
696 | int ch = getchar(); | |
697 | if (ch == EOF) | |
698 | break; | |
699 | ||
700 | if (ch == '\n' || ch == '\r') | |
701 | return data_read; | |
702 | ||
703 | buf[data_read++] = ch; | |
704 | } | |
705 | ||
706 | return data_read; | |
707 | } | |
708 | ||
709 | int main(int argc, char **argv) | |
710 | { | |
711 | char *cdb_src, *sense_src, *data_src; | |
712 | ||
713 | if (argc != 4 && argc != 1) { | |
714 | printf("Usage: %s \"cdb\" \"sense\" \"data\"\n", argv[0]); | |
715 | return 1; | |
716 | } | |
717 | ||
718 | if (argc == 1) { | |
719 | while (__AFL_LOOP(30000)) { | |
720 | char buf[64*1024]; | |
721 | memset(buf, 0, sizeof(buf)); | |
722 | int ret = read_newline(buf, sizeof(buf)); | |
723 | if (ret <= 0) { | |
724 | printf("Insufficient input\n"); | |
725 | return 1; | |
726 | } | |
727 | buf[ret] = 0; | |
728 | ||
729 | csvtok_reset(); | |
730 | csvtok(buf); | |
731 | cdb_src = csvtok(NULL); | |
732 | sense_src = csvtok(NULL); | |
733 | data_src = csvtok(NULL); | |
734 | process_data(cdb_src, sense_src, data_src); | |
735 | printf("=================================================================================\n"); | |
736 | } | |
737 | } else { | |
738 | cdb_src = argv[1]; | |
739 | sense_src = argv[2]; | |
740 | data_src = argv[3]; | |
741 | process_data(cdb_src, sense_src, data_src); | |
742 | } | |
743 | ||
744 | return 0; | |
745 | } |
0 | #!/usr/bin/env python | |
1 | ||
2 | import sys | |
3 | import subprocess | |
4 | ||
5 | files = { | |
6 | ',4d ' : 'log_sense', | |
7 | ',25 ' : 'read_cap_10', | |
8 | ',9e ' : 'read_cap_16', | |
9 | ',12 ' : 'inquiry', | |
10 | ',5a ' : 'mode_sense_10', | |
11 | ',1a ' : 'mode_sense_6', | |
12 | ',37 ' : 'read_defect_data_10', | |
13 | ',b7 ' : 'read_defect_data_12', | |
14 | ',1c ' : 'receive_diagnostics', | |
15 | } | |
16 | ||
17 | for key in files.keys(): | |
18 | filename = files[key] + '.csv.bz2' | |
19 | f = subprocess.Popen(['/bin/bzip2', '-z', '-c', '-9'], stdin=subprocess.PIPE, stdout=file(filename, 'w')) | |
20 | if f is None: | |
21 | print 'Failed to create process for', filename | |
22 | files[key] = f | |
23 | ||
24 | for line in sys.stdin: | |
25 | prefix = line[0:4] | |
26 | f = files.get(prefix, None) | |
27 | if f is None: | |
28 | print '"%s"' % prefix | |
29 | continue | |
30 | f.stdin.write(line) | |
31 | ||
32 | for key in files.keys(): | |
33 | print 'Closing', key | |
34 | files[key].stdin.close() | |
35 | files[key].wait() | |
36 | print 'Done' |
0 | #!/usr/bin/env python | |
1 | ||
2 | import sys | |
3 | import csv | |
4 | import os | |
5 | ||
6 | def parse_file(f): | |
7 | c = csv.reader(f) | |
8 | for line in c: | |
9 | msg = line[0] | |
10 | if msg != '': continue | |
11 | if len(line) != 4: continue | |
12 | ||
13 | cdb = line[1] | |
14 | sense = line[2] | |
15 | data = line[3] | |
16 | ||
17 | print('Parsing CDB: %s' % cdb) | |
18 | print('Parsing Sense: %s' % sense) | |
19 | print('Parsing Data: %s' % data) | |
20 | sys.stdout.flush() | |
21 | sys.stderr.flush() | |
22 | os.system('../parse_scsi "%s" "%s" "%s"' % (cdb, sense, data)) | |
23 | sys.stdout.flush() | |
24 | sys.stderr.flush() | |
25 | print('=========================================================================\n') | |
26 | ||
27 | if len(sys.argv) > 1: | |
28 | for filename in sys.argv[1:]: | |
29 | print('Parsing file %s' % filename) | |
30 | f = file(filename, 'r') | |
31 | parse_file(f) | |
32 | print('Done') | |
33 | print('') | |
34 | else: | |
35 | parse_file(sys.stdin) |
15 | 15 | |
16 | 16 | #include "scsicmd.h" |
17 | 17 | #include "main.h" |
18 | #include "sense_dump.h" | |
19 | #include "parse_extended_inquiry.h" | |
18 | 20 | #include <stdio.h> |
19 | 21 | #include <memory.h> |
20 | 22 | #include <errno.h> |
24 | 26 | #include <fcntl.h> |
25 | 27 | #include <scsi/sg.h> |
26 | 28 | #include <inttypes.h> |
29 | #include <ctype.h> | |
27 | 30 | |
28 | void do_command(int fd) | |
31 | static void dump_evpd_ascii(unsigned char *data, uint16_t data_len) | |
32 | { | |
33 | const uint16_t ascii_len = (data[0] << 8) | data[1]; | |
34 | bool not_in_string = true; | |
35 | uint16_t i; | |
36 | ||
37 | printf("ASCII len: %u\n", ascii_len); | |
38 | printf("ASCII data: \""); | |
39 | for (i = 2; i < ascii_len + 2; i++) | |
40 | putchar(data[i]); | |
41 | printf("\"\n"); | |
42 | ||
43 | for (; i < data_len; i++) { | |
44 | if (isprint(data[i])) { | |
45 | if (not_in_string) { | |
46 | printf("Vendor string: \""); | |
47 | not_in_string = false; | |
48 | } | |
49 | putchar(data[i]); | |
50 | } else { | |
51 | if (!not_in_string) { | |
52 | printf("\"\n"); | |
53 | not_in_string = true; | |
54 | } | |
55 | } | |
56 | } | |
57 | if (!not_in_string) | |
58 | printf("\"\n"); | |
59 | } | |
60 | ||
61 | static void dump_evpd(int fd, uint8_t page) | |
29 | 62 | { |
30 | 63 | unsigned char cdb[32]; |
31 | 64 | unsigned char buf[512] ; |
32 | unsigned cdb_len = cdb_inquiry_simple(cdb, sizeof(buf)); | |
65 | unsigned cdb_len = cdb_inquiry(cdb, true, page, sizeof(buf)); | |
66 | ||
67 | printf("\n\nExtended Inquiry Page %u (%02x):\n", page, page); | |
68 | bool ret = submit_cmd(fd, cdb, cdb_len, buf, sizeof(buf), SG_DXFER_FROM_DEV); | |
69 | if (!ret) { | |
70 | fprintf(stderr, "Failed to submit command\n"); | |
71 | return; | |
72 | } | |
73 | ||
74 | unsigned char *sense = NULL; | |
75 | unsigned sense_len = 0; | |
76 | unsigned buf_len = 0; | |
77 | ret = read_response_buf(fd, &sense, &sense_len, &buf_len); | |
78 | ||
79 | if (sense) { | |
80 | printf("error while reading response buffer, nothing to show\n"); | |
81 | return; | |
82 | } | |
83 | ||
84 | printf("Read %u bytes\n", buf_len); | |
85 | ||
86 | response_dump(buf, buf_len); | |
87 | ||
88 | if (buf_len < EVPD_MIN_LEN) { | |
89 | printf("Buffer returned is too small, got %d expected minimum of %d", buf_len, EVPD_MIN_LEN); | |
90 | return; | |
91 | } | |
92 | ||
93 | if (page >= 0x01 && page <= 0x7F) { | |
94 | dump_evpd_ascii(evpd_page_data(buf), evpd_page_len(buf)); | |
95 | } | |
96 | } | |
97 | ||
98 | static void do_extended_inquiry(int fd) | |
99 | { | |
100 | unsigned char cdb[32]; | |
101 | unsigned char buf[512] ; | |
102 | unsigned cdb_len = cdb_inquiry(cdb, true, 0, sizeof(buf)); | |
103 | ||
104 | printf("\n\nExtended Inquiry:\n"); | |
105 | bool ret = submit_cmd(fd, cdb, cdb_len, buf, sizeof(buf), SG_DXFER_FROM_DEV); | |
106 | if (!ret) { | |
107 | fprintf(stderr, "Failed to submit command\n"); | |
108 | return; | |
109 | } | |
110 | ||
111 | unsigned char *sense = NULL; | |
112 | unsigned sense_len = 0; | |
113 | unsigned buf_len = 0; | |
114 | ret = read_response_buf(fd, &sense, &sense_len, &buf_len); | |
115 | ||
116 | if (sense) { | |
117 | printf("error while reading response buffer, nothing to show\n"); | |
118 | return; | |
119 | } | |
120 | ||
121 | printf("Read %u bytes\n", buf_len); | |
122 | ||
123 | response_dump(buf, buf_len); | |
124 | ||
125 | if (buf_len < EVPD_MIN_LEN) { | |
126 | printf("Buffer returned is too small, got %d expected minimum of %d", buf_len, EVPD_MIN_LEN); | |
127 | return; | |
128 | } | |
129 | ||
130 | printf("Peripheral Qualifier: %u\n", evpd_peripheral_qualifier(buf)); | |
131 | printf("Peripheral Device Type: %u\n", evpd_peripheral_device_type(buf)); | |
132 | ||
133 | uint16_t max_page_idx = evpd_page_len(buf) + 4; | |
134 | uint16_t i; | |
135 | for (i = 4; i < max_page_idx; i++) | |
136 | dump_evpd(fd, buf[i]); | |
137 | } | |
138 | ||
139 | static void do_simple_inquiry(int fd) | |
140 | { | |
141 | unsigned char cdb[32]; | |
142 | unsigned char buf[512] ; | |
143 | unsigned cdb_len = cdb_inquiry_simple(cdb, 96); | |
33 | 144 | |
34 | 145 | bool ret = submit_cmd(fd, cdb, cdb_len, buf, sizeof(buf), SG_DXFER_FROM_DEV); |
35 | 146 | if (!ret) { |
48 | 159 | } |
49 | 160 | |
50 | 161 | printf("Read %u bytes\n", buf_len); |
162 | response_dump(buf, buf_len); | |
51 | 163 | |
52 | 164 | int device_type; |
53 | 165 | scsi_vendor_t vendor; |
66 | 178 | printf("Rev: %s\n", rev); |
67 | 179 | printf("Serial: %s\n", serial); |
68 | 180 | } |
181 | ||
182 | void do_command(int fd) | |
183 | { | |
184 | do_simple_inquiry(fd); | |
185 | do_extended_inquiry(fd); | |
186 | } |
14 | 14 | */ |
15 | 15 | |
16 | 16 | #include "scsicmd.h" |
17 | #include "scsicmd_utils.h" | |
18 | ||
17 | 19 | #include "main.h" |
20 | #include "sense_dump.h" | |
18 | 21 | #include <stdio.h> |
19 | 22 | #include <memory.h> |
20 | 23 | #include <errno.h> |
24 | 27 | #include <fcntl.h> |
25 | 28 | #include <scsi/sg.h> |
26 | 29 | #include <inttypes.h> |
27 | ||
28 | static inline uint16_t get_uint16(unsigned char *buf, int start) | |
29 | { | |
30 | return (uint16_t)buf[start] << 8 | | |
31 | (uint16_t)buf[start+1]; | |
32 | } | |
33 | 30 | |
34 | 31 | static void dump_page(int fd, uint8_t page, uint8_t subpage) |
35 | 32 | { |
0 | /* Copyright 2014 Baruch Even | |
1 | * | |
2 | * Licensed under the Apache License, Version 2.0 (the "License"); | |
3 | * you may not use this file except in compliance with the License. | |
4 | * You may obtain a copy of the License at | |
5 | * | |
6 | * http://www.apache.org/licenses/LICENSE-2.0 | |
7 | * | |
8 | * Unless required by applicable law or agreed to in writing, software | |
9 | * distributed under the License is distributed on an "AS IS" BASIS, | |
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
11 | * See the License for the specific language governing permissions and | |
12 | * limitations under the License. | |
13 | * | |
14 | */ | |
15 | ||
16 | #include "scsicmd.h" | |
17 | #include "main.h" | |
18 | #include "sense_dump.h" | |
19 | #include "parse_mode_sense.h" | |
20 | #include <stdio.h> | |
21 | #include <memory.h> | |
22 | #include <errno.h> | |
23 | #include <unistd.h> | |
24 | #include <sys/types.h> | |
25 | #include <sys/stat.h> | |
26 | #include <fcntl.h> | |
27 | #include <scsi/sg.h> | |
28 | #include <inttypes.h> | |
29 | ||
30 | void do_command(int fd) | |
31 | { | |
32 | unsigned char cdb[32]; | |
33 | unsigned char buf[4096]; | |
34 | unsigned cdb_len = cdb_mode_sense_10(cdb, true, false, PAGE_CONTROL_CURRENT, 0x3F, 0xFF, sizeof(buf)); | |
35 | ||
36 | memset(buf, 0, sizeof(buf)); | |
37 | printf("List all supported pages\n"); | |
38 | bool ret = submit_cmd(fd, cdb, cdb_len, buf, sizeof(buf), SG_DXFER_FROM_DEV); | |
39 | if (!ret) { | |
40 | fprintf(stderr, "Failed to submit command\n"); | |
41 | return; | |
42 | } | |
43 | ||
44 | unsigned char *sense = NULL; | |
45 | unsigned sense_len = 0; | |
46 | unsigned buf_len = 0; | |
47 | ret = read_response_buf(fd, &sense, &sense_len, &buf_len); | |
48 | ||
49 | if (sense) { | |
50 | printf("error while reading response buffer, nothing to show\n"); | |
51 | return; | |
52 | } | |
53 | ||
54 | printf("Read %u bytes\n", buf_len); | |
55 | response_dump(buf, buf_len); | |
56 | ||
57 | if (buf_len < MODE_SENSE_10_MIN_LEN) { | |
58 | printf("Returned data is too short, expected a minimum of %u bytes and got only %u\n", MODE_SENSE_10_MIN_LEN, buf_len); | |
59 | return; | |
60 | } | |
61 | ||
62 | printf("Mode data len: %u\n", mode_sense_10_data_len(buf)); | |
63 | printf("Medium Type: %u\n", mode_sense_10_medium_type(buf)); | |
64 | printf("Device specific param: %u\n", mode_sense_10_device_specific_param(buf)); | |
65 | printf("Long LBA: %s\n", mode_sense_10_long_lba(buf) ? "yes" : "no"); | |
66 | printf("Block Descriptor length: %u\n", mode_sense_10_block_descriptor_length(buf)); | |
67 | ||
68 | if (buf_len < MODE_SENSE_10_MIN_LEN + mode_sense_10_block_descriptor_length(buf)) | |
69 | { | |
70 | printf("Not enough data for the block descriptor length\n"); | |
71 | return; | |
72 | } | |
73 | ||
74 | if (mode_sense_10_long_lba(buf)) { | |
75 | printf("Don't know how to parse the block descriptor for a long lba yet\n"); | |
76 | } else { | |
77 | uint8_t *bdb = mode_sense_10_block_descriptor_data(buf); | |
78 | ||
79 | putchar('\n'); | |
80 | printf("Density code: %u\n", block_descriptor_density_code(bdb)); | |
81 | printf("Num blocks: %u\n", block_descriptor_num_blocks(bdb)); | |
82 | printf("Block length: %u\n", block_descriptor_block_length(bdb)); | |
83 | } | |
84 | ||
85 | if (buf_len < MODE_SENSE_10_MIN_LEN + mode_sense_10_block_descriptor_length(buf) + mode_sense_10_data_len(buf)) | |
86 | { | |
87 | printf("Not enough data for the mode data length\n"); | |
88 | return; | |
89 | } | |
90 | ||
91 | putchar('\n'); | |
92 | //uint8_t *mode_data = mode_sense_10_mode_data(buf); | |
93 | ||
94 | } |
0 | /* Copyright 2014 Baruch Even | |
1 | * | |
2 | * Licensed under the Apache License, Version 2.0 (the "License"); | |
3 | * you may not use this file except in compliance with the License. | |
4 | * You may obtain a copy of the License at | |
5 | * | |
6 | * http://www.apache.org/licenses/LICENSE-2.0 | |
7 | * | |
8 | * Unless required by applicable law or agreed to in writing, software | |
9 | * distributed under the License is distributed on an "AS IS" BASIS, | |
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
11 | * See the License for the specific language governing permissions and | |
12 | * limitations under the License. | |
13 | * | |
14 | */ | |
15 | ||
16 | #include "scsicmd.h" | |
17 | #include "parse_receive_diagnostics.h" | |
18 | #include "main.h" | |
19 | #include "sense_dump.h" | |
20 | ||
21 | #include <stdio.h> | |
22 | #include <memory.h> | |
23 | #include <errno.h> | |
24 | #include <unistd.h> | |
25 | #include <sys/types.h> | |
26 | #include <sys/stat.h> | |
27 | #include <fcntl.h> | |
28 | #include <scsi/sg.h> | |
29 | #include <inttypes.h> | |
30 | ||
31 | static void dump_page(int fd, uint8_t page) | |
32 | { | |
33 | unsigned char cdb[32]; | |
34 | unsigned char buf[16*1024]; | |
35 | unsigned cdb_len = cdb_receive_diagnostics(cdb, true, page, sizeof(buf)); | |
36 | ||
37 | printf("List page %02X\n", page); | |
38 | bool ret = submit_cmd(fd, cdb, cdb_len, buf, sizeof(buf), SG_DXFER_FROM_DEV); | |
39 | if (!ret) { | |
40 | fprintf(stderr, "Failed to submit command\n"); | |
41 | return; | |
42 | } | |
43 | ||
44 | unsigned char *sense = NULL; | |
45 | unsigned sense_len = 0; | |
46 | unsigned buf_len = 0; | |
47 | ret = read_response_buf(fd, &sense, &sense_len, &buf_len); | |
48 | ||
49 | if (sense) { | |
50 | printf("error while reading response buffer, nothing to show\n"); | |
51 | return; | |
52 | } | |
53 | ||
54 | printf("Read %u bytes\n", buf_len); | |
55 | response_dump(buf, buf_len); | |
56 | printf("\n"); | |
57 | } | |
58 | ||
59 | void do_command(int fd) | |
60 | { | |
61 | unsigned char cdb[32]; | |
62 | unsigned char buf[16*1024]; | |
63 | unsigned cdb_len = cdb_receive_diagnostics(cdb, true, 0, sizeof(buf)); | |
64 | ||
65 | printf("List all supported pages\n"); | |
66 | bool ret = submit_cmd(fd, cdb, cdb_len, buf, sizeof(buf), SG_DXFER_FROM_DEV); | |
67 | if (!ret) { | |
68 | fprintf(stderr, "Failed to submit command\n"); | |
69 | return; | |
70 | } | |
71 | ||
72 | unsigned char *sense = NULL; | |
73 | unsigned sense_len = 0; | |
74 | unsigned buf_len = 0; | |
75 | ret = read_response_buf(fd, &sense, &sense_len, &buf_len); | |
76 | ||
77 | if (sense) { | |
78 | printf("error while reading response buffer, nothing to show\n"); | |
79 | return; | |
80 | } | |
81 | ||
82 | printf("Read %u bytes\n", buf_len); | |
83 | response_dump(buf, buf_len); | |
84 | ||
85 | if (buf_len < RECV_DIAG_MIN_LEN) { | |
86 | printf("receive diagnostics list must have at least 4 bytes\n"); | |
87 | return; | |
88 | } | |
89 | ||
90 | if (recv_diag_get_page_code(buf) != 0) { | |
91 | printf("expected to receive receive diagnostics page 0\n"); | |
92 | return; | |
93 | } | |
94 | ||
95 | uint16_t num_pages = recv_diag_get_len(buf); | |
96 | uint16_t i; | |
97 | for (i = 0; i < num_pages; i++) { | |
98 | dump_page(fd, buf[4 + i]); | |
99 | } | |
100 | } |
1 | 1 | #include "scsicmd.h" |
2 | 2 | #include <stdio.h> |
3 | 3 | #include <inttypes.h> |
4 | ||
5 | void cdb_dump(unsigned char *cdb, int cdb_len) | |
6 | { | |
7 | int i; | |
8 | ||
9 | printf("CDB: "); | |
10 | for (i = 0; i < cdb_len; i++) { | |
11 | printf("%02x ", cdb[i]); | |
12 | } | |
13 | printf("\n"); | |
14 | } | |
4 | 15 | |
5 | 16 | void response_dump(unsigned char *buf, int buf_len) |
6 | 17 | { |