1 /* 2 * File : rz.c 3 * the core functions of implementing zmodem protocol 4 * Change Logs: 5 * Date Author Notes 6 * 2011-03-29 itspy 7 */ 8 9 #include <rtthread.h> 10 #include <finsh.h> 11 #include <shell.h> 12 #include <rtdef.h> 13 #include <dfs.h> 14 #include <dfs_file.h> 15 #include <dfs_posix.h> 16 #include <stdio.h> 17 #include "zdef.h" 18 19 char ZF0_CMD; /* file conversion request */ 20 char ZF1_CMD; /* file management request */ 21 char ZF2_CMD; /* file transport request */ 22 char ZF3_CMD; 23 rt_uint8_t Rxframeind; /* ZBIN ZBIN32, or ZHEX type of frame */ 24 rt_uint16_t Rxcount; /* received count*/ 25 char header_type; /* header type */ 26 rt_uint8_t rx_header[4]; /* received header */ 27 rt_uint8_t tx_header[4]; /* transmitted header */ 28 rt_uint32_t Rxpos; /* received file position */ 29 rt_uint32_t Txpos; /* transmitted file position */ 30 rt_uint8_t Txfcs32; /* TURE means send binary frames with 32 bit FCS */ 31 rt_uint8_t TxCRC; /* controls 32 bit CRC being sent */ 32 rt_uint8_t RxCRC; /* indicates/controls 32 bit CRC being received */ 33 /* 0 == CRC16, 1 == CRC32, 2 == CRC32 + RLE */ 34 char Attn[ZATTNLEN+1]; /* attention string rx sends to tx on err */ 35 36 void zinit_parameter(void); 37 void zsend_bin_header(rt_uint8_t type, rt_uint8_t *hdr); 38 void zsend_hex_header(rt_uint8_t type, rt_uint8_t *hdr); 39 void zsend_bin_data(rt_uint8_t *buf, rt_int16_t len, rt_uint8_t frameend); 40 static rt_int16_t zrec_data16(rt_uint8_t *buf, rt_uint16_t len); 41 static rt_int16_t zrec_data32(rt_uint8_t *buf, rt_int16_t len); 42 static rt_int16_t zrec_data32r(rt_uint8_t *buf, rt_int16_t len); 43 rt_int16_t zget_data(rt_uint8_t *buf, rt_uint16_t len); 44 rt_int16_t zget_header(rt_uint8_t *hdr); 45 static rt_int16_t zget_bin_header(rt_uint8_t *hdr); 46 static rt_int16_t zget_bin_fcs(rt_uint8_t *hdr); 47 rt_int16_t zget_hex_header(rt_uint8_t *hdr); 48 static void zsend_ascii(rt_uint8_t c); 49 void zsend_zdle_char(rt_uint16_t ch); 50 static rt_int16_t zget_hex(void); 51 rt_int16_t zread_byte(void); 52 rt_int16_t zxor_read(void); 53 void zput_pos(rt_uint32_t pos); 54 void zget_pos(rt_uint32_t pos); 55 56 57 58 59 void zinit_parameter(void) 60 { 61 rt_uint8_t i; 62 63 ZF0_CMD = CANFC32|CANFDX|CANOVIO; /* not chose CANFC32,CANRLE,although it have been supported */ 64 ZF1_CMD = 0; /* fix header length,not support CANVHDR */ 65 ZF2_CMD = 0; 66 ZF3_CMD = 0; 67 Rxframeind =0; 68 header_type = 0; 69 Rxcount = 0; 70 for (i=0;i<4;i++) rx_header[i] = tx_header[i] = 0; 71 Rxpos = Txpos = 0; 72 RxCRC = 0; 73 Txfcs32 = 0; 74 75 return ; 76 } 77 78 /* send binary header */ 79 void zsend_bin_header(rt_uint8_t type, rt_uint8_t *hdr) 80 { 81 rt_uint8_t i; 82 rt_uint32_t crc; 83 84 zsend_byte(ZPAD); 85 zsend_byte(ZDLE); 86 TxCRC = Txfcs32; 87 if (TxCRC == 0) 88 { 89 zsend_byte(ZBIN); 90 zsend_zdle_char(type); 91 /* add 16bits crc */ 92 crc = 0L; 93 crc = updcrc16(type, 0); 94 for (i=0;i<4;i++) 95 { 96 zsend_zdle_char(*hdr); 97 crc = updcrc16((0377 & *hdr++),crc); 98 } 99 crc = updcrc16(0,updcrc16(0,crc)); 100 zsend_zdle_char(((int)(crc>>8))); 101 zsend_zdle_char(crc); 102 } 103 else if(TxCRC == 1) 104 { 105 zsend_byte(ZBIN32); 106 zsend_zdle_char(type); 107 /* add 32bits crc */ 108 crc = 0xffffffffL; 109 crc = updcrc32(type, crc); 110 for (i=0;i<4;i++) 111 { 112 zsend_zdle_char(*hdr); 113 crc = updcrc32((0377 & *hdr++), crc); 114 } 115 crc = ~crc; 116 for (i=0; i<4;i++) 117 { 118 zsend_zdle_char(crc); 119 crc >>= 8; 120 } 121 } 122 else if (TxCRC == 2) 123 { 124 zsend_byte(ZBINR32); 125 zsend_zdle_char(type); 126 /* add 32bits crc */ 127 crc = 0xffffffffL; 128 crc = updcrc32(type, crc); 129 for (i=0;i<4;i++) 130 { 131 zsend_zdle_char(*hdr); 132 crc = updcrc32((0377 & *hdr++), crc); 133 } 134 crc = ~crc; 135 for (i=0; i<4;i++) 136 { 137 zsend_zdle_char(crc); 138 crc >>= 8; 139 } 140 } 141 142 return; 143 } 144 145 /* send hex header */ 146 void zsend_hex_header(rt_uint8_t type, rt_uint8_t *hdr) 147 { 148 rt_uint8_t i; 149 rt_uint16_t crc; 150 151 zsend_line(ZPAD); zsend_line(ZPAD); zsend_line(ZDLE); 152 zsend_line(ZHEX); 153 zsend_ascii(type); 154 crc = updcrc16(type, 0); 155 for (i=0; i<4; i++) 156 { 157 zsend_ascii(*hdr); 158 crc = updcrc16((0377 & *hdr++), crc); 159 } 160 crc = updcrc16(0,updcrc16(0,crc)); 161 zsend_ascii(crc>>8); 162 zsend_ascii(crc); 163 /* send display control cmd */ 164 zsend_line(015); zsend_line(0212); 165 if (type != ZFIN && type != ZACK) 166 zsend_line(021); 167 TxCRC = 0; /* clear tx crc type */ 168 169 return; 170 } 171 172 /* send binary data,with frameend */ 173 void zsend_bin_data(rt_uint8_t *buf, rt_int16_t len, rt_uint8_t frameend) 174 { 175 rt_int16_t i,c,tmp; 176 rt_uint32_t crc; 177 178 if (TxCRC == 0) /* send binary data with 16bits crc check */ 179 { 180 crc = 0x0L; 181 for (i=0;i<len;i++) 182 { 183 zsend_zdle_char(*buf); 184 crc = updcrc16((0377 & *buf++), crc); 185 } 186 zsend_byte(ZDLE); zsend_byte(frameend); 187 crc = updcrc16(frameend, crc); 188 crc = updcrc16(0,updcrc16(0,crc)); 189 zsend_zdle_char(crc>>8); 190 zsend_zdle_char(crc); 191 } 192 else if (TxCRC == 1) /* send binary data with 32 bits crc check */ 193 { 194 crc = 0xffffffffL; 195 for (i=0;i<len;i++) 196 { 197 c = *buf++ & 0377; 198 zsend_zdle_char(c); 199 crc = updcrc32(c, crc); 200 } 201 zsend_byte(ZDLE); zsend_byte(frameend); 202 crc = updcrc32(frameend, crc); 203 crc = ~crc; 204 for (i=0;i<4;i++) 205 { 206 zsend_zdle_char((int)crc); crc >>= 8; 207 } 208 } 209 else if (TxCRC == 2) /* send binary data with 32bits crc check,RLE encode */ 210 { 211 crc = 0xffffffffL; 212 tmp = *buf++ & 0377; 213 for (i = 0; --len >= 0; ++buf) 214 { 215 if ((c = *buf & 0377) == tmp && i < 126 && len>0) 216 { 217 ++i; continue; 218 } 219 if (i==0) 220 { 221 zsend_zdle_char(tmp); 222 crc = updcrc32(tmp, crc); 223 if (tmp == ZRESC) 224 { 225 zsend_zdle_char(0100); crc = updcrc32(0100, crc); 226 } 227 tmp = c; 228 } 229 else if (i == 1) 230 { 231 if (tmp != ZRESC) 232 { 233 zsend_zdle_char(tmp); zsend_zdle_char(tmp); 234 crc = updcrc32(tmp, crc); 235 crc = updcrc32(tmp, crc); 236 i = 0; tmp = c; 237 } 238 239 } 240 else 241 { 242 zsend_zdle_char(ZRESC); crc = updcrc32(ZRESC, crc); 243 if (tmp == 040 && i < 34) 244 { 245 i += 036; 246 zsend_zdle_char(i); 247 crc = updcrc32(i, crc); 248 } 249 else 250 { 251 i += 0101; 252 zsend_zdle_char(i); crc = updcrc32(i, crc); 253 zsend_zdle_char(tmp); crc = updcrc32(tmp, crc); 254 } 255 i = 0; tmp = c; 256 } 257 } 258 zsend_byte(ZDLE); zsend_byte(frameend); 259 crc = updcrc32(frameend, crc); 260 crc = ~crc; 261 for (i=0;i<4;i++) 262 { 263 zsend_zdle_char(crc); 264 crc >>= 8; 265 } 266 } 267 if (frameend == ZCRCW) 268 zsend_byte(XON); 269 270 return; 271 } 272 273 /* receive data,with 16bits CRC check */ 274 static rt_int16_t zrec_data16(rt_uint8_t *buf, rt_uint16_t len) 275 { 276 rt_int16_t c,crc_cnt; 277 rt_uint16_t crc; 278 rt_err_t res = -RT_ERROR; 279 rt_uint8_t *p,flag = 0; 280 281 p = buf; 282 crc_cnt = 0; crc = 0L; 283 Rxcount = 0; 284 while(buf <= p+len) 285 { 286 if ((res = zread_byte()) & ~0377) 287 { 288 if (res == GOTCRCE || res == GOTCRCG || 289 res == GOTCRCQ || res == GOTCRCW) 290 { 291 c = res; 292 c = res; 293 crc = updcrc16(res&0377, crc); 294 flag = 1; 295 continue; 296 } 297 else if (res == GOTCAN) return ZCAN; 298 else if (res == TIMEOUT) return TIMEOUT; 299 else return res; 300 301 } 302 else 303 { 304 if (flag) 305 { 306 crc = updcrc16(res, crc); 307 crc_cnt++; 308 if (crc_cnt < 2) continue; 309 if ((crc & 0xffff)) 310 { 311 #ifdef ZDEBUG 312 rt_kprintf("error code: CRC16 error \r\n"); 313 #endif 314 return -RT_ERROR; 315 } 316 return c; 317 } 318 else 319 { 320 *buf++ = res; 321 Rxcount++; 322 crc = updcrc16(res, crc); 323 } 324 } 325 } 326 327 return -RT_ERROR; 328 } 329 330 /* receive data,with 32bits CRC check */ 331 static rt_int16_t zrec_data32(rt_uint8_t *buf, rt_int16_t len) 332 { 333 rt_int16_t c,crc_cnt; 334 rt_uint32_t crc; 335 rt_err_t res = -RT_ERROR; 336 rt_uint8_t *p,flag = 0; 337 338 crc_cnt = 0; crc = 0xffffffffL; 339 Rxcount = 0; 340 while (buf <= p+len) 341 { 342 if ((res = zread_byte()) & ~0377) 343 { 344 if (res == GOTCRCE || res == GOTCRCG || 345 res == GOTCRCQ || res == GOTCRCW) 346 { 347 c = res; 348 crc = updcrc32(res&0377, crc); 349 flag = 1; 350 continue; 351 } 352 else if (res == GOTCAN) return ZCAN; 353 else if (res == TIMEOUT) return TIMEOUT; 354 else return res; 355 356 } 357 else 358 { 359 if (flag) 360 { 361 crc = updcrc32(res, crc); 362 crc_cnt++; 363 if (crc_cnt < 4) continue; 364 if ((crc & 0xDEBB20E3)) 365 { 366 #ifdef ZDEBUG 367 rt_kprintf("error code: CRC32 error \r\n"); 368 #endif 369 return -RT_ERROR; 370 } 371 return c; 372 } 373 else 374 { 375 *buf++ = res; 376 Rxcount++; 377 crc = updcrc32(res, crc); 378 } 379 } 380 } 381 382 return -RT_ERROR; 383 } 384 /* receive data,with RLE encoded,32bits CRC check */ 385 static rt_int16_t zrec_data32r(rt_uint8_t *buf, rt_int16_t len) 386 { 387 rt_int16_t c,crc_cnt; 388 rt_uint32_t crc; 389 rt_err_t res = -RT_ERROR; 390 rt_uint8_t *p,flag = 0; 391 392 crc_cnt = 0; crc = 0xffffffffL; 393 Rxcount = 0; 394 p = buf; 395 while (buf <= p+len) 396 { 397 if ((res = zread_byte()) & ~0377) 398 { 399 if (res == GOTCRCE || res == GOTCRCG || 400 res == GOTCRCQ || res == GOTCRCW) 401 { 402 c = res; 403 crc = updcrc32(res&0377, crc); 404 flag = 1; 405 continue; 406 } 407 else if (res == GOTCAN) return ZCAN; 408 else if (res == TIMEOUT) return TIMEOUT; 409 else return res; 410 411 } 412 else 413 { 414 if (flag) 415 { 416 crc = updcrc32(res, crc); 417 crc_cnt++; 418 if (crc_cnt < 4) continue; 419 if ((crc & 0xDEBB20E3)) 420 { 421 #ifdef ZDEBUG 422 rt_kprintf("error code: CRC32 error \r\n"); 423 #endif 424 return -RT_ERROR; 425 } 426 return c; 427 } 428 else 429 { 430 crc = updcrc32(res, crc); 431 switch (c) 432 { 433 case 0: 434 if (res == ZRESC) 435 { 436 c = -1; continue; 437 } 438 *buf++ = res; 439 Rxcount++; 440 continue; 441 case -1: 442 if (res >= 040 && res < 0100) 443 { 444 c = res - 035; res = 040; 445 goto spaces; 446 } 447 if (res == 0100) 448 { 449 c = 0; 450 *buf++ = ZRESC; 451 Rxcount++; 452 continue; 453 } 454 c = res; continue; 455 default: 456 c -= 0100; 457 if (c < 1) 458 goto end; 459 spaces: 460 if ((buf + c) > p+len) 461 goto end; 462 while ( --res >= 0) 463 { 464 *buf++ = res; 465 Rxcount++; 466 } 467 c = 0; continue; 468 } 469 } 470 } // if -else 471 472 } 473 end: 474 return -RT_ERROR; 475 } 476 rt_int16_t zget_data(rt_uint8_t *buf, rt_uint16_t len) 477 { 478 rt_int16_t res = -RT_ERROR; 479 480 if (RxCRC == 0) 481 { 482 res = zrec_data16(buf,len); 483 } 484 else if (RxCRC == 1) 485 { 486 res = zrec_data32(buf, len); 487 } 488 else if (RxCRC == 2) 489 { 490 res = zrec_data32r(buf, len); 491 } 492 493 return res; 494 } 495 /* get type and cmd of header, fix lenght */ 496 rt_int16_t zget_header(rt_uint8_t *hdr) 497 { 498 rt_int16_t c,prev_char; 499 rt_uint32_t bit; 500 rt_uint16_t get_can,step_out; 501 502 bit = get_device_baud(); /* get console baud rate */ 503 Rxframeind = header_type = 0; 504 step_out = 0; 505 prev_char = 0xff; 506 for (;;) 507 { 508 c = zread_line(100); 509 switch(c) 510 { 511 case 021: 512 case 0221: 513 if (prev_char == CAN) break; 514 if (prev_char == ZCRCW) goto start_again; 515 break; 516 case RCDO: 517 goto end; 518 case TIMEOUT: 519 if (prev_char == CAN) break; 520 if (prev_char == ZCRCW) 521 { 522 c = -RT_ERROR; goto end; 523 } 524 goto end; 525 case ZCRCW: 526 if (prev_char == CAN) goto start_again; 527 break; 528 case CAN: 529 get_can: 530 if (++get_can > 5) 531 { 532 c = ZCAN; goto end; 533 } 534 break; 535 case ZPAD: 536 if (prev_char == CAN) break; 537 if (prev_char == ZCRCW) goto start_again; 538 step_out = 1; 539 break; 540 default: 541 if (prev_char == CAN) break; 542 if (prev_char == ZCRCW) goto start_again; 543 start_again: 544 if (--bit == 0) 545 { 546 c = GCOUNT; goto end; 547 } 548 get_can = 0; 549 break; 550 } 551 prev_char = c; 552 if (step_out) break; /* exit loop */ 553 } 554 step_out = get_can = 0; 555 for (;;) 556 { 557 c = zxor_read(); 558 switch(c) 559 { 560 case ZPAD: 561 break; 562 case RCDO: 563 case TIMEOUT: 564 goto end; 565 case ZDLE: 566 step_out = 1; 567 break; 568 default: 569 goto start_again; 570 } 571 if (step_out) break; 572 } 573 574 Rxframeind = c = zxor_read(); 575 switch (c) 576 { 577 case ZBIN32: 578 RxCRC = 1; c = zget_bin_fcs(hdr); break; 579 case ZBINR32: 580 RxCRC = 2; c = zget_bin_fcs(hdr); break; 581 case ZBIN: 582 RxCRC = 0; c = zget_bin_header(hdr); break; 583 case ZHEX: 584 RxCRC = 0; c = zget_hex_header(hdr); break; 585 case CAN: 586 goto get_can; 587 case RCDO: 588 case TIMEOUT: 589 goto end; 590 default: 591 goto start_again; 592 } 593 end: 594 return c; 595 } 596 597 /* receive a binary header */ 598 static rt_int16_t zget_bin_header(rt_uint8_t *hdr) 599 { 600 rt_int16_t res, i; 601 rt_uint16_t crc; 602 603 if ((res = zread_byte()) & ~0377) 604 return res; 605 header_type = res; 606 crc = updcrc16(res, 0); 607 608 for (i=0;i<4;i++) 609 { 610 if ((res = zread_byte()) & ~0377) 611 return res; 612 crc = updcrc16(res, crc); 613 *hdr++ = res; 614 } 615 if ((res = zread_byte()) & ~0377) 616 return res; 617 crc = updcrc16(res, crc); 618 if ((res = zread_byte()) & ~0377) 619 return res; 620 crc = updcrc16(res, crc); 621 if (crc & 0xFFFF) 622 { 623 rt_kprintf("CRC error\n"); 624 return -RT_ERROR; 625 } 626 627 return header_type; 628 } 629 630 /* receive a binary header,with 32bits FCS */ 631 static rt_int16_t zget_bin_fcs(rt_uint8_t *hdr) 632 { 633 rt_int16_t res, i; 634 rt_uint32_t crc; 635 636 if ((res = zread_byte()) & ~0377) 637 return res; 638 header_type = res; 639 crc = 0xFFFFFFFFL; 640 crc = updcrc32(res, crc); 641 642 for (i=0;i<4;i++) /* 4headers */ 643 { 644 if ((res = zread_byte()) & ~0377) 645 return res; 646 crc = updcrc32(res, crc); 647 *hdr++ = res; 648 649 } 650 for (i=0;i<4;i++) /* 4bytes crc */ 651 { 652 if ((res = zread_byte()) & ~0377) 653 return res; 654 crc = updcrc32(res, crc); 655 656 } 657 if (crc != 0xDEBB20E3) 658 { 659 #ifdef ZDEBUG 660 rt_kprintf("CRC error\n"); 661 #endif 662 return -RT_ERROR; 663 } 664 665 return header_type; 666 } 667 668 669 /* receive a hex style header (type and position) */ 670 rt_int16_t zget_hex_header(rt_uint8_t *hdr) 671 { 672 rt_int16_t res,i; 673 rt_uint16_t crc; 674 675 if ((res = zget_hex()) < 0) 676 return res; 677 header_type = res; 678 crc = updcrc16(res, 0); 679 680 for (i=0;i<4;i++) 681 { 682 if ((res = zget_hex()) < 0) 683 return res; 684 crc = updcrc16(res, crc); 685 *hdr++ = res; 686 } 687 if ((res = zget_hex()) < 0) 688 return res; 689 crc = updcrc16(res, crc); 690 if ((res = zget_hex()) < 0) 691 return res; 692 crc = updcrc16(res, crc); 693 if (crc & 0xFFFF) 694 { 695 #ifdef ZDEBUG 696 rt_kprintf("error code : CRC error\r\n"); 697 #endif 698 return -RT_ERROR; 699 } 700 res = zread_line(100); 701 if (res < 0) 702 return res; 703 res = zread_line(100); 704 if (res < 0) 705 return res; 706 707 return header_type; 708 } 709 710 /* convert to ascii */ 711 static void zsend_ascii(rt_uint8_t c) 712 { 713 const char hex[] = "0123456789abcdef"; 714 715 zsend_line(hex[(c&0xF0)>>4]); 716 zsend_line(hex[(c)&0xF]); 717 718 return; 719 } 720 721 /* 722 * aend character c with ZMODEM escape sequence encoding. 723 */ 724 void zsend_zdle_char(rt_uint16_t ch) 725 { 726 rt_uint16_t res; 727 728 res = ch & 0377; 729 switch (res) 730 { 731 case 0377: 732 zsend_byte(res); 733 break; 734 case ZDLE: 735 zsend_byte(ZDLE); 736 res ^= 0100; 737 zsend_byte(res); 738 break; 739 case 021: 740 case 023: 741 case 0221: 742 case 0223: 743 zsend_byte(ZDLE); 744 res ^= 0100; 745 zsend_byte(res); 746 break; 747 default: 748 zsend_byte(res); 749 } 750 } 751 752 /* decode two lower case hex digits into an 8 bit byte value */ 753 static rt_int16_t zget_hex(void) 754 { 755 rt_int16_t res,n; 756 757 if ((res = zxor_read()) < 0) 758 return res; 759 n = res - '0'; 760 if (n > 9) 761 n -= ('a' - ':'); 762 if (n & ~0x0f) 763 return -RT_ERROR; 764 if ((res = zxor_read()) < 0) 765 return res; 766 res -= '0'; 767 if (res > 9) 768 res -= ('a' - ':'); 769 if (res & ~0x0f) 770 return -RT_ERROR; 771 res += (n<<4); 772 773 return res; 774 } 775 776 777 /* 778 * read a byte, checking for ZMODEM escape encoding 779 * including CAN*5 which represents a quick abort 780 */ 781 rt_int16_t zread_byte(void) 782 { 783 register int res; 784 785 again: 786 /* Quick check for non control characters */ 787 if ((res = zread_line(100)) & 0140) 788 return res; 789 switch (res) 790 { 791 case ZDLE: 792 break; 793 case 023: 794 case 0223: 795 case 021: 796 case 0221: 797 goto again; 798 default: 799 return res; 800 } 801 again2: 802 if ((res = zread_line(100)) < 0) 803 return res; 804 if (res == CAN && (res = zread_line(100)) < 0) 805 return res; 806 if (res == CAN && (res = zread_line(100)) < 0) 807 return res; 808 if (res == CAN && (res = zread_line(100)) < 0) 809 return res; 810 switch (res) 811 { 812 case CAN: 813 return GOTCAN; 814 case ZCRCE: 815 case ZCRCG: 816 case ZCRCQ: 817 case ZCRCW: 818 return (res | GOTOR); 819 case ZRUB0: 820 return 0177; 821 case ZRUB1: 822 return 0377; 823 case 023: 824 case 0223: 825 case 021: 826 case 0221: 827 goto again2; 828 default: 829 if ((res & 0140) == 0100) 830 return (res ^ 0100); 831 break; 832 } 833 834 return -RT_ERROR; 835 } 836 837 /* 838 * @read a character from the modem line with timeout. 839 * @eat parity, XON and XOFF characters. 840 */ 841 rt_int16_t zxor_read(void) 842 { 843 rt_int16_t res; 844 845 for (;;) 846 { 847 if ((res = zread_line(100)) < 0) 848 return res; 849 switch (res &= 0177) { 850 case XON: 851 case XOFF: 852 continue; 853 case '\r': 854 case '\n': 855 case ZDLE: 856 default: 857 return res; 858 } 859 } 860 861 } 862 863 /* put file posistion into the header*/ 864 void zput_pos(rt_uint32_t pos) 865 { 866 tx_header[ZP0] = pos; 867 tx_header[ZP1] = pos>>8; 868 tx_header[ZP2] = pos>>16; 869 tx_header[ZP3] = pos>>24; 870 871 return; 872 } 873 874 /* Recover a long integer from a header */ 875 void zget_pos(rt_uint32_t pos) 876 { 877 Rxpos = (rx_header[ZP3] & 0377); 878 Rxpos = (Rxpos << 8) | (rx_header[ZP2] & 0377); 879 Rxpos = (Rxpos << 8) | (rx_header[ZP1] & 0377); 880 Rxpos = (Rxpos << 8) | (rx_header[ZP0] & 0377); 881 882 return; 883 } 884 885 /* end of zcore.c */ 886