root/drivers/isdn/teles/q931.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. findie
  2. iecpy
  3. getcallref
  4. prbits
  5. skipext
  6. prcause
  7. prchident
  8. prcalled
  9. prcalling
  10. prbearer
  11. general
  12. display
  13. prfacility
  14. hexdump
  15. dlogframe

   1 /* $Id: q931.c,v 1.2 1996/04/20 16:48:19 fritz Exp $
   2  *
   3  * q931.c               code to decode ITU Q.931 call control messages
   4  * 
   5  * Author               Jan den Ouden
   6  * 
   7  * Changelog
   8  * 
   9  * Pauline Middelink    general improvements
  10  * 
  11  * Beat Doebeli         cause texts, display information element
  12  * 
  13  * $Log: q931.c,v $
  14  * Revision 1.2  1996/04/20 16:48:19  fritz
  15  * Misc. typos
  16  *
  17  * Revision 1.1  1996/04/13 10:27:49  fritz
  18  * Initial revision
  19  *
  20  *
  21  */
  22 
  23 
  24 #define __NO_VERSION__
  25 #include "teles.h"
  26 
  27 byte           *
  28 findie(byte * p, int size, byte ie, int wanted_set)
     /* [previous][next][first][last][top][bottom][index][help] */
  29 {
  30         int             l, codeset, maincodeset;
  31         byte           *pend = p + size;
  32 
  33         /* skip protocol discriminator, callref and message type */
  34         p++;
  35         l = (*p++) & 0xf;
  36         p += l;
  37         p++;
  38         codeset = 0;
  39         maincodeset = 0;
  40         /* while there are bytes left... */
  41         while (p < pend) {
  42                 if ((*p & 0xf0) == 0x90) {
  43                         codeset = *p & 0x07;
  44                         if (!(*p & 0x08))
  45                                 maincodeset = codeset;
  46                 }
  47                 if (*p & 0x80)
  48                         p++;
  49                 else {
  50                         if (codeset == wanted_set) {
  51                                 if (*p == ie)
  52                                         return (p);
  53                                 if (*p > ie)
  54                                         return (NULL);
  55                         }
  56                         p++;
  57                         l = *p++;
  58                         p += l;
  59                         codeset = maincodeset;
  60                 }
  61         }
  62         return (NULL);
  63 }
  64 
  65 void
  66 iecpy(byte * dest, byte * iestart, int ieoffset)
     /* [previous][next][first][last][top][bottom][index][help] */
  67 {
  68         byte           *p;
  69         int             l;
  70 
  71         p = iestart + ieoffset + 2;
  72         l = iestart[1] - ieoffset;
  73         while (l--)
  74                 *dest++ = *p++;
  75         *dest++ = '\0';
  76 }
  77 
  78 int
  79 getcallref(byte * p)
     /* [previous][next][first][last][top][bottom][index][help] */
  80 {
  81         p++;                    /* prot discr */
  82         p++;                    /* callref length */
  83         return (*p);            /* assuming one-byte callref */
  84 }
  85 
  86 /*
  87  * According to Table 4-2/Q.931
  88  */
  89 static
  90 struct MessageType {
  91         byte            nr;
  92         char           *descr;
  93 } mtlist[] = {
  94 
  95         {
  96                 0x1, "ALERTING"
  97         },
  98         {
  99                 0x2, "CALL PROCEEDING"
 100         },
 101         {
 102                 0x7, "CONNECT"
 103         },
 104         {
 105                 0xf, "CONNECT ACKNOWLEDGE"
 106         },
 107         {
 108                 0x3, "PROGRESS"
 109         },
 110         {
 111                 0x5, "SETUP"
 112         },
 113         {
 114                 0xd, "SETUP ACKNOWLEDGE"
 115         },
 116         {
 117                 0x26, "RESUME"
 118         },
 119         {
 120                 0x2e, "RESUME ACKNOWLEDGE"
 121         },
 122         {
 123                 0x22, "RESUME REJECT"
 124         },
 125         {
 126                 0x25, "SUSPEND"
 127         },
 128         {
 129                 0x2d, "SUSPEND ACKNOWLEDGE"
 130         },
 131         {
 132                 0x21, "SUSPEND REJECT"
 133         },
 134         {
 135                 0x20, "USER INFORMATION"
 136         },
 137         {
 138                 0x45, "DISCONNECT"
 139         },
 140         {
 141                 0x4d, "RELEASE"
 142         },
 143         {
 144                 0x5a, "RELEASE COMPLETE"
 145         },
 146         {
 147                 0x46, "RESTART"
 148         },
 149         {
 150                 0x4e, "RESTART ACKNOWLEDGE"
 151         },
 152         {
 153                 0x60, "SEGMENT"
 154         },
 155         {
 156                 0x79, "CONGESTION CONTROL"
 157         },
 158         {
 159                 0x7b, "INFORMATION"
 160         },
 161         {
 162                 0x62, "FACILITY"
 163         },
 164         {
 165                 0x6e, "NOTIFY"
 166         },
 167         {
 168                 0x7d, "STATUS"
 169         },
 170         {
 171                 0x75, "STATUS ENQUIRY"
 172         }
 173 };
 174 
 175 #define MTSIZE sizeof(mtlist)/sizeof(struct MessageType)
 176 
 177 
 178 static
 179 int
 180 prbits(char *dest, byte b, int start, int len)
     /* [previous][next][first][last][top][bottom][index][help] */
 181 {
 182         char           *dp = dest;
 183 
 184         b = b << (8 - start);
 185         while (len--) {
 186                 if (b & 0x80)
 187                         *dp++ = '1';
 188                 else
 189                         *dp++ = '0';
 190                 b = b << 1;
 191         }
 192         return (dp - dest);
 193 }
 194 
 195 static
 196 byte           *
 197 skipext(byte * p)
     /* [previous][next][first][last][top][bottom][index][help] */
 198 {
 199         while (!(*p++ & 0x80));
 200         return (p);
 201 }
 202 
 203 /*
 204  * Cause Values According to Q.850
 205  * edescr: English description
 206  * ddescr: German description used by Swissnet II (Swiss Telecom
 207  *         not yet written...
 208  */
 209 
 210 static
 211 struct CauseValue {
 212         byte            nr;
 213         char           *edescr;
 214         char           *ddescr;
 215 } cvlist[] = {
 216 
 217         {
 218                 0x01, "Unallocated (unassigned) number", "Nummer nicht zugeteilt"
 219         },
 220         {
 221                 0x02, "No route to specified transit network", ""
 222         },
 223         {
 224                 0x03, "No route to destination", ""
 225         },
 226         {
 227                 0x04, "Send special information tone", ""
 228         },
 229         {
 230                 0x05, "Misdialled trunk prefix", ""
 231         },
 232         {
 233                 0x06, "Channel unacceptable", "Kanal nicht akzeptierbar"
 234         },
 235         {
 236                 0x07, "Channel awarded and being delivered in an established channel", ""
 237         },
 238         {
 239                 0x08, "Preemption", ""
 240         },
 241         {
 242                 0x09, "Preemption - circuit reserved for reuse", ""
 243         },
 244         {
 245                 0x10, "Normal call clearing", "Normale Ausloesung"
 246         },
 247         {
 248                 0x11, "User busy", "TNB besetzt"
 249         },
 250         {
 251                 0x12, "No user responding", ""
 252         },
 253         {
 254                 0x13, "No answer from user (user alerted)", ""
 255         },
 256         {
 257                 0x14, "Subscriber absent", ""
 258         },
 259         {
 260                 0x15, "Call rejected", ""
 261         },
 262         {
 263                 0x16, "Number changed", ""
 264         },
 265         {
 266                 0x1a, "non-selected user clearing", ""
 267         },
 268         {
 269                 0x1b, "Destination out of order", ""
 270         },
 271         {
 272                 0x1c, "Invalid number format (address incomplete)", ""
 273         },
 274         {
 275                 0x1d, "Facility rejected", ""
 276         },
 277         {
 278                 0x1e, "Response to Status enquiry", ""
 279         },
 280         {
 281                 0x1f, "Normal, unspecified", ""
 282         },
 283         {
 284                 0x22, "No circuit/channel available", ""
 285         },
 286         {
 287                 0x26, "Network out of order", ""
 288         },
 289         {
 290                 0x27, "Permanent frame mode connection out-of-service", ""
 291         },
 292         {
 293                 0x28, "Permanent frame mode connection operational", ""
 294         },
 295         {
 296                 0x29, "Temporary failure", ""
 297         },
 298         {
 299                 0x2a, "Switching equipment congestion", ""
 300         },
 301         {
 302                 0x2b, "Access information discarded", ""
 303         },
 304         {
 305                 0x2c, "Requested circuit/channel not available", ""
 306         },
 307         {
 308                 0x2e, "Precedence call blocked", ""
 309         },
 310         {
 311                 0x2f, "Resource unavailable, unspecified", ""
 312         },
 313         {
 314                 0x31, "Quality of service unavailable", ""
 315         },
 316         {
 317                 0x32, "Requested facility not subscribed", ""
 318         },
 319         {
 320                 0x35, "Outgoing calls barred within CUG", ""
 321         },
 322         {
 323                 0x37, "Incoming calls barred within CUG", ""
 324         },
 325         {
 326                 0x39, "Bearer capability not authorized", ""
 327         },
 328         {
 329                 0x3a, "Bearer capability not presently available", ""
 330         },
 331         {
 332                 0x3e, "Inconsistency in designated outgoing access information and subscriber class ", " "
 333         },
 334         {
 335                 0x3f, "Service or option not available, unspecified", ""
 336         },
 337         {
 338                 0x41, "Bearer capability not implemented", ""
 339         },
 340         {
 341                 0x42, "Channel type not implemented", ""
 342         },
 343         {
 344                 0x43, "Requested facility not implemented", ""
 345         },
 346         {
 347                 0x44, "Only restricted digital information bearer capability is available", ""
 348         },
 349         {
 350                 0x4f, "Service or option not implemented", ""
 351         },
 352         {
 353                 0x51, "Invalid call reference value", ""
 354         },
 355         {
 356                 0x52, "Identified channel does not exist", ""
 357         },
 358         {
 359                 0x53, "A suspended call exists, but this call identity does not", ""
 360         },
 361         {
 362                 0x54, "Call identity in use", ""
 363         },
 364         {
 365                 0x55, "No call suspended", ""
 366         },
 367         {
 368                 0x56, "Call having the requested call identity has been cleared", ""
 369         },
 370         {
 371                 0x57, "User not member of CUG", ""
 372         },
 373         {
 374                 0x58, "Incompatible destination", ""
 375         },
 376         {
 377                 0x5a, "Non-existent CUG", ""
 378         },
 379         {
 380                 0x5b, "Invalid transit network selection", ""
 381         },
 382         {
 383                 0x5f, "Invalid message, unspecified", ""
 384         },
 385         {
 386                 0x60, "Mandatory information element is missing", ""
 387         },
 388         {
 389                 0x61, "Message type non-existent or not implemented", ""
 390         },
 391         {
 392                 0x62, "Message not compatible with call state or message type non-existent or not implemented ", " "
 393         },
 394         {
 395                 0x63, "Information element/parameter non-existent or not implemented", ""
 396         },
 397         {
 398                 0x64, "Invalid information element contents", ""
 399         },
 400         {
 401                 0x65, "Message not compatible with call state", ""
 402         },
 403         {
 404                 0x66, "Recovery on timer expiry", ""
 405         },
 406         {
 407                 0x67, "Parameter non-existent or not implemented - passed on", ""
 408         },
 409         {
 410                 0x6e, "Message with unrecognized parameter discarded", ""
 411         },
 412         {
 413                 0x6f, "Protocol error, unspecified", ""
 414         },
 415         {
 416                 0x7f, "Interworking, unspecified", ""
 417         },
 418 };
 419 
 420 #define CVSIZE sizeof(cvlist)/sizeof(struct CauseValue)
 421 
 422 static
 423 int
 424 prcause(char *dest, byte * p)
     /* [previous][next][first][last][top][bottom][index][help] */
 425 {
 426         byte           *end;
 427         char           *dp = dest;
 428         int             i, cause;
 429 
 430         end = p + p[1] + 1;
 431         p += 2;
 432         dp += sprintf(dp, "    coding ");
 433         dp += prbits(dp, *p, 7, 2);
 434         dp += sprintf(dp, " location ");
 435         dp += prbits(dp, *p, 4, 4);
 436         *dp++ = '\n';
 437         p = skipext(p);
 438 
 439         cause = 0x7f & *p++;
 440 
 441         /* locate cause value */
 442         for (i = 0; i < CVSIZE; i++)
 443                 if (cvlist[i].nr == cause)
 444                         break;
 445 
 446         /* display cause value if it exists */
 447         if (i == CVSIZE)
 448                 dp += sprintf(dp, "Unknown cause type %x!\n", cause);
 449         else
 450                 dp += sprintf(dp, "  cause value %x : %s \n", cause, cvlist[i].edescr);
 451 
 452 
 453 #if 0
 454         dp += sprintf(dp,"    cause value ");
 455         dp += prbits(dp,*p++,7,7);
 456         *dp++ = '\n';
 457 #endif
 458         while (!0) {
 459                 if (p > end)
 460                         break;
 461                 dp += sprintf(dp, "    diag attribute %d ", *p++ & 0x7f);
 462                 dp += sprintf(dp, " rej %d ", *p & 0x7f);
 463                 if (*p & 0x80) {
 464                         *dp++ = '\n';
 465                         break;
 466                 } else
 467                         dp += sprintf(dp, " av %d\n", (*++p) & 0x7f);
 468         }
 469         return (dp - dest);
 470 
 471 }
 472 
 473 static
 474 int
 475 prchident(char *dest, byte * p)
     /* [previous][next][first][last][top][bottom][index][help] */
 476 {
 477         char           *dp = dest;
 478 
 479         p += 2;
 480         dp += sprintf(dp, "    octet 3 ");
 481         dp += prbits(dp, *p, 8, 8);
 482         *dp++ = '\n';
 483         return (dp - dest);
 484 }
 485 static
 486 int
 487 prcalled(char *dest, byte * p)
     /* [previous][next][first][last][top][bottom][index][help] */
 488 {
 489         int             l;
 490         char           *dp = dest;
 491 
 492         p++;
 493         l = *p++ - 1;
 494         dp += sprintf(dp, "    octet 3 ");
 495         dp += prbits(dp, *p++, 8, 8);
 496         *dp++ = '\n';
 497         dp += sprintf(dp, "    number digits ");
 498         while (l--)
 499                 *dp++ = *p++;
 500         *dp++ = '\n';
 501         return (dp - dest);
 502 }
 503 static
 504 int
 505 prcalling(char *dest, byte * p)
     /* [previous][next][first][last][top][bottom][index][help] */
 506 {
 507         int             l;
 508         char           *dp = dest;
 509 
 510         p++;
 511         l = *p++ - 1;
 512         dp += sprintf(dp, "    octet 3 ");
 513         dp += prbits(dp, *p, 8, 8);
 514         *dp++ = '\n';
 515         if (!(*p & 0x80)) {
 516                 dp += sprintf(dp, "    octet 3a ");
 517                 dp += prbits(dp, *++p, 8, 8);
 518                 *dp++ = '\n';
 519                 l--;
 520         };
 521 
 522         p++;
 523 
 524         dp += sprintf(dp, "    number digits ");
 525         while (l--)
 526                 *dp++ = *p++;
 527         *dp++ = '\n';
 528         return (dp - dest);
 529 }
 530 
 531 static
 532 int
 533 prbearer(char *dest, byte * p)
     /* [previous][next][first][last][top][bottom][index][help] */
 534 {
 535         char           *dp = dest, ch;
 536 
 537         p += 2;
 538         dp += sprintf(dp, "    octet 3  ");
 539         dp += prbits(dp, *p++, 8, 8);
 540         *dp++ = '\n';
 541         dp += sprintf(dp, "    octet 4  ");
 542         dp += prbits(dp, *p, 8, 8);
 543         *dp++ = '\n';
 544         if ((*p++ & 0x1f) == 0x18) {
 545                 dp += sprintf(dp, "    octet 4.1 ");
 546                 dp += prbits(dp, *p++, 8, 8);
 547                 *dp++ = '\n';
 548         }
 549         /* check for user information layer 1 */
 550         if ((*p & 0x60) == 0x20) {
 551                 ch = ' ';
 552                 do {
 553                         dp += sprintf(dp, "    octet 5%c ", ch);
 554                         dp += prbits(dp, *p, 8, 8);
 555                         *dp++ = '\n';
 556                         if (ch == ' ')
 557                                 ch = 'a';
 558                         else
 559                                 ch++;
 560                 }
 561                 while (!(*p++ & 0x80));
 562         }
 563         /* check for user information layer 2 */
 564         if ((*p & 0x60) == 0x40) {
 565                 dp += sprintf(dp, "    octet 6  ");
 566                 dp += prbits(dp, *p++, 8, 8);
 567                 *dp++ = '\n';
 568         }
 569         /* check for user information layer 3 */
 570         if ((*p & 0x60) == 0x60) {
 571                 dp += sprintf(dp, "    octet 7  ");
 572                 dp += prbits(dp, *p++, 8, 8);
 573                 *dp++ = '\n';
 574         }
 575         return (dp - dest);
 576 }
 577 
 578 static
 579 int
 580 general(char *dest, byte * p)
     /* [previous][next][first][last][top][bottom][index][help] */
 581 {
 582         char           *dp = dest;
 583         char            ch = ' ';
 584         int             l, octet = 3;
 585 
 586         p++;
 587         l = *p++;
 588         /* Iterate over all octets in the information element */
 589         while (l--) {
 590                 dp += sprintf(dp, "    octet %d%c ", octet, ch);
 591                 dp += prbits(dp, *p++, 8, 8);
 592                 *dp++ = '\n';
 593 
 594                 /* last octet in group? */
 595                 if (*p & 0x80) {
 596                         octet++;
 597                         ch = ' ';
 598                 } else if (ch == ' ')
 599                         ch = 'a';
 600 
 601                 else
 602                         ch++;
 603         }
 604         return (dp - dest);
 605 }
 606 
 607 static
 608 int
 609 display(char *dest, byte * p)
     /* [previous][next][first][last][top][bottom][index][help] */
 610 {
 611         char           *dp = dest;
 612         char            ch = ' ';
 613         int             l, octet = 3;
 614 
 615         p++;
 616         l = *p++;
 617         /* Iterate over all octets in the * display-information element */
 618         dp += sprintf(dp, "   \"");
 619         while (l--) {
 620                 dp += sprintf(dp, "%c", *p++);
 621 
 622                 /* last octet in group? */
 623                 if (*p & 0x80) {
 624                         octet++;
 625                         ch = ' ';
 626                 } else if (ch == ' ')
 627                         ch = 'a';
 628 
 629                 else
 630                         ch++;
 631         }
 632         *dp++ = '\"';
 633         *dp++ = '\n';
 634         return (dp - dest);
 635 }
 636 
 637 int
 638 prfacility(char *dest, byte * p)
     /* [previous][next][first][last][top][bottom][index][help] */
 639 {
 640         char           *dp = dest;
 641         int             l, l2;
 642 
 643         p++;
 644         l = *p++;
 645         dp += sprintf(dp, "    octet 3 ");
 646         dp += prbits(dp, *p++, 8, 8);
 647         dp += sprintf(dp, "\n");
 648         l -= 1;
 649 
 650         while (l > 0) {
 651                 dp += sprintf(dp, "   octet 4 ");
 652                 dp += prbits(dp, *p++, 8, 8);
 653                 dp += sprintf(dp, "\n");
 654                 dp += sprintf(dp, "   octet 5 %d\n", l2 = *p++ & 0x7f);
 655                 l -= 2;
 656                 dp += sprintf(dp, "   contents ");
 657                 while (l2--) {
 658                         dp += sprintf(dp, "%2x ", *p++);
 659                         l--;
 660                 }
 661                 dp += sprintf(dp, "\n");
 662         }
 663 
 664         return (dp - dest);
 665 }
 666 
 667 static
 668 struct InformationElement {
 669         byte            nr;
 670         char           *descr;
 671         int             (*f) (char *, byte *);
 672 } ielist[] = {
 673 
 674         {
 675                 0x00, "Segmented message", general
 676         },
 677         {
 678                 0x04, "Bearer capability", prbearer
 679         },
 680         {
 681                 0x08, "Cause", prcause
 682         },
 683         {
 684                 0x10, "Call identity", general
 685         },
 686         {
 687                 0x14, "Call state", general
 688         },
 689         {
 690                 0x18, "Channel identification", prchident
 691         },
 692         {
 693                 0x1c, "Facility", prfacility
 694         },
 695         {
 696                 0x1e, "Progress indicator", general
 697         },
 698         {
 699                 0x20, "Network-specific facilities", general
 700         },
 701         {
 702                 0x27, "Notification indicator", general
 703         },
 704         {
 705                 0x28, "Display", display
 706         },
 707         {
 708                 0x29, "Date/Time", general
 709         },
 710         {
 711                 0x2c, "Keypad facility", general
 712         },
 713         {
 714                 0x34, "Signal", general
 715         },
 716         {
 717                 0x40, "Information rate", general
 718         },
 719         {
 720                 0x42, "End-to-end delay", general
 721         },
 722         {
 723                 0x43, "Transit delay selection and indication", general
 724         },
 725         {
 726                 0x44, "Packet layer binary parameters", general
 727         },
 728         {
 729                 0x45, "Packet layer window size", general
 730         },
 731         {
 732                 0x46, "Packet size", general
 733         },
 734         {
 735                 0x47, "Closed user group", general
 736         },
 737         {
 738                 0x4a, "Reverse charge indication", general
 739         },
 740         {
 741                 0x6c, "Calling party number", prcalling
 742         },
 743         {
 744                 0x6d, "Calling party subaddress", general
 745         },
 746         {
 747                 0x70, "Called party number", prcalled
 748         },
 749         {
 750                 0x71, "Called party subaddress", general
 751         },
 752         {
 753                 0x74, "Redirecting number", general
 754         },
 755         {
 756                 0x78, "Transit network selection", general
 757         },
 758         {
 759                 0x79, "Restart indicator", general
 760         },
 761         {
 762                 0x7c, "Low layer compatibility", general
 763         },
 764         {
 765                 0x7d, "High layer compatibility", general
 766         },
 767         {
 768                 0x7e, "User-user", general
 769         },
 770         {
 771                 0x7f, "Escape for extension", general
 772         },
 773 };
 774 
 775 #define IESIZE sizeof(ielist)/sizeof(struct InformationElement)
 776 
 777 #ifdef FRITZDEBUG
 778 void
 779 hexdump(byte * buf, int len, char *comment)
     /* [previous][next][first][last][top][bottom][index][help] */
 780 {
 781         static char     dbuf[1024];
 782         char           *p = dbuf;
 783 
 784         p += sprintf(p, "%s: ", comment);
 785         while (len) {
 786                 p += sprintf(p, "%02x ", *p++);
 787                 len--;
 788         }
 789         p += sprintf(p, "\n");
 790 
 791         teles_putstatus(dbuf);
 792 }
 793 #endif
 794 
 795 void
 796 dlogframe(struct IsdnCardState *sp, byte * buf, int size, char *comment)
     /* [previous][next][first][last][top][bottom][index][help] */
 797 {
 798         byte           *bend = buf + size;
 799         char           *dp;
 800         int             i;
 801 
 802         /* display header */
 803         dp = sp->dlogspace;
 804         dp += sprintf(dp, "%s\n", comment);
 805 
 806         {
 807                 byte           *p = buf;
 808 
 809                 dp += sprintf(dp, "hex: ");
 810                 while (p < bend)
 811                         dp += sprintf(dp, "%02x ", *p++);
 812                 dp += sprintf(dp, "\n");
 813                 teles_putstatus(sp->dlogspace);
 814                 dp = sp->dlogspace;
 815         }
 816         /* locate message type */
 817         for (i = 0; i < MTSIZE; i++)
 818                 if (mtlist[i].nr == buf[3])
 819                         break;
 820 
 821         /* display message type iff it exists */
 822         if (i == MTSIZE)
 823                 dp += sprintf(dp, "Unknown message type %x!\n", buf[3]);
 824         else
 825                 dp += sprintf(dp, "call reference %d size %d message type %s\n",
 826                               buf[2], size, mtlist[i].descr);
 827 
 828         /* display each information element */
 829         buf += 4;
 830         while (buf < bend) {
 831                 /* Is it a single octet information element? */
 832                 if (*buf & 0x80) {
 833                         switch ((*buf >> 4) & 7) {
 834                           case 1:
 835                                   dp += sprintf(dp, "  Shift %x\n", *buf & 0xf);
 836                                   break;
 837                           case 3:
 838                                   dp += sprintf(dp, "  Congestion level %x\n", *buf & 0xf);
 839                                   break;
 840                           case 5:
 841                                   dp += sprintf(dp, "  Repeat indicator %x\n", *buf & 0xf);
 842                                   break;
 843                           case 2:
 844                                   if (*buf == 0xa0) {
 845                                           dp += sprintf(dp, "  More data\n");
 846                                           break;
 847                                   }
 848                                   if (*buf == 0xa1) {
 849                                           dp += sprintf(dp, "  Sending complete\n");
 850                                   }
 851                                   break;
 852                                   /* fall through */
 853                           default:
 854                                   dp += sprintf(dp, "  Reserved %x\n", *buf);
 855                                   break;
 856                         }
 857                         buf++;
 858                         continue;
 859                 }
 860                 /* No, locate it in the table */
 861                 for (i = 0; i < IESIZE; i++)
 862                         if (*buf == ielist[i].nr)
 863                                 break;
 864 
 865                 /* When not found, give appropriate msg */
 866                 if (i != IESIZE) {
 867                         dp += sprintf(dp, "  %s\n", ielist[i].descr);
 868                         dp += ielist[i].f(dp, buf);
 869                 } else
 870                         dp += sprintf(dp, "  attribute %x attribute size %d\n", *buf, buf[1]);
 871 
 872                 /* Skip to next element */
 873                 buf += buf[1] + 2;
 874         }
 875 
 876         dp += sprintf(dp, "\n");
 877         teles_putstatus(sp->dlogspace);
 878 }

/* [previous][next][first][last][top][bottom][index][help] */