ROHC compression/decompression library
|
00001 /* 00002 * This program is free software; you can redistribute it and/or modify 00003 * it under the terms of the GNU General Public License as published by 00004 * the Free Software Foundation; either version 2 of the License, or 00005 * (at your option) any later version. 00006 * 00007 * This program is distributed in the hope that it will be useful, 00008 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00009 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00010 * GNU General Public License for more details. 00011 * 00012 * You should have received a copy of the GNU General Public License 00013 * along with this program; if not, write to the Free Software 00014 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00015 */ 00016 00024 #ifndef ROHC_H 00025 #define ROHC_H 00026 00372 #include <endian.h> 00373 00374 00375 /* 00376 * Below are some return codes: 00377 */ 00378 00380 #define ROHC_OK 1 00381 00382 #define ROHC_ERROR_NO_CONTEXT -1 00383 00384 #define ROHC_ERROR_PACKET_FAILED -2 00385 00386 #define ROHC_FEEDBACK_ONLY -3 00387 00388 #define ROHC_ERROR_CRC -4 00389 00390 #define ROHC_ERROR -5 00391 00392 #define ROHC_NEED_REPARSE -6 00393 00395 #define ROHC_TRUE 1 00396 00397 #define ROHC_FALSE 0 00398 00399 typedef unsigned char boolean; 00400 00401 00404 #define RTP_PORTS 1234, 36780, 33238, 5020, 5002 00405 00406 00407 00411 typedef enum 00412 { 00414 U_MODE = 1, 00416 O_MODE = 2, 00418 R_MODE = 3, 00419 } rohc_mode; 00420 00421 00425 struct medium 00426 { 00434 enum { 00436 LARGE_CID, 00438 SMALL_CID, 00439 } cid_type; 00440 00442 int max_cid; 00443 }; 00444 00445 00446 /* 00447 * ROHC profiles numbers allocated by the IANA (see 8 in the RFC 3095): 00448 */ 00449 00451 #define ROHC_PROFILE_UNCOMPRESSED 0x0000 00452 00453 #define ROHC_PROFILE_RTP 0x0001 00454 00455 #define ROHC_PROFILE_UDP 0x0002 00456 00457 #define ROHC_PROFILE_IP 0x0004 00458 00459 #define ROHC_PROFILE_UDPLITE 0x0008 00460 00461 00462 /* 00463 * The limits for the compressor states changes: 00464 */ 00465 00468 #define CHANGE_TO_IR_COUNT 1700 00469 00472 #define CHANGE_TO_FO_COUNT 700 00473 00476 #define MAX_IR_COUNT 3 00477 00480 #define MAX_FO_COUNT 3 00481 00482 00483 /* 00484 * The types of ROHC packets and their extensions: 00485 */ 00486 00488 #define PACKET_UO_0 0 00489 00490 #define PACKET_UO_1 1 00491 00492 #define PACKET_UOR_2 2 00493 00494 #define PACKET_IR_DYN 3 00495 00496 #define PACKET_IR 4 00497 00498 #define PACKET_UNKNOWN 5 00499 00500 #define PACKET_CCE 6 00501 00502 #define PACKET_CCE_OFF 7 00503 00504 #define PACKET_UO_1_RTP 8 00505 00506 #define PACKET_UO_1_ID 9 00507 00508 #define PACKET_UO_1_TS 10 00509 00510 #define PACKET_UOR_2_RTP 11 00511 00512 #define PACKET_UOR_2_ID 12 00513 00514 #define PACKET_UOR_2_TS 13 00515 00516 #define PACKET_NORMAL 14 00517 00519 #define PACKET_NOEXT (-1) 00520 00521 #define PACKET_EXT_0 0 00522 00523 #define PACKET_EXT_1 1 00524 00525 #define PACKET_EXT_2 2 00526 00527 #define PACKET_EXT_3 3 00528 00529 00530 /* 00531 * Constants related to packet recovery after CRC failure: 00532 */ 00533 00535 #define CRC_ACTION 1 00536 00537 00538 /* 00539 * Bitwised operations: 00540 */ 00541 00542 #define GET_BIT_0_2(x) ((*(x)) & 0x07) 00543 #define GET_BIT_0_4(x) ((*(x)) & 0x1f) 00544 #define GET_BIT_0_3(x) ((*(x)) & 0x0f) 00545 #define GET_BIT_0_5(x) ((*(x)) & 0x3f) 00546 #define GET_BIT_0_6(x) ((*(x)) & 0x7f) 00547 #define GET_BIT_0_7(x) ((*(x)) & 0xff) 00548 00549 #define GET_BIT_1_7(x) ( ((*(x)) & 0xfe) >> 1 ) 00550 #define GET_BIT_3_4(x) ( ((*(x)) & 0x18) >> 3 ) 00551 #define GET_BIT_3_5(x) ( ((*(x)) & 0x38) >> 3 ) 00552 #define GET_BIT_3_6(x) ( ((*(x)) & 0x78) >> 3 ) 00553 #define GET_BIT_3_7(x) ( ((*(x)) & 0xf8) >> 3 ) 00554 #define GET_BIT_4_7(x) ( ((*(x)) & 0xf0) >> 4 ) 00555 #define GET_BIT_5_7(x) ( ((*(x)) & 0xe0) >> 5 ) 00556 #define GET_BIT_6_7(x) ( ((*(x)) & 0xc0) >> 6 ) 00557 #define GET_BIT_4_6(x) ( ((*(x)) & 0x70) >> 4 ) 00558 00559 #define GET_BIT_0(x) ((*(x)) & 0x01) 00560 #define GET_BIT_1(x) ((*(x)) & 0x02) 00561 #define GET_BIT_2(x) ((*(x)) & 0x04) 00562 #define GET_BIT_3(x) ((*(x)) & 0x08) 00563 #define GET_BIT_4(x) ((*(x)) & 0x10) 00564 #define GET_BIT_5(x) ((*(x)) & 0x20) 00565 #define GET_BIT_6(x) ((*(x)) & 0x40) 00566 #define GET_BIT_7(x) ((*(x)) & 0x80) 00567 00569 #define GET_REAL(x) ( (x) ? 1 : 0 ) 00570 00572 #if __BYTE_ORDER == __LITTLE_ENDIAN 00573 # define GET_NEXT_16_BITS(x) \ 00574 ((((*((x) + 1)) << 8) & 0xff00) | ((*(x)) & 0x00ff)) 00575 #elif __BYTE_ORDER == __BIG_ENDIAN 00576 # define GET_NEXT_16_BITS(x) \ 00577 ((((*(x)) << 8) & 0xff00) | ((*((x) + 1)) & 0x00ff)) 00578 #else 00579 # error "Adjust your <bits/endian.h> defines" 00580 #endif 00581 00582 00583 /* 00584 * The flags for the IP changed fields: 00585 */ 00586 00588 #define MOD_TOS 0x0001 00589 00590 #define MOD_TOT_LEN 0x0002 00591 00592 #define MOD_ID 0x0004 00593 00594 #define MOD_FRAG_OFF 0x0008 00595 00596 #define MOD_TTL 0x0010 00597 00598 #define MOD_PROTOCOL 0x0020 00599 00600 #define MOD_CHECK 0x0040 00601 00602 #define MOD_SADDR 0x0080 00603 00604 #define MOD_DADDR 0x0100 00605 00606 00607 /* 00608 * The flags for the RTP changed fields: 00609 */ 00610 00612 #define MOD_RTP_PADDING 0x0200 00613 00614 #define MOD_RTP_EXT 0x0400 00615 00616 #define MOD_RTP_M 0x0800 00617 00618 #define MOD_RTP_PT 0x1000 00619 00620 #define MOD_RTP_SN 0x2000 00621 00622 #define MOD_RTP_TS 0x4000 00623 00624 #define MOD_RTP_SSRC 0x8000 00625 00626 00627 /* 00628 * Time-related constants: 00629 */ 00630 00631 #define WEIGHT_OLD 1 00632 #define WEIGHT_NEW 1 00633 00634 00635 /* 00636 * System includes: 00637 */ 00638 00639 #include <stdio.h> 00640 #include <stdlib.h> 00641 #include <time.h> 00642 #include <sys/time.h> 00643 #include <netinet/in.h> 00644 00645 /* 00646 * Debug macros: 00647 */ 00648 00650 #define zfree(pointer) \ 00651 do { \ 00652 free(pointer); \ 00653 pointer = NULL; \ 00654 } while(0) 00655 00656 00657 #ifdef __i386__ 00658 00670 static inline unsigned short ip_fast_csum(unsigned char *iph, unsigned int ihl) 00671 { 00672 unsigned int sum; 00673 00674 __asm__ __volatile__(" \n\ 00675 movl (%1), %0 \n\ 00676 subl $4, %2 \n\ 00677 jbe 2f \n\ 00678 addl 4(%1), %0 \n\ 00679 adcl 8(%1), %0 \n\ 00680 adcl 12(%1), %0 \n\ 00681 1: adcl 16(%1), %0 \n\ 00682 lea 4(%1), %1 \n\ 00683 decl %2 \n\ 00684 jne 1b \n\ 00685 adcl $0, %0 \n\ 00686 movl %0, %2 \n\ 00687 shrl $16, %0 \n\ 00688 addw %w2, %w0 \n\ 00689 adcl $0, %0 \n\ 00690 notl %0 \n\ 00691 2: \n\ 00692 " 00693 /* Since the input registers which are loaded with iph and ipl 00694 are modified, we must also specify them as outputs, or gcc 00695 will assume they contain their original values. */ 00696 : "=r" (sum), "=r" (iph), "=r" (ihl) 00697 : "1" (iph), "2" (ihl)); 00698 00699 return(sum); 00700 } 00701 00702 #else 00703 00704 static inline unsigned short from32to16(unsigned long x) 00705 { 00706 /* add up 16-bit and 16-bit for 16+c bit */ 00707 x = (x & 0xffff) + (x >> 16); 00708 /* add up carry.. */ 00709 x = (x & 0xffff) + (x >> 16); 00710 return x; 00711 } 00712 00713 static unsigned int do_csum(const unsigned char *buff, int len) 00714 { 00715 int odd, count; 00716 unsigned long result = 0; 00717 00718 if (len <= 0) 00719 goto out; 00720 odd = 1 & (unsigned long) buff; 00721 if (odd) { 00722 #ifdef __LITTLE_ENDIAN 00723 result = *buff; 00724 #else 00725 result += (*buff << 8); 00726 #endif 00727 len--; 00728 buff++; 00729 } 00730 count = len >> 1; /* nr of 16-bit words.. */ 00731 if (count) { 00732 if (2 & (unsigned long) buff) { 00733 result += *(unsigned short *) buff; 00734 count--; 00735 len -= 2; 00736 buff += 2; 00737 } 00738 count >>= 1; /* nr of 32-bit words.. */ 00739 if (count) { 00740 unsigned long carry = 0; 00741 do { 00742 unsigned long w = *(unsigned int *) buff; 00743 count--; 00744 buff += 4; 00745 result += carry; 00746 result += w; 00747 carry = (w > result); 00748 } while (count); 00749 result += carry; 00750 result = (result & 0xffff) + (result >> 16); 00751 } 00752 if (len & 2) { 00753 result += *(unsigned short *) buff; 00754 buff += 2; 00755 } 00756 } 00757 if (len & 1) 00758 #ifdef __LITTLE_ENDIAN 00759 result += *buff; 00760 #else 00761 result += (*buff << 8); 00762 #endif 00763 result = from32to16(result); 00764 if (odd) 00765 result = ((result >> 8) & 0xff) | ((result & 0xff) << 8); 00766 out: 00767 return result; 00768 } 00769 00774 static inline uint16_t ip_fast_csum(const void *iph, unsigned int ihl) 00775 { 00776 return (uint16_t)~do_csum(iph, ihl*4); 00777 } 00778 00779 #endif 00780 00781 00787 static inline unsigned int get_microseconds(void) 00788 { 00789 struct timeval tv; 00790 gettimeofday(&tv, NULL); 00791 return tv.tv_sec * 1000000 + tv.tv_usec; 00792 } 00793 00794 00800 static inline unsigned int get_milliseconds(void) 00801 { 00802 struct timeval tv; 00803 gettimeofday(&tv, NULL); 00804 return tv.tv_sec * 1000 + tv.tv_usec / 1000; 00805 } 00806 00807 char *rohc_version(void); 00808 00809 00810 /* 00811 * ROHC library includes: 00812 */ 00813 00814 #include "crc.h" 00815 #include "decode.h" 00816 #include "ip_id.h" 00817 #include "lsb.h" 00818 #include "sdvl.h" 00819 #include "wlsb.h" 00820 #include "rtp.h" 00821 #include "ip.h" 00822 00823 00824 #endif 00825