1 /* 2 * USB descriptor handling functions for libusb 3 * Copyright (C) 2007 Daniel Drake <dsd (at) gentoo.org> 4 * Copyright (c) 2001 Johannes Erdfelt <johannes (at) erdfelt.com> 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 */ 20 21 #include <errno.h> 22 #include <stdint.h> 23 #include <stdlib.h> 24 #include <string.h> 25 26 #include "libusbi.h" 27 28 #define DESC_HEADER_LENGTH 2 29 #define DEVICE_DESC_LENGTH 18 30 #define CONFIG_DESC_LENGTH 9 31 #define INTERFACE_DESC_LENGTH 9 32 #define ENDPOINT_DESC_LENGTH 7 33 #define ENDPOINT_AUDIO_DESC_LENGTH 9 34 35 /** @defgroup desc USB descriptors 36 * This page details how to examine the various standard USB descriptors 37 * for detected devices 38 */ 39 40 /* set host_endian if the w values are already in host endian format, 41 * as opposed to bus endian. */ 42 int usbi_parse_descriptor(unsigned char *source, const char *descriptor, 43 void *dest, int host_endian) 44 { 45 unsigned char *sp = source, *dp = dest; 46 uint16_t w; 47 const char *cp; 48 49 for (cp = descriptor; *cp; cp++) { 50 switch (*cp) { 51 case 'b': /* 8-bit byte */ 52 *dp++ = *sp++; 53 break; 54 case 'w': /* 16-bit word, convert from little endian to CPU */ 55 dp += ((uintptr_t)dp & 1); /* Align to word boundary */ 56 57 if (host_endian) { 58 memcpy(dp, sp, 2); 59 } else { 60 w = (sp[1] << 8) | sp[0]; 61 *((uint16_t *)dp) = w; 62 } 63 sp += 2; 64 dp += 2; 65 break; 66 } 67 } 68 69 return (int) (sp - source); 70 } 71 72 static void clear_endpoint(struct libusb_endpoint_descriptor *endpoint) 73 { 74 if (endpoint->extra) 75 free((unsigned char *) endpoint->extra); 76 } 77 78 static int parse_endpoint(struct libusb_context *ctx, 79 struct libusb_endpoint_descriptor *endpoint, unsigned char *buffer, 80 int size, int host_endian) 81 { 82 struct usb_descriptor_header header; 83 unsigned char *extra; 84 unsigned char *begin; 85 int parsed = 0; 86 int len; 87 88 usbi_parse_descriptor(buffer, "bb", &header, 0); 89 90 /* Everything should be fine being passed into here, but we sanity */ 91 /* check JIC */ 92 if (header.bLength > size) { 93 usbi_err(ctx, "ran out of descriptors parsing"); 94 return -1; 95 } 96 97 if (header.bDescriptorType != LIBUSB_DT_ENDPOINT) { 98 usbi_err(ctx, "unexpected descriptor %x (expected %x)", 99 header.bDescriptorType, LIBUSB_DT_ENDPOINT); 100 return parsed; 101 } 102 103 if (header.bLength >= ENDPOINT_AUDIO_DESC_LENGTH) 104 usbi_parse_descriptor(buffer, "bbbbwbbb", endpoint, host_endian); 105 else if (header.bLength >= ENDPOINT_DESC_LENGTH) 106 usbi_parse_descriptor(buffer, "bbbbwb", endpoint, host_endian); 107 108 buffer += header.bLength; 109 size -= header.bLength; 110 parsed += header.bLength; 111 112 /* Skip over the rest of the Class Specific or Vendor Specific */ 113 /* descriptors */ 114 begin = buffer; 115 while (size >= DESC_HEADER_LENGTH) { 116 usbi_parse_descriptor(buffer, "bb", &header, 0); 117 118 if (header.bLength < 2) { 119 usbi_err(ctx, "invalid descriptor length %d", header.bLength); 120 return -1; 121 } 122 123 /* If we find another "proper" descriptor then we're done */ 124 if ((header.bDescriptorType == LIBUSB_DT_ENDPOINT) || 125 (header.bDescriptorType == LIBUSB_DT_INTERFACE) || 126 (header.bDescriptorType == LIBUSB_DT_CONFIG) || 127 (header.bDescriptorType == LIBUSB_DT_DEVICE)) 128 break; 129 130 usbi_dbg("skipping descriptor %x", header.bDescriptorType); 131 buffer += header.bLength; 132 size -= header.bLength; 133 parsed += header.bLength; 134 } 135 136 /* Copy any unknown descriptors into a storage area for drivers */ 137 /* to later parse */ 138 len = (int)(buffer - begin); 139 if (!len) { 140 endpoint->extra = NULL; 141 endpoint->extra_length = 0; 142 return parsed; 143 } 144 145 extra = malloc(len); 146 endpoint->extra = extra; 147 if (!extra) { 148 endpoint->extra_length = 0; 149 return LIBUSB_ERROR_NO_MEM; 150 } 151 152 memcpy(extra, begin, len); 153 endpoint->extra_length = len; 154 155 return parsed; 156 } 157 158 static void clear_interface(struct libusb_interface *usb_interface) 159 { 160 int i; 161 int j; 162 163 if (usb_interface->altsetting) { 164 for (i = 0; i < usb_interface->num_altsetting; i++) { 165 struct libusb_interface_descriptor *ifp = 166 (struct libusb_interface_descriptor *) 167 usb_interface->altsetting + i; 168 if (ifp->extra) 169 free((void *) ifp->extra); 170 if (ifp->endpoint) { 171 for (j = 0; j < ifp->bNumEndpoints; j++) 172 clear_endpoint((struct libusb_endpoint_descriptor *) 173 ifp->endpoint + j); 174 free((void *) ifp->endpoint); 175 } 176 } 177 free((void *) usb_interface->altsetting); 178 usb_interface->altsetting = NULL; 179 } 180 181 } 182 183 static int parse_interface(libusb_context *ctx, 184 struct libusb_interface *usb_interface, unsigned char *buffer, int size, 185 int host_endian) 186 { 187 int i; 188 int len; 189 int r; 190 int parsed = 0; 191 size_t tmp; 192 struct usb_descriptor_header header; 193 struct libusb_interface_descriptor *ifp; 194 unsigned char *begin; 195 196 usb_interface->num_altsetting = 0; 197 198 while (size >= INTERFACE_DESC_LENGTH) { 199 struct libusb_interface_descriptor *altsetting = 200 (struct libusb_interface_descriptor *) usb_interface->altsetting; 201 altsetting = realloc(altsetting, 202 sizeof(struct libusb_interface_descriptor) * 203 (usb_interface->num_altsetting + 1)); 204 if (!altsetting) { 205 r = LIBUSB_ERROR_NO_MEM; 206 goto err; 207 } 208 usb_interface->altsetting = altsetting; 209 210 ifp = altsetting + usb_interface->num_altsetting; 211 usb_interface->num_altsetting++; 212 usbi_parse_descriptor(buffer, "bbbbbbbbb", ifp, 0); 213 ifp->extra = NULL; 214 ifp->extra_length = 0; 215 ifp->endpoint = NULL; 216 217 /* Skip over the interface */ 218 buffer += ifp->bLength; 219 parsed += ifp->bLength; 220 size -= ifp->bLength; 221 222 begin = buffer; 223 224 /* Skip over any interface, class or vendor descriptors */ 225 while (size >= DESC_HEADER_LENGTH) { 226 usbi_parse_descriptor(buffer, "bb", &header, 0); 227 if (header.bLength < 2) { 228 usbi_err(ctx, "invalid descriptor of length %d", 229 header.bLength); 230 r = LIBUSB_ERROR_IO; 231 goto err; 232 } 233 234 /* If we find another "proper" descriptor then we're done */ 235 if ((header.bDescriptorType == LIBUSB_DT_INTERFACE) || 236 (header.bDescriptorType == LIBUSB_DT_ENDPOINT) || 237 (header.bDescriptorType == LIBUSB_DT_CONFIG) || 238 (header.bDescriptorType == LIBUSB_DT_DEVICE)) 239 break; 240 241 buffer += header.bLength; 242 parsed += header.bLength; 243 size -= header.bLength; 244 } 245 246 /* Copy any unknown descriptors into a storage area for */ 247 /* drivers to later parse */ 248 len = (int)(buffer - begin); 249 if (len) { 250 ifp->extra = malloc(len); 251 if (!ifp->extra) { 252 r = LIBUSB_ERROR_NO_MEM; 253 goto err; 254 } 255 memcpy((unsigned char *) ifp->extra, begin, len); 256 ifp->extra_length = len; 257 } 258 259 /* Did we hit an unexpected descriptor? */ 260 if (size >= DESC_HEADER_LENGTH) { 261 usbi_parse_descriptor(buffer, "bb", &header, 0); 262 if ((header.bDescriptorType == LIBUSB_DT_CONFIG) || 263 (header.bDescriptorType == LIBUSB_DT_DEVICE)) { 264 return parsed; 265 } 266 } 267 268 if (ifp->bNumEndpoints > USB_MAXENDPOINTS) { 269 usbi_err(ctx, "too many endpoints (%d)", ifp->bNumEndpoints); 270 r = LIBUSB_ERROR_IO; 271 goto err; 272 } 273 274 if (ifp->bNumEndpoints > 0) { 275 struct libusb_endpoint_descriptor *endpoint; 276 tmp = ifp->bNumEndpoints * sizeof(struct libusb_endpoint_descriptor); 277 endpoint = malloc(tmp); 278 ifp->endpoint = endpoint; 279 if (!endpoint) { 280 r = LIBUSB_ERROR_NO_MEM; 281 goto err; 282 } 283 284 memset(endpoint, 0, tmp); 285 for (i = 0; i < ifp->bNumEndpoints; i++) { 286 usbi_parse_descriptor(buffer, "bb", &header, 0); 287 288 if (header.bLength > size) { 289 usbi_err(ctx, "ran out of descriptors parsing"); 290 r = LIBUSB_ERROR_IO; 291 goto err; 292 } 293 294 r = parse_endpoint(ctx, endpoint + i, buffer, size, 295 host_endian); 296 if (r < 0) 297 goto err; 298 299 buffer += r; 300 parsed += r; 301 size -= r; 302 } 303 } 304 305 /* We check to see if it's an alternate to this one */ 306 ifp = (struct libusb_interface_descriptor *) buffer; 307 if (size < LIBUSB_DT_INTERFACE_SIZE || 308 ifp->bDescriptorType != LIBUSB_DT_INTERFACE || 309 !ifp->bAlternateSetting) 310 return parsed; 311 } 312 313 return parsed; 314 err: 315 clear_interface(usb_interface); 316 return r; 317 } 318 319 static void clear_configuration(struct libusb_config_descriptor *config) 320 { 321 if (config->interface) { 322 int i; 323 for (i = 0; i < config->bNumInterfaces; i++) 324 clear_interface((struct libusb_interface *) 325 config->interface + i); 326 free((void *) config->interface); 327 } 328 if (config->extra) 329 free((void *) config->extra); 330 } 331 332 static int parse_configuration(struct libusb_context *ctx, 333 struct libusb_config_descriptor *config, unsigned char *buffer, 334 int host_endian) 335 { 336 int i; 337 int r; 338 int size; 339 size_t tmp; 340 struct usb_descriptor_header header; 341 struct libusb_interface *usb_interface; 342 343 usbi_parse_descriptor(buffer, "bbwbbbbb", config, host_endian); 344 size = config->wTotalLength; 345 346 if (config->bNumInterfaces > USB_MAXINTERFACES) { 347 usbi_err(ctx, "too many interfaces (%d)", config->bNumInterfaces); 348 return LIBUSB_ERROR_IO; 349 } 350 351 tmp = config->bNumInterfaces * sizeof(struct libusb_interface); 352 usb_interface = malloc(tmp); 353 config->interface = usb_interface; 354 if (!config->interface) 355 return LIBUSB_ERROR_NO_MEM; 356 357 memset(usb_interface, 0, tmp); 358 buffer += config->bLength; 359 size -= config->bLength; 360 361 config->extra = NULL; 362 config->extra_length = 0; 363 364 for (i = 0; i < config->bNumInterfaces; i++) { 365 int len; 366 unsigned char *begin; 367 368 /* Skip over the rest of the Class Specific or Vendor */ 369 /* Specific descriptors */ 370 begin = buffer; 371 while (size >= DESC_HEADER_LENGTH) { 372 usbi_parse_descriptor(buffer, "bb", &header, 0); 373 374 if ((header.bLength > size) || 375 (header.bLength < DESC_HEADER_LENGTH)) { 376 usbi_err(ctx, "invalid descriptor length of %d", 377 header.bLength); 378 r = LIBUSB_ERROR_IO; 379 goto err; 380 } 381 382 /* If we find another "proper" descriptor then we're done */ 383 if ((header.bDescriptorType == LIBUSB_DT_ENDPOINT) || 384 (header.bDescriptorType == LIBUSB_DT_INTERFACE) || 385 (header.bDescriptorType == LIBUSB_DT_CONFIG) || 386 (header.bDescriptorType == LIBUSB_DT_DEVICE)) 387 break; 388 389 usbi_dbg("skipping descriptor 0x%x\n", header.bDescriptorType); 390 buffer += header.bLength; 391 size -= header.bLength; 392 } 393 394 /* Copy any unknown descriptors into a storage area for */ 395 /* drivers to later parse */ 396 len = (int)(buffer - begin); 397 if (len) { 398 /* FIXME: We should realloc and append here */ 399 if (!config->extra_length) { 400 config->extra = malloc(len); 401 if (!config->extra) { 402 r = LIBUSB_ERROR_NO_MEM; 403 goto err; 404 } 405 406 memcpy((unsigned char *) config->extra, begin, len); 407 config->extra_length = len; 408 } 409 } 410 411 r = parse_interface(ctx, usb_interface + i, buffer, size, host_endian); 412 if (r < 0) 413 goto err; 414 415 buffer += r; 416 size -= r; 417 } 418 419 return size; 420 421 err: 422 clear_configuration(config); 423 return r; 424 } 425 426 /** \ingroup desc 427 * Get the USB device descriptor for a given device. 428 * 429 * This is a non-blocking function; the device descriptor is cached in memory. 430 * 431 * \param dev the device 432 * \param desc output location for the descriptor data 433 * \returns 0 on success or a LIBUSB_ERROR code on failure 434 */ 435 int API_EXPORTED libusb_get_device_descriptor(libusb_device *dev, 436 struct libusb_device_descriptor *desc) 437 { 438 unsigned char raw_desc[DEVICE_DESC_LENGTH]; 439 int host_endian = 0; 440 int r; 441 442 usbi_dbg(""); 443 r = usbi_backend->get_device_descriptor(dev, raw_desc, &host_endian); 444 if (r < 0) 445 return r; 446 447 memcpy((unsigned char *) desc, raw_desc, sizeof(raw_desc)); 448 if (!host_endian) { 449 desc->bcdUSB = libusb_le16_to_cpu(desc->bcdUSB); 450 desc->idVendor = libusb_le16_to_cpu(desc->idVendor); 451 desc->idProduct = libusb_le16_to_cpu(desc->idProduct); 452 desc->bcdDevice = libusb_le16_to_cpu(desc->bcdDevice); 453 } 454 return 0; 455 } 456 457 /** \ingroup desc 458 * Get the USB configuration descriptor for the currently active configuration. 459 * This is a non-blocking function which does not involve any requests being 460 * sent to the device. 461 * 462 * \param dev a device 463 * \param config output location for the USB configuration descriptor. Only 464 * valid if 0 was returned. Must be freed with libusb_free_config_descriptor() 465 * after use. 466 * \returns 0 on success 467 * \returns LIBUSB_ERROR_NOT_FOUND if the device is in unconfigured state 468 * \returns another LIBUSB_ERROR code on error 469 * \see libusb_get_config_descriptor 470 */ 471 int API_EXPORTED libusb_get_active_config_descriptor(libusb_device *dev, 472 struct libusb_config_descriptor **config) 473 { 474 struct libusb_config_descriptor *_config = malloc(sizeof(*_config)); 475 unsigned char tmp[8]; 476 unsigned char *buf = NULL; 477 int host_endian = 0; 478 int r; 479 480 usbi_dbg(""); 481 if (!_config) 482 return LIBUSB_ERROR_NO_MEM; 483 484 r = usbi_backend->get_active_config_descriptor(dev, tmp, sizeof(tmp), 485 &host_endian); 486 if (r < 0) 487 goto err; 488 489 usbi_parse_descriptor(tmp, "bbw", _config, host_endian); 490 buf = malloc(_config->wTotalLength); 491 if (!buf) { 492 r = LIBUSB_ERROR_NO_MEM; 493 goto err; 494 } 495 496 r = usbi_backend->get_active_config_descriptor(dev, buf, 497 _config->wTotalLength, &host_endian); 498 if (r < 0) 499 goto err; 500 501 r = parse_configuration(dev->ctx, _config, buf, host_endian); 502 if (r < 0) { 503 usbi_err(dev->ctx, "parse_configuration failed with error %d", r); 504 goto err; 505 } else if (r > 0) { 506 usbi_warn(dev->ctx, "descriptor data still left"); 507 } 508 509 free(buf); 510 *config = _config; 511 return 0; 512 513 err: 514 free(_config); 515 if (buf) 516 free(buf); 517 return r; 518 } 519 520 /** \ingroup desc 521 * Get a USB configuration descriptor based on its index. 522 * This is a non-blocking function which does not involve any requests being 523 * sent to the device. 524 * 525 * \param dev a device 526 * \param config_index the index of the configuration you wish to retrieve 527 * \param config output location for the USB configuration descriptor. Only 528 * valid if 0 was returned. Must be freed with libusb_free_config_descriptor() 529 * after use. 530 * \returns 0 on success 531 * \returns LIBUSB_ERROR_NOT_FOUND if the configuration does not exist 532 * \returns another LIBUSB_ERROR code on error 533 * \see libusb_get_active_config_descriptor() 534 * \see libusb_get_config_descriptor_by_value() 535 */ 536 int API_EXPORTED libusb_get_config_descriptor(libusb_device *dev, 537 uint8_t config_index, struct libusb_config_descriptor **config) 538 { 539 struct libusb_config_descriptor *_config; 540 unsigned char tmp[8]; 541 unsigned char *buf = NULL; 542 int host_endian = 0; 543 int r; 544 545 usbi_dbg("index %d", config_index); 546 if (config_index >= dev->num_configurations) 547 return LIBUSB_ERROR_NOT_FOUND; 548 549 _config = malloc(sizeof(*_config)); 550 if (!_config) 551 return LIBUSB_ERROR_NO_MEM; 552 553 r = usbi_backend->get_config_descriptor(dev, config_index, tmp, 554 sizeof(tmp), &host_endian); 555 if (r < 0) 556 goto err; 557 558 usbi_parse_descriptor(tmp, "bbw", _config, host_endian); 559 buf = malloc(_config->wTotalLength); 560 if (!buf) { 561 r = LIBUSB_ERROR_NO_MEM; 562 goto err; 563 } 564 565 host_endian = 0; 566 r = usbi_backend->get_config_descriptor(dev, config_index, buf, 567 _config->wTotalLength, &host_endian); 568 if (r < 0) 569 goto err; 570 571 r = parse_configuration(dev->ctx, _config, buf, host_endian); 572 if (r < 0) { 573 usbi_err(dev->ctx, "parse_configuration failed with error %d", r); 574 goto err; 575 } else if (r > 0) { 576 usbi_warn(dev->ctx, "descriptor data still left"); 577 } 578 579 free(buf); 580 *config = _config; 581 return 0; 582 583 err: 584 free(_config); 585 if (buf) 586 free(buf); 587 return r; 588 } 589 590 /* iterate through all configurations, returning the index of the configuration 591 * matching a specific bConfigurationValue in the idx output parameter, or -1 592 * if the config was not found. 593 * returns 0 or a LIBUSB_ERROR code 594 */ 595 int usbi_get_config_index_by_value(struct libusb_device *dev, 596 uint8_t bConfigurationValue, int *idx) 597 { 598 uint8_t i; 599 600 usbi_dbg("value %d", bConfigurationValue); 601 for (i = 0; i < dev->num_configurations; i++) { 602 unsigned char tmp[6]; 603 int host_endian; 604 int r = usbi_backend->get_config_descriptor(dev, i, tmp, sizeof(tmp), 605 &host_endian); 606 if (r < 0) 607 return r; 608 if (tmp[5] == bConfigurationValue) { 609 *idx = i; 610 return 0; 611 } 612 } 613 614 *idx = -1; 615 return 0; 616 } 617 618 /** \ingroup desc 619 * Get a USB configuration descriptor with a specific bConfigurationValue. 620 * This is a non-blocking function which does not involve any requests being 621 * sent to the device. 622 * 623 * \param dev a device 624 * \param bConfigurationValue the bConfigurationValue of the configuration you 625 * wish to retrieve 626 * \param config output location for the USB configuration descriptor. Only 627 * valid if 0 was returned. Must be freed with libusb_free_config_descriptor() 628 * after use. 629 * \returns 0 on success 630 * \returns LIBUSB_ERROR_NOT_FOUND if the configuration does not exist 631 * \returns another LIBUSB_ERROR code on error 632 * \see libusb_get_active_config_descriptor() 633 * \see libusb_get_config_descriptor() 634 */ 635 int API_EXPORTED libusb_get_config_descriptor_by_value(libusb_device *dev, 636 uint8_t bConfigurationValue, struct libusb_config_descriptor **config) 637 { 638 int idx; 639 int r = usbi_get_config_index_by_value(dev, bConfigurationValue, &idx); 640 if (r < 0) 641 return r; 642 else if (idx == -1) 643 return LIBUSB_ERROR_NOT_FOUND; 644 else 645 return libusb_get_config_descriptor(dev, (uint8_t) idx, config); 646 } 647 648 /** \ingroup desc 649 * Free a configuration descriptor obtained from 650 * libusb_get_active_config_descriptor() or libusb_get_config_descriptor(). 651 * It is safe to call this function with a NULL config parameter, in which 652 * case the function simply returns. 653 * 654 * \param config the configuration descriptor to free 655 */ 656 void API_EXPORTED libusb_free_config_descriptor( 657 struct libusb_config_descriptor *config) 658 { 659 if (!config) 660 return; 661 662 clear_configuration(config); 663 free(config); 664 } 665 666 /** \ingroup desc 667 * Retrieve a string descriptor in C style ASCII. 668 * 669 * Wrapper around libusb_get_string_descriptor(). Uses the first language 670 * supported by the device. 671 * 672 * \param dev a device handle 673 * \param desc_index the index of the descriptor to retrieve 674 * \param data output buffer for ASCII string descriptor 675 * \param length size of data buffer 676 * \returns number of bytes returned in data, or LIBUSB_ERROR code on failure 677 */ 678 int API_EXPORTED libusb_get_string_descriptor_ascii(libusb_device_handle *dev, 679 uint8_t desc_index, unsigned char *data, int length) 680 { 681 unsigned char tbuf[255]; /* Some devices choke on size > 255 */ 682 int r, si, di; 683 uint16_t langid; 684 685 /* Asking for the zero'th index is special - it returns a string 686 * descriptor that contains all the language IDs supported by the 687 * device. Typically there aren't many - often only one. Language 688 * IDs are 16 bit numbers, and they start at the third byte in the 689 * descriptor. There's also no point in trying to read descriptor 0 690 * with this function. See USB 2.0 specification section 9.6.7 for 691 * more information. 692 */ 693 694 if (desc_index == 0) 695 return LIBUSB_ERROR_INVALID_PARAM; 696 697 r = libusb_get_string_descriptor(dev, 0, 0, tbuf, sizeof(tbuf)); 698 if (r < 0) 699 return r; 700 701 if (r < 4) 702 return LIBUSB_ERROR_IO; 703 704 langid = tbuf[2] | (tbuf[3] << 8); 705 706 r = libusb_get_string_descriptor(dev, desc_index, langid, tbuf, 707 sizeof(tbuf)); 708 if (r < 0) 709 return r; 710 711 if (tbuf[1] != LIBUSB_DT_STRING) 712 return LIBUSB_ERROR_IO; 713 714 if (tbuf[0] > r) 715 return LIBUSB_ERROR_IO; 716 717 for (di = 0, si = 2; si < tbuf[0]; si += 2) { 718 if (di >= (length - 1)) 719 break; 720 721 if (tbuf[si + 1]) /* high byte */ 722 data[di++] = '?'; 723 else 724 data[di++] = tbuf[si]; 725 } 726 727 data[di] = 0; 728 return di; 729 } 730 731