rtp_parser_err_t rtp_packet_parse(struct rtp_packet *pkt) { int padding_size; rtp_hdr_ext_t *hdr_ext_ptr; padding_size = 0; pkt->data_size = 0; pkt->data_offset = 0; pkt->appendable = 1; pkt->nsamples = RTP_NSAMPLES_UNKNOWN; if (pkt->size < sizeof(pkt->data.header)) return RTP_PARSER_PTOOSHRT; if (pkt->data.header.version != 2) return RTP_PARSER_IHDRVER; pkt->data_offset = RTP_HDR_LEN(&pkt->data.header); if (pkt->data.header.x != 0) { if (pkt->size < pkt->data_offset + sizeof(*hdr_ext_ptr)) return RTP_PARSER_PTOOSHRTXS; hdr_ext_ptr = (rtp_hdr_ext_t *)&pkt->data.buf[pkt->data_offset]; pkt->data_offset += sizeof(rtp_hdr_ext_t) + (ntohs(hdr_ext_ptr->length) * sizeof(hdr_ext_ptr->extension[0])); } if (pkt->size < pkt->data_offset) return RTP_PARSER_PTOOSHRTXH; if (pkt->data.header.p != 0) { if (pkt->data_offset == pkt->size) return RTP_PARSER_PTOOSHRTPS; padding_size = pkt->data.buf[pkt->size - 1]; if (padding_size == 0) return RTP_PARSER_IPS; } if (pkt->size < pkt->data_offset + padding_size) return RTP_PARSER_PTOOSHRTP; pkt->data_size = pkt->size - pkt->data_offset - padding_size; pkt->ts = ntohl(pkt->data.header.ts); pkt->seq = ntohs(pkt->data.header.seq); if (pkt->data_size == 0) return RTP_PARSER_OK; pkt->nsamples = rtp_calc_samples(pkt->data.header.pt, pkt->data_size, &pkt->data.buf[pkt->data_offset]); /* * G.729 comfort noise frame as the last frame causes * packet to be non-appendable */ if (pkt->data.header.pt == RTP_G729 && (pkt->data_size % 10) != 0) pkt->appendable = 0; return RTP_PARSER_OK; }
rtp_parser_err_t rtp_packet_parse_raw(unsigned char *buf, size_t size, struct rtp_info *rinfo) { int padding_size; rtp_hdr_ext_t *hdr_ext_ptr; rtp_hdr_t *header; header = (rtp_hdr_t *)buf; padding_size = 0; rinfo->data_size = 0; rinfo->data_offset = 0; rinfo->appendable = 1; rinfo->nsamples = RTP_NSAMPLES_UNKNOWN; if (size < sizeof(*header)) return RTP_PARSER_PTOOSHRT; if (header->version != 2) return RTP_PARSER_IHDRVER; rinfo->data_offset = RTP_HDR_LEN(header); if (header->x != 0) { if (size < rinfo->data_offset + sizeof(*hdr_ext_ptr)) return RTP_PARSER_PTOOSHRTXS; hdr_ext_ptr = (rtp_hdr_ext_t *)&buf[rinfo->data_offset]; rinfo->data_offset += sizeof(rtp_hdr_ext_t) + (ntohs(hdr_ext_ptr->length) * sizeof(hdr_ext_ptr->extension[0])); } if (size < rinfo->data_offset) return RTP_PARSER_PTOOSHRTXH; if (header->p != 0) { if (rinfo->data_offset == size) return RTP_PARSER_PTOOSHRTPS; padding_size = buf[size - 1]; if (padding_size == 0) return RTP_PARSER_IPS; } if (size < rinfo->data_offset + padding_size) return RTP_PARSER_PTOOSHRTP; rinfo->data_size = size - rinfo->data_offset - padding_size; rinfo->ts = ntohl(header->ts); rinfo->seq = ntohs(header->seq); rinfo->ssrc = ntohl(header->ssrc); rinfo->rtp_profile = &rtp_profiles[header->pt]; if (rinfo->data_size == 0) return RTP_PARSER_OK; rinfo->nsamples = rtp_calc_samples(header->pt, rinfo->data_size, &buf[rinfo->data_offset]); /* * G.729 comfort noise frame as the last frame causes * packet to be non-appendable */ if (header->pt == RTP_G729 && (rinfo->data_size % 10) != 0) rinfo->appendable = 0; return RTP_PARSER_OK; }