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
00029
00030 #include <stdio.h>
00031 #include <string.h>
00032 #include <stdlib.h>
00033
00034 #include "../../parser/parser_f.h"
00035 #include "../../parser/sdp/sdp.h"
00036 #include "../../ut.h"
00037 #include "../../dprint.h"
00038 #include "../dialog/dlg_hash.h"
00039
00040 #include "qos_mi.h"
00041 #include "qos_handlers.h"
00042 #include "qos_ctx_helpers.h"
00043
00044
00045
00046
00047
00048 extern struct dlg_binds *dlg_binds;
00049
00050
00051
00052
00053
00054
00055 static void setup_dialog_callbacks(struct dlg_cell *did, qos_ctx_t *ctx);
00056
00057 static void qos_dialog_destroy_CB(struct dlg_cell* did, int type, struct dlg_cb_params * params);
00058 static void qos_dialog_request_CB(struct dlg_cell* did, int type, struct dlg_cb_params * params);
00059 static void qos_dialog_response_CB(struct dlg_cell* did, int type,struct dlg_cb_params * params);
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079 static void setup_dialog_callbacks(struct dlg_cell *did, qos_ctx_t *ctx)
00080 {
00081 dlg_binds->register_dlgcb(did, DLGCB_REQ_WITHIN,
00082 qos_dialog_request_CB, (void *)ctx, NULL);
00083
00084 dlg_binds->register_dlgcb(did, DLGCB_RESPONSE_FWDED|DLGCB_RESPONSE_WITHIN,
00085 qos_dialog_response_CB, (void *)ctx, NULL);
00086
00087 dlg_binds->register_dlgcb(did, DLGCB_DESTROY,
00088 qos_dialog_destroy_CB, (void *)ctx, NULL);
00089
00090 dlg_binds->register_dlgcb(did, DLGCB_MI_CONTEXT,
00091 qos_dialog_mi_context_CB, (void *)ctx, NULL);
00092
00093 return;
00094 }
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113 void qos_dialog_created_CB(struct dlg_cell *did, int type, struct dlg_cb_params * params)
00114 {
00115 qos_ctx_t *qos_ctx = NULL;
00116 struct sip_msg* msg = params->msg;
00117 unsigned int dir = params->direction, role, other_role;
00118
00119 if (dir == DLG_DIR_UPSTREAM) {
00120 role = QOS_CALLEE;
00121 other_role = QOS_CALLER;
00122 } else if (dir == DLG_DIR_DOWNSTREAM) {
00123 role = QOS_CALLER;
00124 other_role = QOS_CALLEE;
00125 } else {
00126 LM_ERR("Unknown dir %d\n", dir);
00127 return;
00128 }
00129
00130 if (msg == NULL || msg == FAKED_REPLY) {
00131 LM_ERR("Improper msg\n");
00132 return;
00133 }
00134
00135
00136 if (msg->first_line.type != SIP_REQUEST ||
00137 msg->first_line.u.request.method_value != METHOD_INVITE) {
00138 LM_WARN("Dialog create callback called with a non-INVITE req.\n");
00139 return;
00140 }
00141
00142 qos_ctx = build_new_qos_ctx();
00143 if (qos_ctx==NULL) {
00144
00145 return;
00146 }
00147
00148 LM_DBG("setup_dialog_callbacks( %p , %p )\n", did, qos_ctx);
00149 setup_dialog_callbacks(did, qos_ctx);
00150
00151 run_create_cbs(qos_ctx, msg);
00152
00153 if (0 == parse_sdp(msg)) {
00154 lock_get(&qos_ctx->lock);
00155 add_sdp(qos_ctx, dir, msg, role, other_role);
00156 lock_release(&qos_ctx->lock);
00157 }
00158
00159
00160 return;
00161 }
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171 static void qos_dialog_destroy_CB(struct dlg_cell* did, int type, struct dlg_cb_params * params)
00172 {
00173 struct sip_msg* msg = params->msg;
00174 qos_ctx_t* qos_ctx = (qos_ctx_t*)*(params->param);
00175
00176
00177 run_qos_callbacks(QOSCB_TERMINATED, qos_ctx, NULL, 0, msg);
00178
00179
00180 if (qos_ctx) {
00181 destroy_qos_ctx(qos_ctx);
00182 params->param = NULL;
00183 }
00184 return;
00185 }
00186
00187
00188
00189
00190
00191
00192
00193
00194 static void qos_dialog_request_CB(struct dlg_cell* did, int type, struct dlg_cb_params * params)
00195 {
00196 struct sip_msg* msg = params->msg;
00197 unsigned int dir = params->direction, role, other_role;
00198 qos_ctx_t* qos_ctx = (qos_ctx_t*)*(params->param);
00199
00200 if (dir == DLG_DIR_UPSTREAM) {
00201 role = QOS_CALLEE;
00202 other_role = QOS_CALLER;
00203 } else if (dir == DLG_DIR_DOWNSTREAM) {
00204 role = QOS_CALLER;
00205 other_role = QOS_CALLEE;
00206 } else {
00207 LM_ERR("Unknown dir %d\n", dir);
00208 return;
00209 }
00210
00211 if (msg->first_line.type == SIP_REQUEST) {
00212 if ( (msg->first_line.u.request.method_value == METHOD_INVITE) ||
00213 (msg->first_line.u.request.method_value == METHOD_UPDATE) ||
00214 (msg->first_line.u.request.method_value == METHOD_ACK) ||
00215 (msg->first_line.u.request.method_value == METHOD_PRACK)) {
00216 if (0 == parse_sdp(msg)) {
00217 lock_get(&qos_ctx->lock);
00218 add_sdp(qos_ctx, dir, msg, role, other_role);
00219 lock_release(&qos_ctx->lock);
00220 }
00221 } else {
00222 LM_DBG("Ignoring non-carrying SDP req\n");
00223 return;
00224 }
00225 } else {
00226 LM_ERR("not a SIP_REQUEST\n");
00227 return;
00228 }
00229
00230 return;
00231 }
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243 static void qos_dialog_response_CB(struct dlg_cell* did, int type, struct dlg_cb_params * params)
00244 {
00245 struct sip_msg* msg = params->msg;
00246 unsigned int dir = params->direction, role, other_role;
00247 qos_ctx_t* qos_ctx = (qos_ctx_t*)*(params->param);
00248
00249 if (dir == DLG_DIR_UPSTREAM) {
00250 role = QOS_CALLEE;
00251 other_role = QOS_CALLER;
00252 } else if (dir == DLG_DIR_DOWNSTREAM) {
00253 role = QOS_CALLER;
00254 other_role = QOS_CALLEE;
00255 } else {
00256 LM_ERR("Unknown dir %d\n", dir);
00257 return;
00258 }
00259
00260 if (msg->first_line.type == SIP_REPLY) {
00261 if (msg->first_line.u.reply.statuscode > 100 &&
00262 msg->first_line.u.reply.statuscode < 300) {
00263 if (0 == parse_sdp(msg)) {
00264 lock_get(&qos_ctx->lock);
00265 add_sdp(qos_ctx, dir, msg, role, other_role);
00266 lock_release(&qos_ctx->lock);
00267 }
00268 } else if (msg->first_line.u.reply.statuscode > 399 &&
00269 msg->first_line.u.reply.statuscode < 700) {
00270 lock_get(&qos_ctx->lock);
00271 remove_sdp(qos_ctx, dir, msg, role, other_role);
00272 lock_release(&qos_ctx->lock);
00273 }
00274 } else {
00275 LM_ERR("not a SIP_REPLY\n");
00276 return;
00277 }
00278
00279 return;
00280 }
00281