sdpops_mod.c

00001 /*
00002  * $Id$
00003  *
00004  * Copyright (C) 2011 Daniel-Constantin Mierla (asipto.com)
00005  *
00006  * This file is part of Kamailio, a free SIP server.
00007  *
00008  * Kamailio is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation; either version 2 of the License, or
00011  * (at your option) any later version
00012  *
00013  * Kamailio is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  * GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License 
00019  * along with this program; if not, write to the Free Software 
00020  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00021  *
00022  */
00023 
00024 
00025 #include <string.h>
00026 #include <stdlib.h>
00027 #include <stdio.h>
00028 
00029 #include "../../sr_module.h"
00030 #include "../../dprint.h"
00031 #include "../../mod_fix.h"
00032 #include "../../pvar.h"
00033 #include "../../parser/sdp/sdp.h"
00034 #include "../../trim.h"
00035 #include "../../data_lump.h"
00036 
00037 #include "api.h"
00038 #include "sdpops_data.h"
00039 
00040 MODULE_VERSION
00041 
00042 static int w_sdp_remove_codecs_by_id(sip_msg_t* msg, char* codecs, char *bar);
00043 static int w_sdp_remove_codecs_by_name(sip_msg_t* msg, char* codecs, char *bar);
00044 static int w_sdp_keep_codecs_by_id(sip_msg_t* msg, char* codecs, char *bar);
00045 static int w_sdp_keep_codecs_by_name(sip_msg_t* msg, char* codecs, char *bar);
00046 static int w_sdp_with_media(sip_msg_t* msg, char* media, char *bar);
00047 static int w_sdp_with_codecs_by_id(sip_msg_t* msg, char* codec, char *bar);
00048 static int w_sdp_with_codecs_by_name(sip_msg_t* msg, char* codec, char *bar);
00049 static int w_sdp_remove_media(sip_msg_t* msg, char* media, char *bar);
00050 static int w_sdp_print(sip_msg_t* msg, char* level, char *bar);
00051 static int w_get_sdp(sip_msg_t* msg, char *bar);
00052 
00053 static int mod_init(void);
00054 
00055 static cmd_export_t cmds[] = {
00056         {"sdp_remove_codecs_by_id",    (cmd_function)w_sdp_remove_codecs_by_id,
00057                 1, fixup_spve_null,  0, ANY_ROUTE},
00058         {"sdp_remove_codecs_by_name",  (cmd_function)w_sdp_remove_codecs_by_name,
00059                 1, fixup_spve_null,  0, ANY_ROUTE},
00060         {"sdp_keep_codecs_by_id",    (cmd_function)w_sdp_keep_codecs_by_id,
00061                 1, fixup_spve_null,  0, ANY_ROUTE},
00062         {"sdp_keep_codecs_by_id",    (cmd_function)w_sdp_keep_codecs_by_id,
00063                 2, fixup_spve_spve,  0, ANY_ROUTE},
00064         {"sdp_keep_codecs_by_name",  (cmd_function)w_sdp_keep_codecs_by_name,
00065                 1, fixup_spve_null,  0, ANY_ROUTE},
00066         {"sdp_keep_codecs_by_name",  (cmd_function)w_sdp_keep_codecs_by_name,
00067                 2, fixup_spve_spve,  0, ANY_ROUTE},
00068         {"sdp_with_media",             (cmd_function)w_sdp_with_media,
00069                 1, fixup_spve_null,  0, ANY_ROUTE},
00070         {"sdp_remove_media",             (cmd_function)w_sdp_remove_media,
00071                 1, fixup_spve_null,  0, ANY_ROUTE},
00072         {"sdp_with_codecs_by_id",      (cmd_function)w_sdp_with_codecs_by_id,
00073                 1, fixup_spve_null,  0, ANY_ROUTE},
00074         {"sdp_with_codecs_by_name",    (cmd_function)w_sdp_with_codecs_by_name,
00075                 1, fixup_spve_null,  0, ANY_ROUTE},
00076         {"sdp_print",                  (cmd_function)w_sdp_print,
00077                 1, fixup_igp_null,  0, ANY_ROUTE},
00078         {"sdp_get",                  (cmd_function)w_get_sdp,
00079                 1, 0,  0, ANY_ROUTE},
00080         {"bind_sdpops",                (cmd_function)bind_sdpops,
00081                 1, 0, 0, 0},
00082         {0, 0, 0, 0, 0, 0}
00083 };
00084 
00085 static pv_export_t mod_pvs[] = {
00086 #if 0
00087         {{"sdp", (sizeof("sdp")-1)}, /* */
00088                 PVT_OTHER, pv_get_sdp, 0,
00089                 0, 0, 0, 0},
00090 #endif
00091 
00092         { {0, 0}, 0, 0, 0, 0, 0, 0, 0 }
00093 };
00094 
00095 static param_export_t params[] = {
00096         {0, 0, 0}
00097 };
00098 
00100 struct module_exports exports= {
00101         "sdpops",
00102         DEFAULT_DLFLAGS, /* dlopen flags */
00103         cmds,
00104         params,
00105         0,          /* exported statistics */
00106         0  ,        /* exported MI functions */
00107         mod_pvs,    /* exported pseudo-variables */
00108         0,          /* extra processes */
00109         mod_init,   /* module initialization function */
00110         0,
00111         0,
00112         0           /* per-child init function */
00113 };
00114 
00118 static int mod_init(void)
00119 {
00120         LM_DBG("sdpops module loaded\n");
00121         return 0;
00122 }
00123 
00124 
00128 int sdp_locate_line(sip_msg_t* msg, char *pos, str *aline)
00129 {
00130         char *p;
00131         p = pos;
00132         while(*p!='\n') p--;
00133         aline->s = p + 1;
00134         p = pos;
00135         while(*p!='\n') p++;
00136         aline->len = p - aline->s + 1;
00137         return 0;
00138 }
00139 
00143 int sdp_remove_str_codec_id_attrs(sip_msg_t* msg,
00144                 sdp_stream_cell_t* sdp_stream, str *rm_codec)
00145 {
00146         str aline = {0, 0};
00147         sdp_payload_attr_t *payload;
00148         struct lump *anchor;
00149 
00150         payload = sdp_stream->payload_attr;
00151         while (payload) {
00152                 LM_DBG("a= ... for codec %.*s/%.*s\n",
00153                         payload->rtp_payload.len, payload->rtp_payload.s,
00154                         payload->rtp_enc.len, payload->rtp_enc.s);
00155                 if(rm_codec->len==payload->rtp_payload.len
00156                                 && strncmp(payload->rtp_payload.s, rm_codec->s,
00157                                         rm_codec->len)==0) {
00158                         if(payload->rtp_enc.s!=NULL) {
00159                                 if(sdp_locate_line(msg, payload->rtp_enc.s, &aline)==0)
00160                                 {
00161                                         LM_DBG("removing line: %.*s", aline.len, aline.s);
00162                                         anchor = del_lump(msg, aline.s - msg->buf,
00163                                                         aline.len, 0);
00164                                         if (anchor == NULL) {
00165                                                 LM_ERR("failed to remove [%.*s] inside [%.*s]\n",
00166                                                         rm_codec->len, rm_codec->s,
00167                                                         aline.len, aline.s);
00168                                                 return -1;
00169                                         }
00170                                 }
00171                         }
00172                         if(payload->fmtp_string.s!=NULL) {
00173                                 if(sdp_locate_line(msg, payload->fmtp_string.s, &aline)==0)
00174                                 {
00175                                         LM_DBG("removing line: %.*s\n", aline.len, aline.s);
00176                                         anchor = del_lump(msg, aline.s - msg->buf,
00177                                                         aline.len, 0);
00178                                         if (anchor == NULL) {
00179                                                 LM_ERR("failed to remove [%.*s] inside [%.*s]\n",
00180                                                         rm_codec->len, rm_codec->s,
00181                                                         aline.len, aline.s);
00182                                                 return -1;
00183                                         }
00184                                 }
00185                         }
00186                 }
00187                 payload=payload->next;
00188         }
00189 
00190         return 0;
00191 }
00192 
00196 int sdp_codec_in_str(str *allcodecs, str* codec, char delim)
00197 {
00198         int i;
00199         int cmp;
00200 
00201         if(allcodecs==NULL || codec==NULL
00202                         || allcodecs->len<=0 || codec->len<=0)
00203                 return 0;
00204 
00205         cmp = 1;
00206         for(i=0; i<allcodecs->len; i++) {
00207                 if(cmp==1) {
00208                         if(codec->len <= allcodecs->len-i) {
00209                                 if(strncmp(&allcodecs->s[i], codec->s, codec->len)==0) {
00210                                         if(&allcodecs->s[i+codec->len]
00211                                                                         == &allcodecs->s[allcodecs->len]
00212                                                         || allcodecs->s[i+codec->len] == delim) {
00213                                                 /* match */
00214                                                 return 1;
00215                                         }
00216                                 }
00217                         }
00218                 }
00219                 if(allcodecs->s[i]==delim)
00220                         cmp = 1;
00221                 else
00222                         cmp = 0;
00223         }
00224 
00225         return 0;
00226 }
00227 
00228 
00232 int sdp_remove_str_codec_id(sip_msg_t* msg, str *allcodecs, str* rmcodec)
00233 {
00234         int i;
00235         int cmp;
00236         struct lump *anchor;
00237 
00238         if(msg==NULL || allcodecs==NULL || rmcodec==NULL
00239                         || allcodecs->len<=0 || rmcodec->len<=0)
00240                 return -1;
00241 
00242         cmp = 1;
00243         for(i=0; i<allcodecs->len; i++) {
00244                 if(cmp==1) {
00245                         if(rmcodec->len <= allcodecs->len-i) {
00246                                 if(strncmp(&allcodecs->s[i], rmcodec->s, rmcodec->len)==0) {
00247                                         if(&allcodecs->s[i+rmcodec->len]
00248                                                                         == &allcodecs->s[allcodecs->len]
00249                                                         || allcodecs->s[i+rmcodec->len] == ' ') {
00250                                                 /* match - remove also the space before codec id */
00251                                                 LM_DBG("found codec [%.*s] inside [%.*s]\n",
00252                                                                         rmcodec->len, rmcodec->s,
00253                                                                         allcodecs->len, allcodecs->s);
00254                                                 anchor = del_lump(msg, &allcodecs->s[i-1] - msg->buf,
00255                                                                 rmcodec->len+1, 0);
00256                                                 if (anchor == NULL) {
00257                                                         LM_ERR("failed to remove [%.*s] inside [%.*s]\n",
00258                                                                         rmcodec->len, rmcodec->s,
00259                                                                         allcodecs->len, allcodecs->s);
00260                                                         return -1;
00261                                                 }
00262                                                 return 0;
00263                                         }
00264                                 }
00265                         }
00266                 }
00267                 if(allcodecs->s[i]==' ')
00268                         cmp = 1;
00269                 else
00270                         cmp = 0;
00271         }
00272 
00273         return 0;
00274 }
00275 
00279 int sdp_remove_codecs_by_id(sip_msg_t* msg, str* codecs)
00280 {
00281         sdp_info_t *sdp = NULL;
00282         int sdp_session_num;
00283         int sdp_stream_num;
00284         sdp_session_cell_t* sdp_session;
00285         sdp_stream_cell_t* sdp_stream;
00286         str sdp_codecs;
00287         str tmp_codecs;
00288         str rm_codec;
00289 
00290         if(parse_sdp(msg) < 0) {
00291                 LM_ERR("Unable to parse sdp\n");
00292                 return -1;
00293         }
00294 
00295         sdp = (sdp_info_t*)msg->body;
00296 
00297         if(sdp==NULL) {
00298                 LM_DBG("No sdp body\n");
00299                 return -1;
00300         }
00301 
00302         LM_DBG("attempting to remove codecs from sdp: [%.*s]\n",
00303                         codecs->len, codecs->s);
00304 
00305         sdp_session_num = 0;
00306         for(;;)
00307         {
00308                 sdp_session = get_sdp_session(msg, sdp_session_num);
00309                 if(!sdp_session) break;
00310                 sdp_stream_num = 0;
00311                 for(;;)
00312                 {
00313                         sdp_stream = get_sdp_stream(msg, sdp_session_num, sdp_stream_num);
00314                         if(!sdp_stream) break;
00315 
00316                         LM_DBG("stream %d of %d - payloads [%.*s]\n",
00317                                 sdp_stream_num, sdp_session_num, 
00318                                 sdp_stream->payloads.len, sdp_stream->payloads.s);
00319                         sdp_codecs = sdp_stream->payloads;
00320                         tmp_codecs = *codecs;
00321                         while(str_find_token(&tmp_codecs, &rm_codec, ',')==0
00322                                         && rm_codec.len>0)
00323                         {
00324                                 tmp_codecs.len -=(int)(&rm_codec.s[rm_codec.len]-tmp_codecs.s);
00325                                 tmp_codecs.s = rm_codec.s + rm_codec.len;
00326 
00327                                 LM_DBG("codecs [%.*s] - remove [%.*s]\n",
00328                                                 sdp_codecs.len, sdp_codecs.s,
00329                                                 rm_codec.len, rm_codec.s);
00330                                 sdp_remove_str_codec_id(msg, &sdp_codecs, &rm_codec);
00331                                 sdp_remove_str_codec_id_attrs(msg, sdp_stream, &rm_codec);
00332                         }
00333                         sdp_stream_num++;
00334                 }
00335                 sdp_session_num++;
00336         }
00337 
00338         return 0;
00339 }
00340 
00344 static int w_sdp_remove_codecs_by_id(sip_msg_t* msg, char* codecs, char* bar)
00345 {
00346         str lcodecs = {0, 0};
00347 
00348         if(codecs==0)
00349         {
00350                 LM_ERR("invalid parameters\n");
00351                 return -1;
00352         }
00353 
00354         if(fixup_get_svalue(msg, (gparam_p)codecs, &lcodecs)!=0)
00355         {
00356                 LM_ERR("unable to get the list of codecs\n");
00357                 return -1;
00358         }
00359 
00360         if(sdp_remove_codecs_by_id(msg, &lcodecs)<0)
00361                 return -1;
00362         return 1;
00363 }
00364 
00368 int sdp_remove_codecs_by_name(sip_msg_t* msg, str* codecs)
00369 {
00370         sdp_info_t *sdp = NULL;
00371         str idslist;
00372 
00373         if(parse_sdp(msg) < 0) {
00374                 LM_ERR("Unable to parse sdp\n");
00375                 return -1;
00376         }
00377 
00378         sdp = (sdp_info_t*)msg->body;
00379 
00380         if(sdp==NULL) {
00381                 LM_DBG("No sdp body\n");
00382                 return -1;
00383         }
00384 
00385         LM_DBG("attempting to remove codecs from sdp: [%.*s]\n",
00386                         codecs->len, codecs->s);
00387 
00388         if(sdpops_build_ids_list(sdp, codecs, &idslist)<0)
00389                 return -1;
00390 
00391         if(sdp_remove_codecs_by_id(msg, &idslist)<0)
00392                 return -1;
00393 
00394         return 0;
00395 
00396 }
00397 
00401 static int w_sdp_remove_codecs_by_name(sip_msg_t* msg, char* codecs, char* bar)
00402 {
00403         str lcodecs = {0, 0};
00404 
00405         if(codecs==0)
00406         {
00407                 LM_ERR("invalid parameters\n");
00408                 return -1;
00409         }
00410 
00411         if(fixup_get_svalue(msg, (gparam_p)codecs, &lcodecs)!=0)
00412         {
00413                 LM_ERR("unable to get the list of codecs\n");
00414                 return -1;
00415         }
00416 
00417         if(sdp_remove_codecs_by_name(msg, &lcodecs)<0)
00418                 return -1;
00419         return 1;
00420 }
00421 
00425 int sdp_keep_codecs_by_id(sip_msg_t* msg, str* codecs, str *media)
00426 {
00427         sdp_info_t *sdp = NULL;
00428         int sdp_session_num;
00429         int sdp_stream_num;
00430         sdp_session_cell_t* sdp_session;
00431         sdp_stream_cell_t* sdp_stream;
00432         str sdp_codecs;
00433         str tmp_codecs;
00434         str rm_codec;
00435 
00436         if(parse_sdp(msg) < 0) {
00437                 LM_ERR("Unable to parse sdp\n");
00438                 return -1;
00439         }
00440 
00441         sdp = (sdp_info_t*)msg->body;
00442 
00443         if(sdp==NULL) {
00444                 LM_DBG("No sdp body\n");
00445                 return -1;
00446         }
00447 
00448         LM_DBG("attempting to keep codecs in sdp: [%.*s]\n",
00449                         codecs->len, codecs->s);
00450 
00451         sdp_session_num = 0;
00452         for(;;)
00453         {
00454                 sdp_session = get_sdp_session(msg, sdp_session_num);
00455                 if(!sdp_session) break;
00456                 sdp_stream_num = 0;
00457                 for(;;)
00458                 {
00459                         sdp_stream = get_sdp_stream(msg, sdp_session_num, sdp_stream_num);
00460                         if(!sdp_stream) break;
00461 
00462                         LM_DBG("stream %d of %d - payloads [%.*s]\n",
00463                                 sdp_stream_num, sdp_session_num,
00464                                 sdp_stream->payloads.len, sdp_stream->payloads.s);
00465                         if((media==NULL)
00466                                         || (media->len==sdp_stream->media.len
00467                                                 && strncasecmp(sdp_stream->media.s, media->s,
00468                                                         media->len)==0))
00469                         {
00470                                 sdp_codecs = sdp_stream->payloads;
00471                                 tmp_codecs = sdp_stream->payloads;
00472                                 while(str_find_token(&tmp_codecs, &rm_codec, ' ')==0
00473                                                 && rm_codec.len>0)
00474                                 {
00475                                         tmp_codecs.len -=(int)(&rm_codec.s[rm_codec.len]-tmp_codecs.s);
00476                                         tmp_codecs.s = rm_codec.s + rm_codec.len;
00477 
00478                                         if(sdp_codec_in_str(codecs, &rm_codec, ',')==0) {
00479                                                 LM_DBG("codecs [%.*s] - remove [%.*s]\n",
00480                                                         sdp_codecs.len, sdp_codecs.s,
00481                                                         rm_codec.len, rm_codec.s);
00482                                                 sdp_remove_str_codec_id(msg, &sdp_codecs, &rm_codec);
00483                                                 sdp_remove_str_codec_id_attrs(msg, sdp_stream, &rm_codec);
00484                                         }
00485                                 }
00486                         }
00487                         sdp_stream_num++;
00488                 }
00489                 sdp_session_num++;
00490         }
00491 
00492         return 0;
00493 }
00494 
00498 static int w_sdp_keep_codecs_by_id(sip_msg_t* msg, char* codecs, char* media)
00499 {
00500         str lcodecs = {0, 0};
00501         str lmedia = {0, 0};
00502 
00503         if(codecs==0)
00504         {
00505                 LM_ERR("invalid parameters\n");
00506                 return -1;
00507         }
00508 
00509         if(fixup_get_svalue(msg, (gparam_p)codecs, &lcodecs)!=0)
00510         {
00511                 LM_ERR("unable to get the list of codecs\n");
00512                 return -1;
00513         }
00514         if(media!=NULL)
00515         {
00516                 if(fixup_get_svalue(msg, (gparam_p)media, &lmedia)!=0)
00517                 {
00518                         LM_ERR("unable to get the media type\n");
00519                         return -1;
00520                 }
00521         }
00522 
00523         if(sdp_keep_codecs_by_id(msg, &lcodecs, (media)?&lmedia:NULL)<0)
00524                 return -1;
00525         return 1;
00526 }
00527 
00531 int sdp_keep_codecs_by_name(sip_msg_t* msg, str* codecs, str *media)
00532 {
00533         sdp_info_t *sdp = NULL;
00534         str idslist;
00535 
00536         if(parse_sdp(msg) < 0) {
00537                 LM_ERR("Unable to parse sdp\n");
00538                 return -1;
00539         }
00540 
00541         sdp = (sdp_info_t*)msg->body;
00542 
00543         if(sdp==NULL) {
00544                 LM_DBG("No sdp body\n");
00545                 return -1;
00546         }
00547 
00548         LM_DBG("attempting to keep codecs in sdp: [%.*s]\n",
00549                         codecs->len, codecs->s);
00550 
00551         if(sdpops_build_ids_list(sdp, codecs, &idslist)<0)
00552                 return -1;
00553 
00554         if(sdp_keep_codecs_by_id(msg, &idslist, media)<0)
00555                 return -1;
00556 
00557         return 0;
00558 
00559 }
00560 
00564 static int w_sdp_keep_codecs_by_name(sip_msg_t* msg, char* codecs, char* media)
00565 {
00566         str lcodecs = {0, 0};
00567         str lmedia = {0, 0};
00568 
00569         if(codecs==0)
00570         {
00571                 LM_ERR("invalid parameters\n");
00572                 return -1;
00573         }
00574 
00575         if(fixup_get_svalue(msg, (gparam_p)codecs, &lcodecs)!=0)
00576         {
00577                 LM_ERR("unable to get the list of codecs\n");
00578                 return -1;
00579         }
00580 
00581         if(media!=NULL)
00582         {
00583                 if(fixup_get_svalue(msg, (gparam_p)media, &lmedia)!=0)
00584                 {
00585                         LM_ERR("unable to get the media type\n");
00586                         return -1;
00587                 }
00588         }
00589 
00590         if(sdp_keep_codecs_by_name(msg, &lcodecs, (media)?&lmedia:NULL)<0)
00591                 return -1;
00592         return 1;
00593 }
00594 
00599 static int sdp_with_media(sip_msg_t *msg, str *media)
00600 {
00601         int sdp_session_num;
00602         int sdp_stream_num;
00603         sdp_session_cell_t* sdp_session;
00604         sdp_stream_cell_t* sdp_stream;
00605 
00606         if(parse_sdp(msg) < 0) {
00607                 LM_ERR("Unable to parse sdp\n");
00608                 return -1;
00609         }
00610 
00611         LM_DBG("attempting to search for media type: [%.*s]\n",
00612                         media->len, media->s);
00613 
00614         sdp_session_num = 0;
00615         for(;;)
00616         {
00617                 sdp_session = get_sdp_session(msg, sdp_session_num);
00618                 if(!sdp_session) break;
00619                 sdp_stream_num = 0;
00620                 for(;;)
00621                 {
00622                         sdp_stream = get_sdp_stream(msg, sdp_session_num, sdp_stream_num);
00623                         if(!sdp_stream) break;
00624 
00625                         LM_DBG("stream %d of %d - media [%.*s]\n",
00626                                 sdp_stream_num, sdp_session_num,
00627                                 sdp_stream->media.len, sdp_stream->media.s);
00628                         if(media->len==sdp_stream->media.len
00629                                         && strncasecmp(sdp_stream->media.s, media->s,
00630                                                         media->len)==0)
00631                                 return 1;
00632                         sdp_stream_num++;
00633                 }
00634                 sdp_session_num++;
00635         }
00636 
00637         return 0;
00638 }
00639 
00643 static int w_sdp_with_media(sip_msg_t* msg, char* media, char *bar)
00644 {
00645         str lmedia = {0, 0};
00646 
00647         if(media==0)
00648         {
00649                 LM_ERR("invalid parameters\n");
00650                 return -1;
00651         }
00652 
00653         if(fixup_get_svalue(msg, (gparam_p)media, &lmedia)!=0)
00654         {
00655                 LM_ERR("unable to get the media value\n");
00656                 return -1;
00657         }
00658 
00659         if(sdp_with_media(msg, &lmedia)<=0)
00660                 return -1;
00661         return 1;
00662 }
00663 
00668 static int sdp_remove_media(sip_msg_t *msg, str *media)
00669 {
00670         sdp_info_t *sdp = NULL;
00671         int sdp_session_num;
00672         int sdp_stream_num;
00673         sdp_session_cell_t* sdp_session;
00674         sdp_stream_cell_t* sdp_stream;
00675         sdp_stream_cell_t* nxt_stream;
00676         int ret = 0;
00677         char *dstart = NULL;
00678         int dlen = 0;
00679         struct lump *anchor;
00680 
00681         if(parse_sdp(msg) < 0) {
00682                 LM_ERR("Unable to parse sdp\n");
00683                 return -1;
00684         }
00685 
00686         LM_DBG("attempting to search for media type: [%.*s]\n",
00687                         media->len, media->s);
00688 
00689         sdp = (sdp_info_t*)msg->body;
00690 
00691         sdp_session_num = 0;
00692         for(;;)
00693         {
00694                 sdp_session = get_sdp_session(msg, sdp_session_num);
00695                 if(!sdp_session) break;
00696                 sdp_stream_num = 0;
00697                 for(;;)
00698                 {
00699                         sdp_stream = get_sdp_stream(msg, sdp_session_num, sdp_stream_num);
00700                         if(!sdp_stream) break;
00701 
00702                         LM_DBG("stream %d of %d - media [%.*s]\n",
00703                                 sdp_stream_num, sdp_session_num,
00704                                 sdp_stream->media.len, sdp_stream->media.s);
00705                         if(media->len==sdp_stream->media.len
00706                                         && strncasecmp(sdp_stream->media.s, media->s,
00707                                                         media->len)==0)
00708                         {
00709                                 /* found - remove */
00710                                 LM_DBG("removing media stream: %.*s", media->len, media->s);
00711                                 nxt_stream = get_sdp_stream(msg, sdp_session_num,
00712                                                                 sdp_stream_num+1);
00713                                 /* skip back 'm=' */
00714                                 dstart = sdp_stream->media.s - 2;
00715                                 if(!nxt_stream) {
00716                                         /* delete to end of sdp */
00717                                         dlen = (int)(sdp->text.s + sdp->text.len - dstart);
00718                                 } else {
00719                                         /* delete to start of next stream */
00720                                         dlen = (int)(nxt_stream->media.s - 2 - dstart);
00721                                 }
00722                                 anchor = del_lump(msg, dstart - msg->buf, dlen, 0);
00723                                 if (anchor == NULL) {
00724                                         LM_ERR("failed to remove media type [%.*s]\n",
00725                                                  media->len, media->s);
00726                                         return -1;
00727                                 }
00728 
00729                                 ret++;
00730                         }
00731                         sdp_stream_num++;
00732                 }
00733                 sdp_session_num++;
00734         }
00735 
00736         return ret;
00737 }
00738 
00739 
00743 static int w_sdp_remove_media(sip_msg_t* msg, char* media, char *bar)
00744 {
00745         str lmedia = {0, 0};
00746 
00747         if(media==0)
00748         {
00749                 LM_ERR("invalid parameters\n");
00750                 return -1;
00751         }
00752 
00753         if(fixup_get_svalue(msg, (gparam_p)media, &lmedia)!=0)
00754         {
00755                 LM_ERR("unable to get the media value\n");
00756                 return -1;
00757         }
00758 
00759         if(sdp_remove_media(msg, &lmedia)<=0)
00760                 return -1;
00761         return 1;
00762 }
00763 
00764 
00768 int sdp_with_codecs_by_id(sip_msg_t* msg, str* codecs)
00769 {
00770         sdp_info_t *sdp = NULL;
00771         int sdp_session_num;
00772         int sdp_stream_num;
00773         sdp_session_cell_t* sdp_session;
00774         sdp_stream_cell_t* sdp_stream;
00775         str sdp_codecs;
00776         str tmp_codecs;
00777         str fnd_codec;
00778         int foundone = 0;
00779         int notfound = 0;
00780 
00781         if(parse_sdp(msg) < 0) {
00782                 LM_ERR("Unable to parse sdp\n");
00783                 return -1;
00784         }
00785 
00786         sdp = (sdp_info_t*)msg->body;
00787 
00788         if(sdp==NULL) {
00789                 LM_DBG("No sdp body\n");
00790                 return -1;
00791         }
00792 
00793         LM_DBG("attempting to search codecs in sdp: [%.*s]\n",
00794                         codecs->len, codecs->s);
00795 
00796         sdp_session_num = 0;
00797         for(;;)
00798         {
00799                 sdp_session = get_sdp_session(msg, sdp_session_num);
00800                 if(!sdp_session) break;
00801                 sdp_stream_num = 0;
00802                 for(;;)
00803                 {
00804                         sdp_stream = get_sdp_stream(msg, sdp_session_num, sdp_stream_num);
00805                         if(!sdp_stream) break;
00806 
00807                         LM_DBG("stream %d of %d - payloads [%.*s]\n",
00808                                 sdp_stream_num, sdp_session_num,
00809                                 sdp_stream->payloads.len, sdp_stream->payloads.s);
00810                         sdp_codecs = sdp_stream->payloads;
00811                         tmp_codecs = *codecs;
00812                         while(str_find_token(&tmp_codecs, &fnd_codec, ',')==0
00813                                         && fnd_codec.len>0)
00814                         {
00815                                 tmp_codecs.len -=(int)(&fnd_codec.s[fnd_codec.len]-tmp_codecs.s);
00816                                 tmp_codecs.s = fnd_codec.s + fnd_codec.len;
00817 
00818                                 if(sdp_codec_in_str(&sdp_codecs, &fnd_codec, ' ')==0) {
00819                                         LM_DBG("codecs [%.*s] - not found [%.*s]\n",
00820                                                 sdp_codecs.len, sdp_codecs.s,
00821                                                 fnd_codec.len, fnd_codec.s);
00822                                         notfound = 1;
00823                                 } else {
00824                                         LM_DBG("codecs [%.*s] - found [%.*s]\n",
00825                                                 sdp_codecs.len, sdp_codecs.s,
00826                                                 fnd_codec.len, fnd_codec.s);
00827                                         foundone = 1;
00828                                 }
00829                         }
00830                         sdp_stream_num++;
00831                 }
00832                 sdp_session_num++;
00833         }
00834 
00835         return (foundone + ((foundone)?notfound:0));
00836 }
00837 
00841 static int w_sdp_with_codecs_by_id(sip_msg_t* msg, char* codecs, char *bar)
00842 {
00843         str lcodecs = {0, 0};
00844         int ret;
00845 
00846         if(codecs==0)
00847         {
00848                 LM_ERR("invalid parameters\n");
00849                 return -1;
00850         }
00851 
00852         if(fixup_get_svalue(msg, (gparam_p)codecs, &lcodecs)!=0)
00853         {
00854                 LM_ERR("unable to get the codecs\n");
00855                 return -1;
00856         }
00857 
00858         ret = sdp_with_codecs_by_id(msg, &lcodecs);
00859         /* ret: -1 error; 0 not found */
00860         if(ret<=0)
00861                 return (ret - 1);
00862         return ret;
00863 }
00864 
00868 static int w_sdp_with_codecs_by_name(sip_msg_t* msg, char* codecs, char *bar)
00869 {
00870         str lcodecs = {0, 0};
00871         str idslist;
00872         sdp_info_t *sdp = NULL;
00873         int ret;
00874 
00875         if(codecs==0)
00876         {
00877                 LM_ERR("invalid parameters\n");
00878                 return -1;
00879         }
00880 
00881         if(fixup_get_svalue(msg, (gparam_p)codecs, &lcodecs)!=0)
00882         {
00883                 LM_ERR("unable to get the codecs\n");
00884                 return -1;
00885         }
00886 
00887         if(parse_sdp(msg) < 0) {
00888                 LM_ERR("Unable to parse sdp\n");
00889                 return -1;
00890         }
00891 
00892         sdp = (sdp_info_t*)msg->body;
00893 
00894         if(sdp==NULL) {
00895                 LM_DBG("No sdp body\n");
00896                 return -1;
00897         }
00898 
00899         if(sdpops_build_ids_list(sdp, &lcodecs, &idslist)<0)
00900                 return -1;
00901 
00902         ret = sdp_with_codecs_by_id(msg, &idslist);
00903         /* ret: -1 error; 0 not found */
00904         if(ret<=0)
00905                 return (ret - 1);
00906         return ret;
00907 }
00908 
00912 static int w_sdp_print(sip_msg_t* msg, char* level, char *bar)
00913 {
00914         sdp_info_t *sdp = NULL;
00915         int llevel = L_DBG;
00916 
00917         if(parse_sdp(msg) < 0) {
00918                 LM_ERR("Unable to parse sdp\n");
00919                 return -1;
00920         }
00921 
00922         if(fixup_get_ivalue(msg, (gparam_p)level, &llevel)!=0)
00923         {
00924                 LM_ERR("unable to get the debug level value\n");
00925                 return -1;
00926         }
00927 
00928         sdp = (sdp_info_t*)msg->body;
00929 
00930         print_sdp(sdp, llevel);
00931         return 1;
00932 }
00933 
00934 
00938 static int w_get_sdp(sip_msg_t* msg, char *avp)
00939 {
00940         sdp_info_t *sdp = NULL;
00941         int_str avp_val;
00942         int_str avp_name;
00943         static unsigned short avp_type = 0;
00944         str s;
00945         pv_spec_t avp_spec;
00946         int sdp_missing=1;
00947         
00948         s.s = avp; s.len = strlen(s.s);
00949         if (pv_parse_spec(&s, &avp_spec)==0
00950                         || avp_spec.type!=PVT_AVP) {
00951                 LM_ERR("malformed or non AVP %s AVP definition\n", avp);
00952                 return -1;
00953         }
00954 
00955         if(pv_get_avp_name(0, &avp_spec.pvp, &avp_name, &avp_type)!=0)
00956         {
00957                 LM_ERR("[%s]- invalid AVP definition\n", avp);
00958                 return -1;
00959         }
00960 
00961         sdp_missing = parse_sdp(msg);
00962         if(sdp_missing < 0) {
00963                 LM_ERR("Unable to parse sdp\n");
00964                 return -1;
00965         }
00966         sdp = (sdp_info_t*)msg->body;
00967         
00968         if (sdp_missing) {
00969                 avp_val.s.s = NULL;
00970                 avp_val.s.len = 0;
00971                 LM_DBG("No SDP\n");
00972         } else {
00973                 avp_val.s.s = pkg_malloc(sdp->raw_sdp.len);
00974                 avp_val.s.len = sdp->raw_sdp.len;
00975                 if (avp_val.s.s == NULL)
00976                 {
00977                   LM_ERR("Failed to alloc memory for SDP");
00978                   return -1;
00979                 }
00980                 memcpy(avp_val.s.s, sdp->raw_sdp.s, avp_val.s.len);
00981                 LM_DBG("Found SDP %.*s\n", sdp->raw_sdp.len, sdp->raw_sdp.s);
00982         }
00983         if (add_avp(AVP_VAL_STR | avp_type, avp_name, avp_val) != 0)
00984         {
00985           LM_ERR("Failed to add SDP avp");
00986           return -1;
00987         }
00988         
00989         return 1;
00990 }
00991 
00995 int bind_sdpops(struct sdpops_binds *sob){
00996         if (sob == NULL) {
00997                 LM_WARN("bind_sdpops: Cannot load sdpops API into a NULL pointer\n");
00998                 return -1;
00999         }
01000         sob->sdp_with_media = sdp_with_media;
01001         return 0;
01002 }