/* method that processes a stream and keeps the original order * of codecs with the same name */ static int stream_process(struct sip_msg * msg, struct sdp_stream_cell *cell, str * s, str* ss, regex_t* re, int op,int description) { static sdp_payload_attr_t static_payloads[] = { /* as per http://www.iana.org/assignments/rtp-parameters/rtp-parameters.xml */ { NULL,0,{ "0",1},{"PCMU",4},{ "8000",4},{NULL,0},{NULL,0} }, /* 0 - PCMU/8000 */ { NULL,0,{ "3",1},{ "GSM",3},{ "8000",4},{NULL,0},{NULL,0} }, /* 3 - GSM/8000 */ { NULL,0,{ "4",1},{"G723",4},{ "8000",4},{NULL,0},{NULL,0} }, /* 4 - G723/8000 */ { NULL,0,{ "5",1},{"DVI4",4},{ "8000",4},{NULL,0},{NULL,0} }, /* 5 - DVI4/8000 */ { NULL,0,{ "6",1},{"DVI4",4},{"16000",5},{NULL,0},{NULL,0} }, /* 6 - DVI4/16000 */ { NULL,0,{ "7",1},{ "LPC",3},{ "8000",4},{NULL,0},{NULL,0} }, /* 7 - LPC/8000 */ { NULL,0,{ "8",1},{"PCMA",4},{ "8000",4},{NULL,0},{NULL,0} }, /* 8 - PCMA/8000 */ { NULL,0,{ "9",1},{"G722",4},{ "8000",4},{NULL,0},{NULL,0} }, /* 9 - G722/8000 */ { NULL,0,{"10",2},{ "L16",3},{"44100",5},{NULL,0},{NULL,0} }, /*10 - L16/44100 */ { NULL,0,{"11",2},{ "L16",3},{"44100",5},{NULL,0},{NULL,0} }, /*11 - L16/44100 */ { NULL,0,{"12",2},{"QCELP",5},{"8000",4},{NULL,0},{NULL,0} }, /*12 -QCELP/8000 */ { NULL,0,{"13",2},{ "CN",2},{ "8000",4},{NULL,0},{NULL,0} }, /*13 - CN/8000 */ { NULL,0,{"14",2},{ "MPA",3},{"90000",5},{NULL,0},{NULL,0} }, /*14 - MPA/90000 */ { NULL,0,{"15",2},{"G728",4},{ "8000",4},{NULL,0},{NULL,0} }, /*15 - G728/8000 */ { NULL,0,{"16",2},{"DVI4",4},{"11025",5},{NULL,0},{NULL,0} }, /*16 - DVI4/11025 */ { NULL,0,{"17",2},{"DVI4",4},{"22050",5},{NULL,0},{NULL,0} }, /*17 - DVI4/22050 */ { NULL,0,{"18",2},{"G729",4},{ "8000",4},{NULL,0},{NULL,0} }, /*18 - G729/8000 */ { NULL,0,{"25",2},{"CelB",4},{ "8000",4},{NULL,0},{NULL,0} }, /*25 - CelB/8000 */ { NULL,0,{"26",2},{"JPEG",4},{"90000",5},{NULL,0},{NULL,0} }, /*26 - JPEG/90000 */ { NULL,0,{"28",2},{ "nv",2},{"90000",5},{NULL,0},{NULL,0} }, /*28 - nv/90000 */ { NULL,0,{"31",2},{"H261",4},{"90000",5},{NULL,0},{NULL,0} }, /*31 - H261/90000 */ { NULL,0,{"32",2},{ "MPV",3},{"90000",5},{NULL,0},{NULL,0} }, /*32 - MPV/90000 */ { NULL,0,{"33",2},{"MP2T",4},{"90000",5},{NULL,0},{NULL,0} }, /*33 - MP2T/90000 */ { NULL,0,{"34",2},{"H263",4},{"90000",5},{NULL,0},{NULL,0} }, /*34 - H263/90000 */ { NULL,0,{"t38",3},{"t38",3},{ "",0},{NULL,0},{NULL,0} }, /*T38- fax */ { NULL,0,{NULL,0},{ NULL,0},{ NULL,0},{NULL,0},{NULL,0} } }; sdp_payload_attr_t *payload; char *cur, *tmp, *buff, temp; struct lump * lmp; str found; int ret, i, depl, single, match, buff_len, is_static; regmatch_t pmatch; lmp = get_associated_lump(msg, cell); if( lmp == NULL) { LM_ERR("There is no lump for this sdp cell\n"); return -1; } /* is stream deleted ?? */ if (lmp->len == 0) return -1; buff_len = 0; ret = 0; buff = pkg_malloc(lmp->len+1); if( buff == NULL) { LM_ERR("Out of memory\n"); return -1; } /* search through each payload */ is_static = 0; payload = cell->payload_attr; while(payload) { if( payload->rtp_enc.s == NULL || (payload->rtp_clock.s == NULL && ss != NULL) || payload->rtp_payload.s == NULL) { goto next_payload; } match = 0; if( description == DESC_REGEXP ||description == DESC_REGEXP_COMPLEMENT ) { /* try to match a regexp */ if (is_static) { match = regexec( re, payload->rtp_enc.s, 1, &pmatch, 0) == 0; } else { temp = payload->rtp_enc.s[payload->rtp_enc.len]; payload->rtp_enc.s[payload->rtp_enc.len] = 0; match = regexec( re, payload->rtp_enc.s, 1, &pmatch, 0) == 0; payload->rtp_enc.s[payload->rtp_enc.len] = temp; } } if( description == DESC_REGEXP_COMPLEMENT) match = !match; if( description == DESC_NAME ) { match = s->len == payload->rtp_enc.len && strncasecmp( s->s, payload->rtp_enc.s , payload->rtp_enc.len) == 0; } if( description == DESC_NAME_AND_CLOCK) { /* try to match name and clock if there is one */ match = s->len == payload->rtp_enc.len && strncasecmp( s->s, payload->rtp_enc.s , payload->rtp_enc.len) == 0 && (ss == NULL || ( ss->len == payload->rtp_clock.len && strncasecmp( ss->s, payload->rtp_clock.s , payload->rtp_clock.len) == 0 ) ); } /* if found, search its index in the m= line */ if (match) { match = 0; cur = lmp->u.value; while( !match && cur < lmp->u.value + lmp->len) { /* find the end of the number */ found.s = cur; while( cur < lmp->u.value + lmp->len && *cur != ' ' ) cur++; found.len = cur - found.s; /* does it matches payload number */ if ( found.len == payload->rtp_payload.len && strncmp( found.s,payload->rtp_payload.s,found.len) == 0) { match = 1; } else { /* continue on searching => skip spaces if there still are any */ while( cur < lmp->u.value + lmp->len && * cur == ' ' ) cur++; } } /* have we found both payload and index */ if (match) { if(op == FIND) { ret = 1; goto end; } if( op == DELETE && !is_static ) { /* find the full 'a=...' entry */ if( delete_sdp_line( msg, payload->rtp_enc.s) < 0 ) { LM_ERR("Unable to add delete lump for a=\n"); ret = -1; goto end; } if( delete_sdp_line( msg, payload->fmtp_string.s) < 0 ) { LM_ERR("Unable to add delete lump for a=\n"); ret = -1; goto end; } } { /* take the following whitespaces as well */ while( cur < lmp->u.value + lmp->len && *cur == ' ' ) { cur++; found.len++; } /* when trimming the very last payload, avoid trailing ws */ if (cur == lmp->u.value + lmp->len) { tmp = found.s; while (*(--tmp) == ' ') { found.s--; found.len++; } } /* delete the string and update iterators */ for(tmp=found.s ; tmp< lmp->u.value + lmp->len ; tmp++ ) *tmp = *(tmp+found.len); cur -= found.len; lmp->len -= found.len; } /* add the deleted number into a buffer to be addded later */ if( op == ADD_TO_FRONT || op == ADD_TO_BACK) { if( buff_len > 0) { memcpy(&buff[buff_len]," ",1); buff_len++; } memcpy(&buff[buff_len],payload->rtp_payload.s, payload->rtp_payload.len); buff_len += payload->rtp_payload.len; } ret = 1; } } /* next payload */ next_payload: if (!is_static) { payload = payload->next; if (payload==NULL) { payload = static_payloads; is_static = 1; } } else { payload ++; if (payload->rtp_payload.s==NULL) payload=NULL; } } if( op == ADD_TO_FRONT && buff_len >0 ) { depl = buff_len; single = 1; if( lmp->len > 0) { depl++; single = 0; } lmp->u.value = (char*)pkg_realloc(lmp->u.value, lmp->len+depl); if(!lmp->u.value) { LM_ERR("No more pkg memory\n"); ret = -1; goto end; } for( i = lmp->len -1 ; i>=0;i--) lmp->u.value[i+depl] = lmp->u.value[i]; memcpy(lmp->u.value,buff,buff_len); if(!single) lmp->u.value[buff_len] = ' '; lmp->len += depl; } if( op == ADD_TO_BACK && buff_len >0 ) { lmp->u.value = (char*)pkg_realloc(lmp->u.value, lmp->len+buff_len+1); if(!lmp->u.value) { LM_ERR("No more pkg memory\n"); ret = -1; goto end; } if( lmp->len > 0) { memcpy(&lmp->u.value[lmp->len]," ",1); lmp->len++; } memcpy(&lmp->u.value[lmp->len],buff,buff_len); lmp->len += buff_len; } end: pkg_free(buff); return ret; }
/* method that processes a stream and keeps the original order * of codecs with the same name */ static int stream_process(struct sip_msg * msg, struct sdp_stream_cell *cell, str * s, str* ss, regex_t* re, int op,int description) { sdp_payload_attr_t *payload; char *cur, *tmp, *buff, temp; struct lump * lmp; str found; int ret, i, depl, single, match, buff_len; regmatch_t pmatch; lmp = get_associated_lump(msg, cell); if( lmp == NULL) { LM_ERR("There is no lump for this sdp cell\n"); return -1; } buff_len = 0; ret = 0; buff = pkg_malloc(lmp->len+1); if( buff == NULL) { LM_ERR("Out of memory\n"); return -1; } /* go through the 'm=' field to find numbers to be deleted */ cur = lmp->u.value; while( cur < lmp->u.value + lmp->len) { /* find the end of the first number */ found.s = cur; while( cur < lmp->u.value + lmp->len && *cur != ' ' ) cur++; found.len = cur - found.s; /* search through each payload */ payload = cell->payload_attr; while(payload) { if( payload->rtp_enc.s == NULL || (payload->rtp_clock.s == NULL && ss != NULL) || payload->rtp_payload.s == NULL) { payload = payload->next; continue; } match = 0; if( description == DESC_REGEXP ||description == DESC_REGEXP_COMPLEMENT ) { /* try to match a regexp */ temp = payload->rtp_enc.s[payload->rtp_enc.len]; payload->rtp_enc.s[payload->rtp_enc.len] = 0; match = regexec( re, payload->rtp_enc.s, 1, &pmatch, 0) == 0; payload->rtp_enc.s[payload->rtp_enc.len] = temp; } if( description == DESC_REGEXP_COMPLEMENT) match = !match; if( description == DESC_NAME ) { match = s->len == payload->rtp_enc.len && strncasecmp( s->s, payload->rtp_enc.s , payload->rtp_enc.len) == 0; } if( description == DESC_NAME_AND_CLOCK) { /* try to match name and clock if there is one */ match = s->len == payload->rtp_enc.len && strncasecmp( s->s, payload->rtp_enc.s , payload->rtp_enc.len) == 0 && (ss == NULL || ( ss->len == payload->rtp_clock.len && strncasecmp( ss->s, payload->rtp_clock.s , payload->rtp_clock.len) == 0 ) ); } /* try to match payload number */ match = match && (found.len == payload->rtp_payload.len && strncmp( found.s,payload->rtp_payload.s,found.len) == 0); /* if we find one of interest delete it */ if( match ) { if(op == FIND) { ret = 1; goto end; } if( op == DELETE) { /* find the full 'a=...' entry */ if( delete_sdp_line( msg, payload->rtp_enc.s) < 0 ) { LM_ERR("Unable to add delete lump for a=\n"); ret = -1; goto end; } if( delete_sdp_line( msg, payload->fmtp_string.s) < 0 ) { LM_ERR("Unable to add delete lump for a=\n"); ret = -1; goto end; } } /* if this number equals the one of interest delete it */ { /* take the following whitespaces as well */ while( cur < lmp->u.value + lmp->len && *cur == ' ' ) { cur++; found.len++; } /* delete the string and update iterators */ for(tmp=found.s ; tmp< lmp->u.value + lmp->len ; tmp++ ) *tmp = *(tmp+found.len); cur -= found.len; lmp->len -= found.len; } /* add the deleted number into a buffer to be addded later */ if( op == ADD_TO_FRONT || op == ADD_TO_BACK) { if( buff_len > 0) { memcpy(&buff[buff_len]," ",1); buff_len++; } memcpy(&buff[buff_len],payload->rtp_payload.s, payload->rtp_payload.len); buff_len += payload->rtp_payload.len; } ret = 1; } payload = payload->next; } /* skip spaces if there still are any */ while( cur < lmp->u.value + lmp->len && * cur == ' ' ) cur++; } if( op == ADD_TO_FRONT && buff_len >0 ) { depl = buff_len; single = 1; if( lmp->len > 0) { depl++; single = 0; } lmp->u.value = (char*)pkg_realloc(lmp->u.value, lmp->len+depl); if(!lmp->u.value) { LM_ERR("No more pkg memory\n"); ret = -1; goto end; } for( i = lmp->len -1 ; i>=0;i--) lmp->u.value[i+depl] = lmp->u.value[i]; memcpy(lmp->u.value,buff,buff_len); if(!single) lmp->u.value[buff_len] = ' '; lmp->len += depl; } if( op == ADD_TO_BACK && buff_len >0 ) { lmp->u.value = (char*)pkg_realloc(lmp->u.value, lmp->len+buff_len+1); if(!lmp->u.value) { LM_ERR("No more pkg memory\n"); ret = -1; goto end; } if( lmp->len > 0) { memcpy(&lmp->u.value[lmp->len]," ",1); lmp->len++; } memcpy(&lmp->u.value[lmp->len],buff,buff_len); lmp->len += buff_len; } end: pkg_free(buff); return ret; }