1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2018 Chelsio Communications, Inc. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 #include <sys/cdefs.h> 30 #include "tcb_common.h" 31 32 /***:----------------------------------------------------------------------- 33 ***: externals 34 ***:----------------------------------------------------------------------- 35 */ 36 37 extern _TCBVAR g_tcb_info4[]; 38 extern _TCBVAR g_scb_info4[]; 39 extern _TCBVAR g_fcb_info4[]; 40 extern void t4_display_tcb_aux_0(_TCBVAR *tvp,int aux); 41 extern void t4_display_tcb_aux_1(_TCBVAR *tvp,int aux); 42 extern void t4_display_tcb_aux_2(_TCBVAR *tvp,int aux); 43 extern void t4_display_tcb_aux_3(_TCBVAR *tvp,int aux); 44 45 extern _TCBVAR g_tcb_info5[]; 46 extern _TCBVAR g_scb_info5[]; 47 extern _TCBVAR g_fcb_info5[]; 48 extern void t5_display_tcb_aux_0(_TCBVAR *tvp,int aux); 49 extern void t5_display_tcb_aux_1(_TCBVAR *tvp,int aux); 50 extern void t5_display_tcb_aux_2(_TCBVAR *tvp,int aux); 51 extern void t5_display_tcb_aux_3(_TCBVAR *tvp,int aux); 52 53 extern _TCBVAR g_tcb_info6[]; 54 extern _TCBVAR g_scb_info6[]; 55 extern _TCBVAR g_fcb_info6[]; 56 extern void t6_display_tcb_aux_0(_TCBVAR *tvp,int aux); 57 extern void t6_display_tcb_aux_1(_TCBVAR *tvp,int aux); 58 extern void t6_display_tcb_aux_2(_TCBVAR *tvp,int aux); 59 extern void t6_display_tcb_aux_3(_TCBVAR *tvp,int aux); 60 extern void t6_display_tcb_aux_4(_TCBVAR *tvp,int aux); 61 62 extern _TCBVAR g_tcb_info7[]; 63 extern _TCBVAR g_scb_info7[]; 64 extern _TCBVAR g_fcb_info7[]; 65 extern void t7_display_tcb_aux_0(_TCBVAR *tvp,int aux); 66 extern void t7_display_tcb_aux_1(_TCBVAR *tvp,int aux); 67 extern void t7_display_tcb_aux_2(_TCBVAR *tvp,int aux); 68 extern void t7_display_tcb_aux_3(_TCBVAR *tvp,int aux); 69 extern void t7_display_tcb_aux_4(_TCBVAR *tvp,int aux); 70 71 /***:----------------------------------------------------------------------- 72 ***: globals 73 ***:----------------------------------------------------------------------- 74 */ 75 76 _TCBVAR *g_tcb_info=g_tcb_info5; 77 _TCBVAR *g_scb_info=g_scb_info5; 78 _TCBVAR *g_fcb_info=g_fcb_info5; 79 static int g_tN=0; 80 81 static int g_prntstyl=PRNTSTYL_COMP; 82 83 static int g_got_scb=0; 84 static int g_got_fcb=0; 85 86 87 /***:----------------------------------------------------------------------- 88 ***: error exit functions 89 ***:----------------------------------------------------------------------- 90 */ 91 92 /**: err_exit functions 93 *: ------------------ 94 */ 95 96 void tcb_prflush(void) 97 { 98 fflush(stdout); 99 fflush(stderr); 100 } 101 102 103 void tcb_code_err_exit(char *fmt, ...) 104 { 105 va_list args; 106 va_start(args, fmt); 107 printf("Coding Error in: "); 108 vprintf(fmt, args); 109 printf("\n"); 110 tcb_prflush(); 111 va_end(args); 112 exit(1); 113 } 114 115 /***:----------------------------------------------------------------------- 116 ***: tcb_hexdump functions 117 ***:----------------------------------------------------------------------- 118 */ 119 120 void 121 tcb_hexdump(unsigned base, unsigned char *buf, unsigned int size) 122 { 123 unsigned offset; 124 125 for (offset = 0; offset < size; ++offset) { 126 if (!(offset % 16)) printf("\n0x%4.4x: ", base + offset); 127 else if (!(offset % 8)) printf(" "); 128 printf("%2.2x ", (unsigned char)buf[offset]); 129 } 130 } 131 132 int tcb_strmatch_nc(char *cs, char *ct) { 133 while (*cs) 134 if (tolower(*cs++) != tolower(*ct++)) return (FALSE); 135 return (!(*ct)); /*return TRUE if *ct NULL at same time as *cs==NULL*/ 136 } 137 138 139 /*: ------------------------------------------------------------------------- 140 string functions 141 tcb_strmatch_nc: Similar to exact match, but case insensitive. 142 */ 143 144 145 int 146 tcb_strncmp_nc(char *cs, char *ct, int n) 147 { 148 /*case insensitive version of the standard strncmp() function */ 149 int i = 0; 150 int ret; 151 152 153 ret = 0; 154 for (i = 0; i < n && 0 == ret && !(EOS == *cs && EOS == *ct); ++i) { 155 /* this is weird, but it matched GCC linux when strings don't 156 * have any upper case characters. 157 */ 158 ret = tolower(*cs++) - tolower(*ct++); 159 } 160 return ret; 161 } 162 163 int 164 tcb_startswith_nc(char *cs, char *ct) 165 { /* return true if cs start with ct */ 166 return (0 == tcb_strncmp_nc(cs, ct, (int)strlen(ct))); 167 } 168 169 170 171 172 /***:----------------------------------------------------------------------- 173 ***: START OF WINDOWS FUNCTIONS 174 ***:----------------------------------------------------------------------- 175 */ 176 177 178 /***:----------------------------------------------------------------------- 179 ***: print utilities 180 ***:----------------------------------------------------------------------- 181 */ 182 183 static int g_PR_indent=1; 184 185 void PR(char *fmt, ...) 186 { 187 int fmt_len; 188 va_list args; 189 va_start(args,fmt); 190 191 if (g_PR_indent) printf(" "); 192 g_PR_indent=0; 193 fmt_len=(int) strlen(fmt); 194 if (fmt_len>0 && fmt[fmt_len-1]=='\n') g_PR_indent=1; 195 196 vprintf(fmt,args); 197 tcb_prflush(); 198 va_end(args); 199 } 200 201 202 /***:----------------------------------------------------------------------- 203 ***: val() 204 ***:----------------------------------------------------------------------- 205 */ 206 207 _TCBVAR * 208 lu_tcbvar(char *name) 209 { 210 _TCBVAR *tvp=g_tcb_info; 211 212 while (tvp->name!=NULL) { 213 if (tcb_strmatch_nc(name,tvp->name)) return tvp; 214 else if (tcb_strmatch_nc(name,tvp->aka )) return tvp; 215 tvp+=1; 216 } 217 tcb_code_err_exit("lu_tcbvar: bad name %s\n",name); 218 return NULL; 219 } 220 221 unsigned 222 val(char *name) 223 { 224 _TCBVAR *tvp; 225 226 tvp=lu_tcbvar(name); 227 return tvp->val; 228 } 229 230 ui64 231 val64(char *name) 232 { 233 _TCBVAR *tvp; 234 235 tvp=lu_tcbvar(name); 236 return tvp->rawval; 237 } 238 239 240 241 /***:----------------------------------------------------------------------- 242 ***: get_tcb_bits 243 ***:----------------------------------------------------------------------- 244 */ 245 246 247 static int 248 get_tcb_bit(unsigned char *A, int bit) 249 { 250 int ret=0; 251 int ix,shift; 252 253 ix = 127 - (bit>>3); 254 shift=bit&0x7; 255 /* prdbg(" ix: %u, shift=%u\n",ix,shift); */ 256 ret=(A[ix] >> shift) & 1; 257 return ret; 258 } 259 260 static ui64 261 get_tcb_bits (unsigned char *A, int hi, int lo) 262 { 263 ui64 ret=0; 264 265 if (lo>hi) { 266 int temp=lo; 267 lo=hi; 268 hi=temp; 269 } 270 271 while (hi>=lo) { 272 ret = (ret<<1) | get_tcb_bit(A,hi); 273 --hi; 274 } 275 276 return ret; 277 } 278 279 280 void 281 decompress_val(_TCBVAR *tvp,unsigned ulp_type,unsigned tx_max, 282 unsigned rcv_nxt,unsigned rx_frag0_start_idx_raw) 283 { 284 unsigned rawval=(unsigned) tvp->rawval; 285 286 switch(tvp->comp) { 287 case COMP_NONE: tvp->val=rawval; break; 288 case COMP_ULP: tvp->val=rawval; break; 289 case COMP_TX_MAX: 290 tvp->val=(tx_max - rawval) & 0xFFFFFFFF; 291 break; 292 case COMP_RCV_NXT: 293 if (tcb_startswith_nc(tvp->name,"rx_frag")) { 294 unsigned fragx=0; 295 if (!tcb_strmatch_nc(tvp->name,"rx_frag0_start_idx_raw")) 296 fragx=rawval; 297 tvp->val=(rcv_nxt+rx_frag0_start_idx_raw+fragx) & 0xFFFFFFFF; 298 } else { 299 tvp->val=(rcv_nxt - rawval) & 0xFFFFFFFF; 300 } 301 break; 302 case COMP_PTR: tvp->val=rawval; break; 303 case COMP_LEN: 304 { 305 tvp->val=rawval; 306 if (PM_MODE_RDDP==ulp_type || PM_MODE_DDP==ulp_type || 307 PM_MODE_IANDP==ulp_type) { 308 /* TP does this internally. Not sure if I should show the 309 * unaltered value or the raw value. For now I 310 * will display the raw value. For now I've added the code 311 * mainly to stop windows compiler from warning about ulp_type 312 * being an unreferenced parameter. 313 */ 314 tvp->val=0; 315 tvp->val=rawval; /* comment this out to display altered value */ 316 } 317 } 318 break; 319 default: 320 tcb_code_err_exit("decompress_val, bad switch: %d",tvp->comp); 321 break; 322 } 323 324 325 326 } 327 328 329 void 330 get_tcb_field(_TCBVAR *tvp,unsigned char *buf) 331 { 332 assert(tvp->hi-tvp->lo+1<=64); 333 assert(tvp->hi>=tvp->lo); 334 335 tvp->rawval=get_tcb_bits(buf,tvp->lo,tvp->hi); 336 /* assume no compression and 32-bit value for now */ 337 tvp->val=(unsigned) (tvp->rawval & 0xFFFFFFFF); 338 339 340 } 341 342 343 /***:----------------------------------------------------------------------- 344 ***: spr_* functions 345 ***:----------------------------------------------------------------------- 346 */ 347 348 char * 349 spr_tcp_state (unsigned state) 350 { 351 char *ret="UNKNOWN"; 352 353 if ( 0 == state) {ret = "CLOSED";} 354 else if ( 1 == state) {ret = "LISTEN";} 355 else if ( 2 == state) {ret = "SYN_SENT";} 356 else if ( 3 == state) {ret = "SYN_RCVD";} 357 else if ( 4 == state) {ret = "ESTABLISHED";} 358 else if ( 5 == state) {ret = "CLOSE_WAIT";} 359 else if ( 6 == state) {ret = "FIN_WAIT_1";} 360 else if ( 7 == state) {ret = "CLOSING";} 361 else if ( 8 == state) {ret = "LAST_ACK";} 362 else if ( 9 == state) {ret = "FIN_WAIT_2";} 363 else if (10 == state) {ret = "TIME_WAIT";} 364 else if (11 == state) {ret = "ESTABLISHED_RX";} 365 else if (12 == state) {ret = "ESTABLISHED_TX";} 366 else if (13 == state) {ret = "SYN_PEND";} 367 else if (14 == state) {ret = "ESC_1_STATE";} 368 else if (15 == state) {ret = "ESC_2_STATE";} 369 370 return ret; 371 } 372 373 char * 374 spr_cctrl_sel(unsigned sel0,unsigned sel1) 375 { 376 unsigned sel=(sel1<<1) | sel0; 377 char *ret="UNKNOWN"; 378 379 if ( 0 == sel) {ret = "Reno";} 380 else if ( 1 == sel) {ret = "Tahoe";} 381 else if ( 2 == sel) {ret = "NewReno";} 382 else if ( 3 == sel) {ret = "HighSpeed";} 383 384 return ret; 385 } 386 387 388 char * 389 spr_ulp_type(unsigned ulp_type) 390 { 391 char *ret="UNKNOWN"; 392 393 /*The tp.h PM_MODE_XXX call 1 DDP and 5 IANDP, but external 394 * documentation (tcb.h" calls 5 ddp, and doesn't mention 1 or 3. 395 */ 396 397 if ( PM_MODE_PASS == ulp_type) {ret = "TOE";} 398 else if ( PM_MODE_DDP == ulp_type) {ret = "DDP";} 399 else if ( PM_MODE_ISCSI == ulp_type) {ret = "ISCSI";} 400 else if ( PM_MODE_IWARP == ulp_type) {ret = "IWARP";} 401 else if ( PM_MODE_RDDP == ulp_type) {ret = "RDMA";} 402 else if ( PM_MODE_IANDP == ulp_type) {ret = "IANDP_DDP";} 403 else if ( PM_MODE_FCOE == ulp_type) {ret = "FCoE";} 404 else if ( PM_MODE_USER == ulp_type) {ret = "USER";} 405 else if ( PM_MODE_TLS == ulp_type) {ret = "TLS";} 406 else if ( PM_MODE_DTLS == ulp_type) {ret = "DTLS";} 407 408 return ret; 409 } 410 411 char * 412 spr_ip_version(unsigned ip_version) 413 { 414 char *ret="UNKNOWN"; 415 416 if ( 0 == ip_version) {ret = "IPv4";} 417 else if ( 1 == ip_version) {ret = "IPv6";} 418 419 return ret; 420 } 421 422 423 424 /***:----------------------------------------------------------------------- 425 ***: display_tcb() 426 ***:----------------------------------------------------------------------- 427 */ 428 429 void 430 display_tcb_compressed(_TCBVAR *tvp,int aux) 431 { 432 433 if (g_tN==4) { 434 t4_display_tcb_aux_0(tvp,aux); 435 if (1==aux) t4_display_tcb_aux_1(tvp,aux); 436 else if (2==aux) t4_display_tcb_aux_2(tvp,aux); 437 else if (3==aux) t4_display_tcb_aux_3(tvp,aux); 438 439 } else if (g_tN==5) { 440 t5_display_tcb_aux_0(tvp,aux); 441 if (1==aux) t5_display_tcb_aux_1(tvp,aux); 442 else if (2==aux) t5_display_tcb_aux_2(tvp,aux); 443 else if (3==aux) t5_display_tcb_aux_3(tvp,aux); 444 } else if (g_tN==6) { 445 t6_display_tcb_aux_0(tvp,aux); 446 if (1==aux) t6_display_tcb_aux_1(tvp,aux); 447 else if (2==aux) t6_display_tcb_aux_2(tvp,aux); 448 else if (3==aux) t6_display_tcb_aux_3(tvp,aux); 449 else if (4==aux) t6_display_tcb_aux_4(tvp,aux); 450 } else if (g_tN==7) { 451 t7_display_tcb_aux_0(tvp,aux); 452 if (1==aux) t7_display_tcb_aux_1(tvp,aux); 453 else if (2==aux) t7_display_tcb_aux_2(tvp,aux); 454 else if (3==aux) t7_display_tcb_aux_3(tvp,aux); 455 else if (4==aux) t7_display_tcb_aux_4(tvp,aux); 456 } 457 } 458 459 460 461 462 /***:----------------------------------------------------------------------- 463 ***: parse_n_decode_tcb 464 ***:----------------------------------------------------------------------- 465 */ 466 467 468 unsigned 469 parse_tcb( _TCBVAR *base_tvp, unsigned char *buf) 470 { /* parse the TCB */ 471 _TCBVAR *tvp=base_tvp; 472 unsigned ulp_type; 473 int aux=1; /* assume TOE or iSCSI */ 474 unsigned tx_max=0, rcv_nxt=0, rx_frag0_start_idx_raw=0; 475 int got_tx_max=0, got_rcv_nxt=0, got_rx_frag0_start_idx_raw=0; 476 477 478 /* parse the TCB */ 479 while (tvp->name!=NULL) { 480 get_tcb_field(tvp,buf); 481 if (!got_tx_max && tcb_strmatch_nc("tx_max",tvp->name)) { 482 tx_max=tvp->val; 483 got_tx_max=1; 484 } 485 if (!got_rcv_nxt && tcb_strmatch_nc("rcv_nxt",tvp->name)) { 486 rcv_nxt=tvp->val; 487 got_rcv_nxt=1; 488 } 489 if (!got_rx_frag0_start_idx_raw && 490 tcb_strmatch_nc("rx_frag0_start_idx_raw",tvp->name)) { 491 rx_frag0_start_idx_raw=tvp->val; 492 got_rx_frag0_start_idx_raw=1; 493 } 494 tvp+=1; 495 } 496 497 tvp=base_tvp; 498 ulp_type=tvp->val; /* ULP type is always first variable in TCB */ 499 if (PM_MODE_IANDP==ulp_type || PM_MODE_FCOE==ulp_type) aux=3; 500 else if (PM_MODE_RDDP==ulp_type) aux=2; 501 else if (6==g_tN && (PM_MODE_TLS==ulp_type || PM_MODE_DTLS==ulp_type)) aux=4; 502 else aux=1; 503 504 assert(got_tx_max && got_rcv_nxt && got_rx_frag0_start_idx_raw); 505 506 /* decompress the compressed values */ 507 tvp=base_tvp; 508 while (tvp->name!=NULL) { 509 decompress_val(tvp,ulp_type,tx_max,rcv_nxt,rx_frag0_start_idx_raw); 510 tvp+=1; 511 } 512 513 return aux; 514 } 515 516 517 518 void 519 parse_scb( _TCBVAR *base_tvp, unsigned char *buf) 520 { /* parse the SCB */ 521 _TCBVAR *tvp=base_tvp; 522 523 while (tvp->name!=NULL) { 524 if (tcb_strmatch_nc("scb_slush",tvp->name)) { 525 /* the scb_slush field is all of remaining memory */ 526 tvp->rawval=0; 527 tvp->val=0; 528 } else { 529 get_tcb_field(tvp,buf); 530 } 531 tvp+=1; 532 } 533 } 534 535 536 void 537 parse_fcb( _TCBVAR *base_tvp, unsigned char *buf) 538 { /* parse the FCB */ 539 _TCBVAR *tvp=base_tvp; 540 541 while (tvp->name!=NULL) { 542 get_tcb_field(tvp,buf); 543 tvp+=1; 544 } 545 } 546 547 548 void 549 display_list_tcb(_TCBVAR *base_tvp,int aux) 550 { 551 _TCBVAR *tvp=base_tvp; 552 while (tvp->name!=NULL) { 553 if (tvp->aux==0 || tvp->aux==aux) { 554 if (tvp->hi-tvp->lo+1<=32) { 555 printf(" %4d:%4d %31s: %10u (0x%1x)",tvp->lo,tvp->hi,tvp->name, 556 (unsigned) tvp->rawval,(unsigned) tvp->rawval); 557 if (COMP_TX_MAX==tvp->comp || COMP_RCV_NXT==tvp->comp) 558 printf(" -> %1u (0x%x)", tvp->val,tvp->val); 559 } else { 560 printf(" %4d:%4d %31s: 0x%1llx",tvp->lo,tvp->hi,tvp->name, 561 tvp->rawval); 562 } 563 printf("\n"); 564 } 565 tvp+=1; 566 } 567 } 568 569 void 570 display_tcb(_TCBVAR *tvp,unsigned char *buf,int aux) 571 { 572 if (g_prntstyl==PRNTSTYL_VERBOSE || 573 g_prntstyl==PRNTSTYL_RAW) { 574 tcb_hexdump(0,buf,128); 575 printf("\n"); 576 } 577 578 if (g_prntstyl==PRNTSTYL_VERBOSE || 579 g_prntstyl==PRNTSTYL_LIST) { 580 display_list_tcb(tvp,aux); 581 } 582 583 if (g_prntstyl==PRNTSTYL_VERBOSE || 584 g_prntstyl==PRNTSTYL_COMP) { 585 display_tcb_compressed(tvp,aux); 586 } 587 588 } 589 590 void 591 parse_n_display_tcb(unsigned char *buf) 592 { 593 _TCBVAR *tvp=g_tcb_info; 594 int aux; 595 596 aux=parse_tcb(tvp,buf); 597 display_tcb(tvp,buf,aux); 598 } 599 600 void 601 parse_n_display_scb(unsigned char *buf) 602 { 603 _TCBVAR *tvp=g_scb_info; 604 605 parse_scb(tvp,buf); 606 if (g_prntstyl==PRNTSTYL_VERBOSE || 607 g_prntstyl==PRNTSTYL_RAW) { 608 tcb_hexdump(0,buf,128); 609 printf("\n"); 610 } 611 if (g_prntstyl==PRNTSTYL_VERBOSE || 612 g_prntstyl==PRNTSTYL_LIST || 613 g_prntstyl==PRNTSTYL_COMP) { 614 display_list_tcb(tvp,0); 615 } 616 } 617 618 void 619 parse_n_display_fcb(unsigned char *buf) 620 { 621 _TCBVAR *tvp=g_fcb_info; 622 623 parse_fcb(tvp,buf); 624 if (g_prntstyl==PRNTSTYL_VERBOSE || 625 g_prntstyl==PRNTSTYL_RAW) { 626 tcb_hexdump(0,buf,128); 627 printf("\n"); 628 } 629 630 if (g_prntstyl==PRNTSTYL_VERBOSE || 631 g_prntstyl==PRNTSTYL_LIST || 632 g_prntstyl==PRNTSTYL_COMP) { 633 display_list_tcb(tvp,0); 634 } 635 } 636 637 void 638 parse_n_display_xcb(unsigned char *buf) 639 { 640 if (g_got_scb) parse_n_display_scb(buf); 641 else if (g_got_fcb) parse_n_display_fcb(buf); 642 else parse_n_display_tcb(buf); 643 } 644 645 /***:----------------------------------------------------------------------- 646 ***: swizzle_tcb 647 ***:----------------------------------------------------------------------- 648 */ 649 650 void 651 swizzle_tcb(unsigned char *buf) 652 { 653 int i,j,k; 654 655 for (i=0, j=128-16 ; i<j ; i+=16, j-=16) { 656 unsigned char temp; 657 for (k=0; k<16; ++k) { 658 temp=buf[i+k]; 659 buf[i+k]=buf[j+k]; 660 buf[j+k]=temp; 661 } 662 } 663 } 664 665 666 /***:----------------------------------------------------------------------- 667 ***: END OF WINDOWS FUNCTIONS 668 ***:----------------------------------------------------------------------- 669 */ 670 671 void set_tidtype(unsigned int tidtype) 672 { 673 if (tidtype == TIDTYPE_SCB) 674 { 675 g_got_scb = 1; 676 } 677 else if (tidtype == TIDTYPE_FCB) 678 { 679 g_got_fcb = 1; 680 } 681 else 682 { 683 g_got_scb = 0; 684 g_got_fcb = 0; 685 } 686 687 } 688 689 void 690 set_tcb_info(unsigned int tidtype, unsigned int cardtype) 691 { 692 set_tidtype(tidtype); 693 694 g_tN = cardtype; 695 if (4 == g_tN) { 696 g_tcb_info = g_tcb_info4; 697 g_scb_info = g_scb_info4; 698 g_fcb_info = g_fcb_info4; 699 } 700 else if (5 == g_tN) { 701 g_tcb_info = g_tcb_info5; 702 g_scb_info = g_scb_info5; 703 g_fcb_info = g_fcb_info5; 704 } 705 else if (6 == g_tN) { 706 g_tcb_info = g_tcb_info6; 707 g_scb_info = g_scb_info6; 708 g_fcb_info = g_fcb_info6; 709 } 710 else if (7 == g_tN) { 711 g_tcb_info = g_tcb_info7; 712 g_scb_info = g_scb_info7; 713 g_fcb_info = g_fcb_info7; 714 } 715 } 716 717 void 718 set_print_style(unsigned int prntstyl) 719 { 720 g_prntstyl=prntstyl; 721 } 722