📄 rtcpsdes.c
字号:
/*------------------------------------------------------------------------- * rtcpsdes.c - rtcpsdes, rtcpprocesschunk, rtcpconsumechunk *------------------------------------------------------------------------- */#include <hash.h>#include <rtcp.h>#include <rtp.h>#include <string.h>#include <strings.h>/*------------------------------------------------------------------------ * rtcpsdes - process an incoming source description message *------------------------------------------------------------------------ */intrtcpsdes(struct session *psn, struct rtcp *prtcp){ struct sdchunk *pchunk; int i; if (prtcp->rtcp_type != RTCP_SDES) return ERROR; /* * Iterate over the source description's chunks. */ pchunk = (struct sdchunk *) prtcp->rtcp_data; for (i = 0; i < prtcp->rtcp_count && pchunk != NULL; i++) { pchunk = rtcpprocesschunk(psn, pchunk); } return OK;}/*------------------------------------------------------------------------ * rtcpprocesschunk - process a single chunk of a source description * message.Rtcpprocesschunk returns a pointer to the next chunk. *------------------------------------------------------------------------ */struct sdchunk *rtcpprocesschunk(struct session *psn, struct sdchunk *pchunk) { struct stream *pstm; struct sditem *psditem; struct sdchunk *nextchunk; pchunk->sdc_ssrc = ntohl(pchunk->sdc_ssrc); pstm = rtpgetstream(psn, pchunk->sdc_ssrc); if (pstm == NULL) if ((pstm = rtpnewstream(psn, pchunk->sdc_ssrc)) == NULL) return rtcpconsumechunk(pchunk); if (!RTP_INACTIVE(pstm->stm_inactive)) pstm->stm_inactive = 0; else { rtpreleasestream(psn, pstm); return rtcpconsumechunk(pchunk); } /* * Iterate over all items in the chunk. */ psditem = (struct sditem *) pchunk->sdc_data; nextchunk = NULL; while (nextchunk == NULL) { switch(psditem->sdi_type) { case RTCP_ITEM_NULL: /* * End of chunk; eat nulls until we reach * 32-bit alignmnet. */ do { psditem = (struct sditem *) ((char *) psditem + 1); } while (((unsigned int) psditem - (unsigned int) pchunk) % 4 != 0); nextchunk = (struct sdchunk *) psditem; break; /* * For all other items, record item in stream's state * and post an event with no data. */ case RTCP_ITEM_CNAME: if (bcmp(pstm->stm_cname, psditem->sdi_data, psditem->sdi_len)) { strncpy(pstm->stm_cname, psditem->sdi_data, psditem->sdi_len); pstm->stm_cname[psditem->sdi_len] = '\0'; rtcpcnameadd(psn, pstm); rtppostevent(psn, EVENT_RTCP_SDES_CNAME, pstm->stm_ssrc, NULL, 0); } break; case RTCP_ITEM_NAME: if (bcmp(pstm->stm_name, psditem->sdi_data, psditem->sdi_len)) { strncpy(pstm->stm_name, psditem->sdi_data, psditem->sdi_len); pstm->stm_name[psditem->sdi_len] = '\0'; rtppostevent(psn, EVENT_RTCP_SDES_NAME, pstm->stm_ssrc, NULL, 0); } break; case RTCP_ITEM_EMAIL: if (bcmp(pstm->stm_email, psditem->sdi_data, psditem->sdi_len)) { strncpy(pstm->stm_email, psditem->sdi_data, psditem->sdi_len); pstm->stm_email[psditem->sdi_len] = '\0'; rtppostevent(psn, EVENT_RTCP_SDES_EMAIL, pstm->stm_ssrc, NULL, 0); } break; case RTCP_ITEM_PHONE: if (bcmp(pstm->stm_phone, psditem->sdi_data, psditem->sdi_len)) { strncpy(pstm->stm_phone, psditem->sdi_data, psditem->sdi_len); pstm->stm_phone[psditem->sdi_len] = '\0'; rtppostevent(psn, EVENT_RTCP_SDES_PHONE, pstm->stm_ssrc, NULL, 0); } break; case RTCP_ITEM_LOC: if (bcmp(pstm->stm_loc, psditem->sdi_data, psditem->sdi_len)) { strncpy(pstm->stm_loc, psditem->sdi_data, psditem->sdi_len); pstm->stm_loc[psditem->sdi_len] = '\0'; rtppostevent(psn, EVENT_RTCP_SDES_LOC, pstm->stm_ssrc, NULL, 0); } break; case RTCP_ITEM_TOOL: if (bcmp(pstm->stm_tool, psditem->sdi_data, psditem->sdi_len)) { strncpy(pstm->stm_tool, psditem->sdi_data, psditem->sdi_len); pstm->stm_tool[psditem->sdi_len] = '\0'; rtppostevent(psn, EVENT_RTCP_SDES_TOOL, pstm->stm_ssrc, NULL, 0); } break; case RTCP_ITEM_NOTE: if (bcmp(pstm->stm_note, psditem->sdi_data, psditem->sdi_len)) { strncpy(pstm->stm_note, psditem->sdi_data, psditem->sdi_len); pstm->stm_note[psditem->sdi_len] = '\0'; rtppostevent(psn, EVENT_RTCP_SDES_NOTE, pstm->stm_ssrc, NULL, 0); } break; case RTCP_ITEM_PRIV: if (bcmp(pstm->stm_priv, psditem->sdi_data, psditem->sdi_len)) { strncpy(pstm->stm_priv, psditem->sdi_data, psditem->sdi_len); pstm->stm_note[psditem->sdi_len] = '\0'; rtppostevent(psn, EVENT_RTCP_SDES_PRIV, pstm->stm_ssrc, NULL, 0); } break; } /* * Advance to next item. */ psditem = (struct sditem *) ((char *) psditem + 2 + psditem->sdi_len); } rtppostevent(psn, EVENT_RTCP_SDES_CHUNK, pstm->stm_ssrc, (char *) pchunk, (unsigned int) nextchunk - (unsigned int) pchunk); rtpreleasestream(psn, pstm); return nextchunk;}/*------------------------------------------------------------------------ * rtcpconsumechunk - quietly consume a source description chunk. * Rtcpconsumechunk is used to skip over chunks that relate to inactive * participants. *------------------------------------------------------------------------ */struct sdchunk *rtcpconsumechunk(struct sdchunk *pchunk){ struct sdchunk *nextchunk; struct sditem *psditem; /* * Iterate over items in the chunk. */ psditem = (struct sditem *) pchunk->sdc_data; nextchunk = NULL; while (nextchunk == NULL) { if (psditem->sdi_type == RTCP_ITEM_NULL) { /* * End of chunk; eat nulls until we * reach 32-bit alignmnet. */ do { psditem = (struct sditem *) ((char *) psditem + 1); } while (((unsigned int) psditem - (unsigned int) pchunk) % 4 != 0); nextchunk = (struct sdchunk *) psditem; } /* * Advance to next item. */ psditem = (struct sditem *) ((char *) psditem + 2 + psditem->sdi_len); } return nextchunk;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -