00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "../../mem/mem.h"
00029 #include "../../mem/shm_mem.h"
00030 #include "../../parser/sdp/sdp_cloner.h"
00031 #include "../dialog/dlg_hash.h"
00032 #include "qos_ctx_helpers.h"
00033
00034 #define ERROR_MATCH -1
00035 #define NO_INVITE_REQ_MATCH 0
00036 #define NO_INVITE_RESP_MATCH 1
00037 #define PENDING_MATCH 2
00038 #define NEGOTIATED_MATCH 3
00039 #define NO_ACK_REQ_MATCH 4
00040 #define NO_UPDATE_REQ_MATCH 7
00041 #define NO_UPDATE_RESP_MATCH 8
00042
00043
00044 #define N_UNKNOWN 0
00045
00046 #define N_INVITE_200OK 1
00047
00048 #define N_200OK_ACK 2
00049
00050
00051 #define N_183_PRACK 3
00052
00053 qos_ctx_t *build_new_qos_ctx(void) {
00054 qos_ctx_t *ctx = NULL;
00055
00056 ctx = (qos_ctx_t *)shm_malloc(sizeof(qos_ctx_t));
00057 if (ctx!=NULL) {
00058 memset(ctx, 0, sizeof(qos_ctx_t));
00059 } else {
00060 LM_ERR("No enough shared memory\n");
00061 return NULL;
00062 }
00063 if (!lock_init(&ctx->lock)) {
00064 shm_free(ctx);
00065 return NULL;
00066 }
00067 return ctx;
00068 }
00069
00070 void destroy_qos(qos_sdp_t *qos_sdp)
00071 {
00072 free_cloned_sdp_session(qos_sdp->sdp_session[0]);
00073 free_cloned_sdp_session(qos_sdp->sdp_session[1]);
00074 shm_free(qos_sdp);
00075
00076 return;
00077 }
00078
00079
00080 void print_qos_sdp(qos_sdp_t *qos_sdp)
00081 {
00082 if (qos_sdp == NULL) {
00083 return;
00084 }
00085 LM_DBG("[%p] prev->%p next->%p method_dir=%d method_id=%d method='%.*s' cseq='%.*s' negotiation=%d sdp[0:QOS_CALLER]=%p sdp[1:QOS_CALLEE]=%p\n",
00086 qos_sdp, qos_sdp->prev, qos_sdp->next, qos_sdp->method_dir, qos_sdp->method_id,
00087 qos_sdp->method.len ,qos_sdp->method.s, qos_sdp->cseq.len, qos_sdp->cseq.s,
00088 qos_sdp->negotiation, qos_sdp->sdp_session[0], qos_sdp->sdp_session[1]);
00089
00090
00091 }
00092
00093
00094
00095
00096
00097
00098
00099
00100 int find_qos_sdp(qos_ctx_t *qos_ctx, unsigned int dir, unsigned int other_role, str *cseq_number, int cseq_method_id, sdp_session_cell_t *session, struct sip_msg *_m, qos_sdp_t **_qos_sdp)
00101 {
00102 qos_sdp_t *qos_sdp;
00103 str *received_cnt_disp, *local_cnt_disp;
00104
00105 LM_DBG("received session: %p and other_role: %s\n", session, (other_role==QOS_CALLER)?"QOS_CALLER":"QOS_CALLEE");
00106
00107 switch (_m->first_line.type) {
00108 case SIP_REQUEST:
00109 switch (cseq_method_id) {
00110 case METHOD_INVITE:
00111 return NO_INVITE_REQ_MATCH;
00112 break;
00113 case METHOD_ACK:
00114
00115 qos_sdp = qos_ctx->pending_sdp;
00116 LM_DBG("searching the negotiated_sdp: %p\n", qos_sdp);
00117 while (qos_sdp) {
00118 if (METHOD_INVITE == qos_sdp->method_id && dir != qos_sdp->method_dir && qos_sdp->negotiation == N_200OK_ACK &&
00119 cseq_number->len == qos_sdp->cseq.len && 0 == strncmp(cseq_number->s, qos_sdp->cseq.s, cseq_number->len)) {
00120 LM_DBG("method_id, dir and cseq match with previous session %p->%p\n",
00121 qos_sdp, qos_sdp->sdp_session[other_role]);
00122
00123 if (qos_sdp->sdp_session[other_role] != NULL) {
00124 local_cnt_disp = &(qos_sdp->sdp_session[other_role]->cnt_disp);
00125 received_cnt_disp = &(session->cnt_disp);
00126 if (local_cnt_disp->len == received_cnt_disp->len) {
00127 if (local_cnt_disp->len == 0) {
00128 LM_DBG("no cnt disp header ... => %p\n", qos_sdp);
00129 *_qos_sdp = qos_sdp;
00130 return PENDING_MATCH;
00131 } else if (0==strncmp(local_cnt_disp->s, received_cnt_disp->s, local_cnt_disp->len)) {
00132 LM_DBG("'%.*s' => %p\n", local_cnt_disp->len, local_cnt_disp->s, qos_sdp);
00133 *_qos_sdp = qos_sdp;
00134 return PENDING_MATCH;
00135 }
00136 } else if (received_cnt_disp->len == 0 && local_cnt_disp->len == 7 &&
00137 0==strncmp(local_cnt_disp->s, "session", 7)) {
00138
00139 *_qos_sdp = qos_sdp;
00140 return PENDING_MATCH;
00141 }
00142 } else {
00143 LM_ERR("skipping search for null sdp for %s\n", (other_role==QOS_CALLER)?"QOS_CALLER":"QOS_CALLEE");
00144 }
00145 }
00146 qos_sdp = qos_sdp->next;
00147 }
00148 return NO_ACK_REQ_MATCH;
00149 break;
00150 case METHOD_UPDATE:
00151 return NO_UPDATE_REQ_MATCH;
00152 break;
00153 case METHOD_PRACK:
00154 LM_ERR("PRACK not implemented yet\n");
00155 return ERROR_MATCH;
00156 break;
00157 default:
00158 LM_ERR("Unexpected method id %d\n", cseq_method_id);
00159 return ERROR_MATCH;
00160 }
00161 break;
00162 case SIP_REPLY:
00163 switch (cseq_method_id) {
00164 case METHOD_INVITE:
00165
00166 qos_sdp = qos_ctx->pending_sdp;
00167 while (qos_sdp) {
00168
00169 if (cseq_method_id == qos_sdp->method_id && dir != qos_sdp->method_dir &&
00170 qos_sdp->negotiation == N_INVITE_200OK && cseq_number->len == qos_sdp->cseq.len &&
00171 0 == strncmp(cseq_number->s, qos_sdp->cseq.s, cseq_number->len)) {
00172 LM_DBG("method_id, dir and cseq match with previous session %p->%p\n",
00173 qos_sdp, qos_sdp->sdp_session[other_role]);
00174
00175 if (qos_sdp->sdp_session[other_role] != NULL) {
00176 local_cnt_disp = &(qos_sdp->sdp_session[other_role]->cnt_disp);
00177 received_cnt_disp = &(session->cnt_disp);
00178 if (local_cnt_disp->len == received_cnt_disp->len) {
00179 if (local_cnt_disp->len == 0) {
00180 LM_DBG("no cnt disp header ... => %p\n", qos_sdp);
00181 *_qos_sdp = qos_sdp;
00182 return PENDING_MATCH;
00183 } else if (0==strncmp(local_cnt_disp->s, received_cnt_disp->s, local_cnt_disp->len)) {
00184 LM_DBG("'%.*s' => %p\n", local_cnt_disp->len, local_cnt_disp->s, qos_sdp);
00185 *_qos_sdp = qos_sdp;
00186 return PENDING_MATCH;
00187 }
00188 } else if (received_cnt_disp->len == 0 && local_cnt_disp->len == 7 &&
00189 0==strncmp(local_cnt_disp->s, "session", 7)) {
00190
00191 *_qos_sdp = qos_sdp;
00192 return PENDING_MATCH;
00193 }
00194 } else {
00195 LM_ERR("skipping search for null sdp for %s\n", (other_role==QOS_CALLER)?"QOS_CALLER":"QOS_CALLEE");
00196 }
00197 }
00198 qos_sdp = qos_sdp->next;
00199 }
00200
00201 qos_sdp = qos_ctx->negotiated_sdp;
00202 LM_DBG("searching the negotiated_sdp: %p\n", qos_sdp);
00203 while (qos_sdp) {
00204
00205 if (cseq_method_id == qos_sdp->method_id && dir != qos_sdp->method_dir &&
00206 qos_sdp->negotiation == N_INVITE_200OK && cseq_number->len == qos_sdp->cseq.len &&
00207 0 == strncmp(cseq_number->s, qos_sdp->cseq.s, cseq_number->len)) {
00208 LM_DBG("method_id, dir and cseq match with previous session %p\n", qos_sdp->sdp_session[other_role]);
00209 if (qos_sdp->sdp_session[other_role] != NULL) {
00210 local_cnt_disp = &(qos_sdp->sdp_session[other_role]->cnt_disp);
00211 received_cnt_disp = &(session->cnt_disp);
00212 if (local_cnt_disp->len == received_cnt_disp->len) {
00213 if (local_cnt_disp->len == 0) {
00214 LM_DBG("no cnt disp header ... => %p\n", qos_sdp);
00215 *_qos_sdp = qos_sdp;
00216 return NEGOTIATED_MATCH;
00217 } else if (0==strncmp(local_cnt_disp->s, received_cnt_disp->s, local_cnt_disp->len)) {
00218 LM_DBG("'%.*s' => %p\n", local_cnt_disp->len, local_cnt_disp->s, qos_sdp);
00219 *_qos_sdp = qos_sdp;
00220 return NEGOTIATED_MATCH;
00221 }
00222 } else if (received_cnt_disp->len == 0 && local_cnt_disp->len == 7 &&
00223 0==strncasecmp(local_cnt_disp->s, "session", 7)) {
00224
00225 *_qos_sdp = qos_sdp;
00226 return NEGOTIATED_MATCH;
00227 }
00228 } else {
00229 LM_ERR("skipping search for null sdp for %s\n", (other_role==QOS_CALLER)?"QOS_CALLER":"QOS_CALLEE");
00230 }
00231 }
00232 qos_sdp = qos_sdp->next;
00233 }
00234 return NO_INVITE_RESP_MATCH;
00235 break;
00236 case METHOD_UPDATE:
00237 LM_ERR("FIXME\n");
00238 return NO_UPDATE_RESP_MATCH;
00239 break;
00240 default:
00241 LM_ERR("Unexpected reply for method id %d\n", cseq_method_id);
00242 return ERROR_MATCH;
00243 }
00244 break;
00245 default:
00246 LM_ERR("Unknown SIP message type: %d\n", _m->first_line.type);
00247 return ERROR_MATCH;
00248 }
00249 LM_ERR("FIXME: out of case\n");
00250 return ERROR_MATCH;
00251 }
00252
00253 void link_pending_qos_sdp(qos_ctx_t *qos_ctx, qos_sdp_t *qos_sdp)
00254 {
00255 if (qos_sdp->prev != NULL) LM_ERR("got qos_sdp->prev=%p\n", qos_sdp->prev);
00256 if (qos_sdp->next != NULL) LM_ERR("got qos_sdp->next=%p\n", qos_sdp->next);
00257
00258 if (qos_ctx->pending_sdp) {
00259 LM_DBG("Adding pending qos_sdp: %p\n", qos_sdp);
00260 if (qos_ctx->pending_sdp->prev != NULL) LM_ERR("got qos_ctx->pending_sdp->prev=%p\n", qos_ctx->pending_sdp->prev);
00261 qos_sdp->next = qos_ctx->pending_sdp;
00262 qos_ctx->pending_sdp->prev = qos_sdp;
00263 qos_ctx->pending_sdp = qos_sdp;
00264 } else {
00265 LM_DBG("Inserting pending qos_sdp: %p\n", qos_sdp);
00266 qos_ctx->pending_sdp = qos_sdp;
00267 }
00268 }
00269
00270 void unlink_pending_qos_sdp(qos_ctx_t *qos_ctx, qos_sdp_t *qos_sdp)
00271 {
00272 if (qos_sdp->next)
00273 qos_sdp->next->prev = qos_sdp->prev;
00274
00275 if (qos_sdp->prev)
00276 qos_sdp->prev->next = qos_sdp->next;
00277 else
00278 qos_ctx->pending_sdp = qos_sdp->next;
00279
00280 qos_sdp->next = qos_sdp->prev = NULL;
00281 }
00282 void unlink_negotiated_qos_sdp(qos_ctx_t *qos_ctx, qos_sdp_t *qos_sdp)
00283 {
00284 if (qos_sdp->next)
00285 qos_sdp->next->prev = qos_sdp->prev;
00286
00287 if (qos_sdp->prev)
00288 qos_sdp->prev->next = qos_sdp->next;
00289 else
00290 qos_ctx->negotiated_sdp = qos_sdp->next;
00291
00292 qos_sdp->next = qos_sdp->prev = NULL;
00293 }
00294
00295
00296 void link_negotiated_qos_sdp_and_run_cb(qos_ctx_t *qos_ctx, qos_sdp_t *qos_sdp, unsigned int role, struct sip_msg *_m)
00297 {
00298 qos_sdp_t *next_qos_sdp;
00299 qos_sdp_t *temp_qos_sdp = qos_ctx->negotiated_sdp;
00300
00301 if (qos_sdp->prev != NULL) LM_ERR("got qos_sdp->prev=%p\n", qos_sdp->prev);
00302 if (qos_sdp->next != NULL) LM_ERR("got qos_sdp->next=%p\n", qos_sdp->next);
00303
00304 if (temp_qos_sdp) {
00305 while (temp_qos_sdp) {
00306 next_qos_sdp = temp_qos_sdp->next;
00307 if (qos_sdp->negotiation == temp_qos_sdp->negotiation) {
00308 LM_DBG("run_qos_callbacks(QOSCB_REMOVE_SDP, qos_ctx=%p, temp_qos_sdp=%p, role=%d, _m=%p)\n",
00309 qos_ctx, temp_qos_sdp, role, _m);
00310 run_qos_callbacks(QOSCB_REMOVE_SDP, qos_ctx, temp_qos_sdp, role, _m);
00311
00312 unlink_negotiated_qos_sdp(qos_ctx, temp_qos_sdp);
00313 destroy_qos(temp_qos_sdp);
00314 break;
00315 }
00316 temp_qos_sdp = next_qos_sdp;
00317 }
00318 if (qos_ctx->negotiated_sdp) {
00319 LM_DBG("Adding negotiated qos_sdp: %p\n", qos_sdp);
00320 if (qos_ctx->negotiated_sdp->prev != NULL) LM_ERR("got qos_ctx->negotiated_sdp->prev=%p\n", qos_ctx->negotiated_sdp->prev);
00321 qos_sdp->next = qos_ctx->negotiated_sdp;
00322 qos_ctx->negotiated_sdp->prev = qos_sdp;
00323 qos_ctx->negotiated_sdp = qos_sdp;
00324 } else {
00325 LM_DBG("Inserting negotiated qos_sdp: %p\n", qos_sdp);
00326 qos_ctx->negotiated_sdp = qos_sdp;
00327 }
00328 } else {
00329 LM_DBG("Inserting first negotiated qos_sdp: %p\n", qos_sdp);
00330 qos_ctx->negotiated_sdp = qos_sdp;
00331 }
00332
00333 LM_DBG("run_qos_callbacks(QOSCB_UPDATE_SDP, qos_ctx=%p, qos_sdp=%p, role=%d, _m=%p)\n",
00334 qos_ctx, qos_sdp, role, _m);
00335 run_qos_callbacks(QOSCB_UPDATE_SDP, qos_ctx, qos_sdp, role, _m);
00336 }
00337
00338 int add_pending_sdp_session(qos_ctx_t *qos_ctx, unsigned int dir, str *cseq_number, str *cseq_method, int cseq_method_id,
00339 unsigned int role, unsigned int negotiation, sdp_session_cell_t *session, struct sip_msg *_m)
00340 {
00341 unsigned int len;
00342 sdp_session_cell_t *cloned_session;
00343 qos_sdp_t *qos_sdp;
00344 char *p;
00345
00346 len = sizeof(qos_sdp_t) + cseq_method->len + cseq_number->len;
00347 qos_sdp = (qos_sdp_t *)shm_malloc(len);
00348 LM_DBG("alloc qos_sdp: %p\n", qos_sdp);
00349 if (qos_sdp==NULL) {
00350 LM_ERR("oom %d\n", len);
00351 return -1;
00352 } else {
00353 memset(qos_sdp, 0, len);
00354 LM_DBG("Allocated memory for qos_sdp: %p\n", qos_sdp);
00355
00356 cloned_session = clone_sdp_session_cell(session);
00357 if (cloned_session==NULL) {
00358 shm_free(qos_sdp);
00359 LM_DBG("free qos_sdp: %p\n", qos_sdp);
00360 return -1;
00361 }
00362 qos_sdp->sdp_session[role] = cloned_session;
00363
00364 LM_DBG("qos_sdp->sdp_session[%d]=%p\n", role, qos_sdp->sdp_session[role]);
00365
00366 if (_m->first_line.type == SIP_REQUEST) {
00367 qos_sdp->method_dir = dir;
00368 } else {
00369
00370
00371 if (dir==DLG_DIR_UPSTREAM)
00372 qos_sdp->method_dir = DLG_DIR_DOWNSTREAM;
00373 else
00374 qos_sdp->method_dir = DLG_DIR_UPSTREAM;
00375 }
00376 qos_sdp->method_id = cseq_method_id;
00377 qos_sdp->negotiation = negotiation;
00378 p = (char*)(qos_sdp+1);
00379
00380 qos_sdp->method.s = p;
00381 qos_sdp->method.len = cseq_method->len;
00382 memcpy( p, cseq_method->s, cseq_method->len);
00383 p += cseq_method->len;
00384
00385 qos_sdp->cseq.s = p;
00386 qos_sdp->cseq.len = cseq_number->len;
00387 memcpy( p,cseq_number->s, cseq_number->len);
00388
00389
00390 link_pending_qos_sdp(qos_ctx, qos_sdp);
00391
00392 LM_DBG("run_qos_callbacks(QOSCB_ADD_SDP, qos_ctx=%p, qos_sdp=%p, role=%d, _m=%p)\n",
00393 qos_ctx, qos_sdp, role, _m);
00394 run_qos_callbacks(QOSCB_ADD_SDP, qos_ctx, qos_sdp, role, _m);
00395 }
00396 return 0;
00397 }
00398
00399
00400
00401
00402
00403
00404
00405 void add_sdp(qos_ctx_t *qos_ctx, unsigned int dir, struct sip_msg *_m, unsigned int role, unsigned int other_role)
00406 {
00407 qos_sdp_t *qos_sdp;
00408 sdp_session_cell_t *recv_session;
00409 str *cseq_number, *cseq_method;
00410 int cseq_method_id, sdp_match;
00411
00412 if ( (!_m->cseq && parse_headers(_m,HDR_CSEQ_F,0)<0) || !_m->cseq || !_m->cseq->parsed) {
00413 LM_ERR("bad sip message or missing CSeq hdr\n");
00414 return;
00415 }
00416
00417 cseq_number = &((get_cseq(_m))->number);
00418 cseq_method = &((get_cseq(_m))->method);
00419 cseq_method_id = (get_cseq(_m))->method_id;
00420
00421 LM_DBG("cseq=`%.*s' `%.*s' and dir=%d\n",
00422 cseq_number->len, cseq_number->s,
00423 cseq_method->len, cseq_method->s, dir);
00424
00425
00426 recv_session = _m->sdp->sessions;
00427 while(recv_session) {
00428 qos_sdp = NULL;
00429 sdp_match = find_qos_sdp(qos_ctx, dir, other_role, cseq_number, cseq_method_id, recv_session, _m, &qos_sdp);
00430
00431 switch (sdp_match) {
00432 case NO_INVITE_REQ_MATCH:
00433 if (0!=add_pending_sdp_session( qos_ctx, dir, cseq_number, cseq_method, cseq_method_id, role, N_INVITE_200OK, recv_session, _m)) {
00434 LM_ERR("Unable to add new sdp session\n");
00435 goto error;
00436 }
00437
00438 break;
00439 case NO_INVITE_RESP_MATCH:
00440 if (0!=add_pending_sdp_session( qos_ctx, dir, cseq_number, cseq_method, cseq_method_id, role, N_200OK_ACK, recv_session, _m)) {
00441 LM_ERR("Unable to add new sdp session\n");
00442 goto error;
00443 }
00444
00445 break;
00446 case ERROR_MATCH:
00447 case NO_ACK_REQ_MATCH:
00448 case NO_UPDATE_REQ_MATCH:
00449 case NO_UPDATE_RESP_MATCH:
00450 LM_ERR("error match: %d\n", sdp_match);
00451 break;
00452 case PENDING_MATCH:
00453 LM_DBG("we have a pending match: %p\n", qos_sdp);
00454
00455 qos_sdp->sdp_session[role] = clone_sdp_session_cell(recv_session);
00456 if (qos_sdp->sdp_session[role] == NULL) {
00457 LM_ERR("PENDING_MATCH:oom: Unable to add new sdp session\n");
00458 return;
00459 }
00460
00461
00462
00463
00464 unlink_pending_qos_sdp(qos_ctx, qos_sdp);
00465
00466 link_negotiated_qos_sdp_and_run_cb(qos_ctx, qos_sdp, role, _m);
00467
00468 break;
00469 case NEGOTIATED_MATCH:
00470 LM_DBG("we have a negotiated match: %p\n", qos_sdp);
00471
00472 if (qos_sdp->sdp_session[role]) {
00473 free_cloned_sdp_session(qos_sdp->sdp_session[role]);
00474 } else {
00475 LM_ERR("missing sdp_session for %s\n", (role==QOS_CALLER)?"QOS_CALLER":"QOS_CALLEE");
00476 }
00477
00478 qos_sdp->sdp_session[role] = clone_sdp_session_cell(recv_session);
00479 if (qos_sdp->sdp_session[role] == NULL) {
00480 LM_ERR("NEGOTIATED_MATCH:oom: Unable to add new sdp session\n");
00481 return;
00482 }
00483
00484 LM_DBG("run_qos_callbacks(QOSCB_UPDATE_SDP, qos_ctx=%p, qos_sdp=%p, role=%d, _m=%p)\n",
00485 qos_ctx, qos_sdp, role, _m);
00486 run_qos_callbacks(QOSCB_UPDATE_SDP, qos_ctx, qos_sdp, role, _m);
00487
00488 break;
00489 default:
00490 LM_CRIT("Undefined return code from find_qos_sdp(): %d\n", sdp_match);
00491 }
00492 recv_session = recv_session->next;
00493 }
00494
00495 return;
00496 error:
00497 shm_free(qos_sdp);
00498 LM_DBG("free qos_sdp: %p\n", qos_sdp);
00499 return;
00500 }
00501
00502
00503
00504
00505 void remove_sdp(qos_ctx_t *qos_ctx, unsigned int dir, struct sip_msg *_m, unsigned int role, unsigned int other_role)
00506 {
00507 str *cseq_number, *cseq_method;
00508 int cseq_method_id;
00509 qos_sdp_t *qos_sdp;
00510
00511 if ( (!_m->cseq && parse_headers(_m,HDR_CSEQ_F,0)<0) || !_m->cseq || !_m->cseq->parsed) {
00512 LM_ERR("bad sip message or missing CSeq hdr\n");
00513 return;
00514 }
00515
00516 cseq_number = &((get_cseq(_m))->number);
00517 cseq_method = &((get_cseq(_m))->method);
00518 cseq_method_id = (get_cseq(_m))->method_id;
00519
00520 if (_m->first_line.type == SIP_REPLY) {
00521 switch (cseq_method_id) {
00522 case METHOD_INVITE:
00523 case METHOD_UPDATE:
00524
00525 qos_sdp = qos_ctx->pending_sdp;
00526 while (qos_sdp) {
00527 qos_sdp = qos_sdp->next;
00528 if (cseq_method_id == qos_sdp->method_id && dir != qos_sdp->method_dir &&
00529 qos_sdp->negotiation == N_INVITE_200OK && cseq_number->len == qos_sdp->cseq.len &&
00530 0 == strncmp(cseq_number->s, qos_sdp->cseq.s, cseq_number->len)) {
00531 LM_DBG("method_id, dir and cseq match with previous session %p->%p\n",
00532 qos_sdp, qos_sdp->sdp_session[other_role]);
00533
00534 if (qos_sdp->sdp_session[other_role] != NULL) {
00535 LM_DBG("run_qos_callbacks(QOSCB_REMOVE_SDP, qos_ctx=%p, qos_sdp=%p, role=%d, _m=%p)\n",
00536 qos_ctx, qos_sdp, role, _m);
00537 run_qos_callbacks(QOSCB_REMOVE_SDP, qos_ctx, qos_sdp, role, _m);
00538 unlink_negotiated_qos_sdp(qos_ctx, qos_sdp);
00539
00540 destroy_qos(qos_sdp);
00541 continue;
00542 } else {
00543 LM_ERR("skipping search for null sdp for %s\n", (other_role==QOS_CALLER)?"QOS_CALLER":"QOS_CALLEE");
00544 }
00545 }
00546 }
00547 break;
00548 default:
00549 LM_ERR("Unexpected method id %d\n", cseq_method_id);
00550 }
00551 } else {
00552 LM_ERR("we remove sdp only for a SIP_REPLY, not for a %d\n",
00553 _m->first_line.type);
00554 }
00555
00556 return;
00557 }
00558
00559 void destroy_qos_ctx(qos_ctx_t *qos_ctx)
00560 {
00561 qos_sdp_t * qos_sdp, * next_qos_sdp;
00562
00563 lock_get(&qos_ctx->lock);
00564
00565 qos_sdp = qos_ctx->pending_sdp;
00566 while (qos_sdp) {
00567 next_qos_sdp = qos_sdp->next;
00568 destroy_qos(qos_sdp);
00569 qos_sdp = next_qos_sdp;
00570 }
00571 qos_sdp = qos_ctx->negotiated_sdp;
00572 while (qos_sdp) {
00573 next_qos_sdp = qos_sdp->next;
00574 destroy_qos(qos_sdp);
00575 qos_sdp = next_qos_sdp;
00576 }
00577
00578 lock_release(&qos_ctx->lock);
00579
00580 lock_destroy(&qos_ctx->lock);
00581
00582 LM_DBG("free qos_ctx: %p\n", qos_ctx);
00583 shm_free(qos_ctx);
00584
00585 return;
00586 }
00587