Changeset 3960 for pjproject/branches/1.x/pjmedia/src/pjmedia/rtcp.c
- Timestamp:
- Feb 27, 2012 2:41:21 PM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/branches/1.x/pjmedia/src/pjmedia/rtcp.c
r3907 r3960 30 30 #define RTCP_SR 200 31 31 #define RTCP_RR 201 32 #define RTCP_SDES 202 33 #define RTCP_BYE 203 32 34 #define RTCP_XR 207 35 36 enum { 37 RTCP_SDES_NULL = 0, 38 RTCP_SDES_CNAME = 1, 39 RTCP_SDES_NAME = 2, 40 RTCP_SDES_EMAIL = 3, 41 RTCP_SDES_PHONE = 4, 42 RTCP_SDES_LOC = 5, 43 RTCP_SDES_TOOL = 6, 44 RTCP_SDES_NOTE = 7 45 }; 33 46 34 47 #if PJ_HAS_HIGH_RES_TIMER==0 … … 474 487 475 488 476 PJ_DEF(void) pjmedia_rtcp_rx_rtcp( pjmedia_rtcp_session *sess,477 478 489 static void parse_rtcp_report( pjmedia_rtcp_session *sess, 490 const void *pkt, 491 pj_size_t size) 479 492 { 480 493 pjmedia_rtcp_common *common = (pjmedia_rtcp_common*) pkt; … … 653 666 654 667 668 static void parse_rtcp_sdes(pjmedia_rtcp_session *sess, 669 const void *pkt, 670 pj_size_t size) 671 { 672 pjmedia_rtcp_sdes *sdes = &sess->stat.peer_sdes; 673 char *p, *p_end; 674 char *b, *b_end; 675 676 p = (char*)pkt + 8; 677 p_end = (char*)pkt + size; 678 679 pj_bzero(sdes, sizeof(*sdes)); 680 b = sess->stat.peer_sdes_buf_; 681 b_end = b + sizeof(sess->stat.peer_sdes_buf_); 682 683 while (p < p_end) { 684 pj_uint8_t sdes_type, sdes_len; 685 pj_str_t sdes_value = {NULL, 0}; 686 687 sdes_type = *p++; 688 689 /* Check for end of SDES item list */ 690 if (sdes_type == RTCP_SDES_NULL || p == p_end) 691 break; 692 693 sdes_len = *p++; 694 695 /* Check for corrupted SDES packet */ 696 if (p + sdes_len > p_end) 697 break; 698 699 /* Get SDES item */ 700 if (b + sdes_len < b_end) { 701 pj_memcpy(b, p, sdes_len); 702 sdes_value.ptr = b; 703 sdes_value.slen = sdes_len; 704 b += sdes_len; 705 } else { 706 /* Insufficient SDES buffer */ 707 PJ_LOG(5, (sess->name, 708 "Unsufficient buffer to save RTCP SDES type %d:%.*s", 709 sdes_type, sdes_len, p)); 710 p += sdes_len; 711 continue; 712 } 713 714 switch (sdes_type) { 715 case RTCP_SDES_CNAME: 716 sdes->cname = sdes_value; 717 break; 718 case RTCP_SDES_NAME: 719 sdes->name = sdes_value; 720 break; 721 case RTCP_SDES_EMAIL: 722 sdes->email = sdes_value; 723 break; 724 case RTCP_SDES_PHONE: 725 sdes->phone = sdes_value; 726 break; 727 case RTCP_SDES_LOC: 728 sdes->loc = sdes_value; 729 break; 730 case RTCP_SDES_TOOL: 731 sdes->tool = sdes_value; 732 break; 733 case RTCP_SDES_NOTE: 734 sdes->note = sdes_value; 735 break; 736 default: 737 TRACE_((sess->name, "Received unknown RTCP SDES type %d:%.*s", 738 sdes_type, sdes_value.slen, sdes_value.ptr)); 739 break; 740 } 741 742 p += sdes_len; 743 } 744 } 745 746 747 static void parse_rtcp_bye(pjmedia_rtcp_session *sess, 748 const void *pkt, 749 pj_size_t size) 750 { 751 pj_str_t reason = {"-", 1}; 752 753 /* Check and get BYE reason */ 754 if (size > 8) { 755 reason.slen = *((pj_uint8_t*)pkt+8); 756 pj_memcpy(sess->stat.peer_sdes_buf_, ((pj_uint8_t*)pkt+9), 757 reason.slen); 758 reason.ptr = sess->stat.peer_sdes_buf_; 759 } 760 761 /* Just print RTCP BYE log */ 762 PJ_LOG(5, (sess->name, "Received RTCP BYE, reason: %.*s", 763 reason.slen, reason.ptr)); 764 } 765 766 767 PJ_DEF(void) pjmedia_rtcp_rx_rtcp( pjmedia_rtcp_session *sess, 768 const void *pkt, 769 pj_size_t size) 770 { 771 pj_uint8_t *p, *p_end; 772 773 p = (pj_uint8_t*)pkt; 774 p_end = p + size; 775 while (p < p_end) { 776 pjmedia_rtcp_common *common = (pjmedia_rtcp_common*)p; 777 unsigned len; 778 779 len = (pj_ntohs((pj_uint16_t)common->length)+1) * 4; 780 switch(common->pt) { 781 case RTCP_SR: 782 case RTCP_RR: 783 case RTCP_XR: 784 parse_rtcp_report(sess, p, len); 785 break; 786 case RTCP_SDES: 787 parse_rtcp_sdes(sess, p, len); 788 break; 789 case RTCP_BYE: 790 parse_rtcp_bye(sess, p, len); 791 break; 792 default: 793 /* Ignore unknown RTCP */ 794 TRACE_((sess->name, "Received unknown RTCP packet type=%d", 795 common->pt)); 796 break; 797 } 798 799 p += len; 800 } 801 } 802 803 655 804 PJ_DEF(void) pjmedia_rtcp_build_rtcp(pjmedia_rtcp_session *sess, 656 805 void **ret_p_pkt, int *len) … … 805 954 } 806 955 956 957 PJ_DEF(pj_status_t) pjmedia_rtcp_build_rtcp_sdes( 958 pjmedia_rtcp_session *session, 959 void *buf, 960 pj_size_t *length, 961 const pjmedia_rtcp_sdes *sdes) 962 { 963 pjmedia_rtcp_common *hdr; 964 pj_uint8_t *p; 965 unsigned len; 966 967 PJ_ASSERT_RETURN(session && buf && length && sdes, PJ_EINVAL); 968 969 /* Verify SDES item length */ 970 if (sdes->cname.slen > 255 || sdes->name.slen > 255 || 971 sdes->email.slen > 255 || sdes->phone.slen > 255 || 972 sdes->loc.slen > 255 || sdes->tool.slen > 255 || 973 sdes->note.slen > 255) 974 { 975 return PJ_EINVAL; 976 } 977 978 /* Verify buffer length */ 979 len = sizeof(*hdr); 980 if (sdes->cname.slen) len += sdes->cname.slen + 2; 981 if (sdes->name.slen) len += sdes->name.slen + 2; 982 if (sdes->email.slen) len += sdes->email.slen + 2; 983 if (sdes->phone.slen) len += sdes->phone.slen + 2; 984 if (sdes->loc.slen) len += sdes->loc.slen + 2; 985 if (sdes->tool.slen) len += sdes->tool.slen + 2; 986 if (sdes->note.slen) len += sdes->note.slen + 2; 987 len++; /* null termination */ 988 len = ((len+3)/4) * 4; 989 if (len > *length) 990 return PJ_ETOOSMALL; 991 992 /* Build RTCP SDES header */ 993 hdr = (pjmedia_rtcp_common*)buf; 994 pj_memcpy(hdr, &session->rtcp_sr_pkt.common, sizeof(*hdr)); 995 hdr->pt = RTCP_SDES; 996 hdr->length = pj_htons((pj_uint16_t)(len/4 - 1)); 997 998 /* Build RTCP SDES items */ 999 p = (pj_uint8_t*)hdr + sizeof(*hdr); 1000 #define BUILD_SDES_ITEM(SDES_NAME, SDES_TYPE) \ 1001 if (sdes->SDES_NAME.slen) { \ 1002 *p++ = SDES_TYPE; \ 1003 *p++ = (pj_uint8_t)sdes->SDES_NAME.slen; \ 1004 pj_memcpy(p, sdes->SDES_NAME.ptr, sdes->SDES_NAME.slen); \ 1005 p += sdes->SDES_NAME.slen; \ 1006 } 1007 BUILD_SDES_ITEM(cname, RTCP_SDES_CNAME); 1008 BUILD_SDES_ITEM(name, RTCP_SDES_NAME); 1009 BUILD_SDES_ITEM(email, RTCP_SDES_EMAIL); 1010 BUILD_SDES_ITEM(phone, RTCP_SDES_PHONE); 1011 BUILD_SDES_ITEM(loc, RTCP_SDES_LOC); 1012 BUILD_SDES_ITEM(tool, RTCP_SDES_TOOL); 1013 BUILD_SDES_ITEM(note, RTCP_SDES_NOTE); 1014 #undef BUILD_SDES_ITEM 1015 1016 /* Null termination */ 1017 *p++ = 0; 1018 1019 /* Pad to 32bit */ 1020 while ((p-(pj_uint8_t*)buf) % 4) 1021 *p++ = 0; 1022 1023 /* Finally */ 1024 pj_assert((int)len == p-(pj_uint8_t*)buf); 1025 *length = len; 1026 1027 return PJ_SUCCESS; 1028 } 1029 1030 1031 PJ_DEF(pj_status_t) pjmedia_rtcp_build_rtcp_bye(pjmedia_rtcp_session *session, 1032 void *buf, 1033 pj_size_t *length, 1034 const pj_str_t *reason) 1035 { 1036 pjmedia_rtcp_common *hdr; 1037 pj_uint8_t *p; 1038 unsigned len; 1039 1040 PJ_ASSERT_RETURN(session && buf && length, PJ_EINVAL); 1041 1042 /* Verify BYE reason length */ 1043 if (reason && reason->slen > 255) 1044 return PJ_EINVAL; 1045 1046 /* Verify buffer length */ 1047 len = sizeof(*hdr); 1048 if (reason && reason->slen) len += reason->slen + 1; 1049 len = ((len+3)/4) * 4; 1050 if (len > *length) 1051 return PJ_ETOOSMALL; 1052 1053 /* Build RTCP BYE header */ 1054 hdr = (pjmedia_rtcp_common*)buf; 1055 pj_memcpy(hdr, &session->rtcp_sr_pkt.common, sizeof(*hdr)); 1056 hdr->pt = RTCP_BYE; 1057 hdr->length = pj_htons((pj_uint16_t)(len/4 - 1)); 1058 1059 /* Write RTCP BYE reason */ 1060 p = (pj_uint8_t*)hdr + sizeof(*hdr); 1061 if (reason && reason->slen) { 1062 *p++ = (pj_uint8_t)reason->slen; 1063 pj_memcpy(p, reason->ptr, reason->slen); 1064 p += reason->slen; 1065 } 1066 1067 /* Pad to 32bit */ 1068 while ((p-(pj_uint8_t*)buf) % 4) 1069 *p++ = 0; 1070 1071 pj_assert((int)len == p-(pj_uint8_t*)buf); 1072 *length = len; 1073 1074 return PJ_SUCCESS; 1075 } 1076 1077 807 1078 PJ_DEF(pj_status_t) pjmedia_rtcp_enable_xr( pjmedia_rtcp_session *sess, 808 1079 pj_bool_t enable)
Note: See TracChangeset
for help on using the changeset viewer.