3 * Copyright (C) 2009 Sippy Software, Inc., http://www.sippysoft.com
5 * This file is part of SIP-Router, a free SIP server.
7 * SIP-Router is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version
12 * SIP-Router is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include "../../action.h"
24 #include "../../mem/mem.h"
25 #include "../../sr_module.h"
26 #include "../../parser/msg_parser.h"
29 #include "structmember.h"
32 #define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
40 static PyTypeObject MSGtype;
42 #define is_msgobject(v) ((v)->ob_type == &MSGtype)
45 newmsgobject(struct sip_msg *msg)
49 msgp = PyObject_New(msgobject, &MSGtype);
58 msg_invalidate(msgobject *self)
65 msg_dealloc(msgobject *msgp)
72 msg_copy(msgobject *self)
76 if ((msgp = newmsgobject(self->msg)) == NULL)
79 return (PyObject *)msgp;
83 msg_rewrite_ruri(msgobject *self, PyObject *args)
87 struct run_act_ctx ra_ctx;
89 if (self->msg == NULL) {
90 PyErr_SetString(PyExc_RuntimeError, "self->msg is NULL");
95 if ((self->msg->first_line).type != SIP_REQUEST) {
96 PyErr_SetString(PyExc_RuntimeError, "Not a request message - "
97 "rewrite is not possible.\n");
102 if(!PyArg_ParseTuple(args, "s:rewrite_ruri", &ruri))
105 memset(&act, '\0', sizeof(act));
107 act.type = SET_URI_T;
108 act.val[0].type = STR_ST;
109 act.val[0].u.str.s = ruri;
110 act.val[0].u.str.len = strlen(ruri);
112 init_run_actions_ctx(&ra_ctx);
113 if (do_action(&ra_ctx, &act, self->msg) < 0) {
114 LM_ERR("Error in do_action\n");
115 PyErr_SetString(PyExc_RuntimeError, "Error in do_action\n");
123 msg_set_dst_uri(msgobject *self, PyObject *args)
127 if (self->msg == NULL) {
128 PyErr_SetString(PyExc_RuntimeError, "self->msg is NULL");
133 if ((self->msg->first_line).type != SIP_REQUEST) {
134 PyErr_SetString(PyExc_RuntimeError, "Not a request message - "
135 "set destination is not possible.\n");
140 if(!PyArg_ParseTuple(args, "s:set_dst_uri", &ruri.s))
143 ruri.len = strlen(ruri.s);
145 if (set_dst_uri(self->msg, &ruri) < 0) {
146 LM_ERR("Error in set_dst_uri\n");
147 PyErr_SetString(PyExc_RuntimeError, "Error in set_dst_uri\n");
155 msg_getHeader(msgobject *self, PyObject *args)
157 struct hdr_field *hf;
160 if (self->msg == NULL) {
161 PyErr_SetString(PyExc_RuntimeError, "self->msg is NULL");
166 if(!PyArg_ParseTuple(args, "s:getHeader", &hname.s))
168 hname.len = strlen(hname.s);
170 parse_headers(self->msg, ~0, 0);
172 for (hf = self->msg->headers; hf != NULL; hf = hf->next) {
173 if (hname.len == hf->name.len &&
174 strncasecmp(hname.s, hf->name.s, hname.len) == 0) {
185 return PyString_FromStringAndSize(hbody->s, hbody->len);
189 msg_call_function(msgobject *self, PyObject *args)
192 char *fname, *arg1, *arg2;
193 union cmd_export_u* fexport;
195 struct run_act_ctx ra_ctx;
198 if (self->msg == NULL) {
199 PyErr_SetString(PyExc_RuntimeError, "self->msg is NULL");
204 i = PySequence_Size(args);
205 if (i < 1 || i > 3) {
206 PyErr_SetString(PyExc_RuntimeError, "call_function() should " \
207 "have from 1 to 3 arguments");
212 if(!PyArg_ParseTuple(args, "s|ss:call_function", &fname, &arg1, &arg2))
215 fexport = find_export_record(fname, i - 2, 0, &mod_ver);
216 if (fexport == NULL) {
217 PyErr_SetString(PyExc_RuntimeError, "no such function");
222 act = mk_action(MODULE2_T, 4 /* number of (type, value) pairs */,
223 MODEXP_ST, fexport, /* function */
224 NUMBER_ST, 2, /* parameter number */
225 STRING_ST, arg1, /* param. 1 */
226 STRING_ST, arg2 /* param. 2 */
230 PyErr_SetString(PyExc_RuntimeError,
231 "action structure could not be created");
236 if (fexport->v1.fixup != NULL) {
238 rval = fexport->v1.fixup(&(act->val[2].u.data), 2);
240 PyErr_SetString(PyExc_RuntimeError, "Error in fixup (2)");
244 act->val[2].type = MODFIXUP_ST;
247 rval = fexport->v1.fixup(&(act->val[1].u.data), 1);
249 PyErr_SetString(PyExc_RuntimeError, "Error in fixup (1)");
253 act->val[1].type = MODFIXUP_ST;
256 rval = fexport->v1.fixup(0, 0);
258 PyErr_SetString(PyExc_RuntimeError, "Error in fixup (0)");
265 init_run_actions_ctx(&ra_ctx);
266 rval = do_action(&ra_ctx, act, self->msg);
268 if ((act->val[2].type == MODFIXUP_ST) && (act->val[2].u.data)) {
269 pkg_free(act->val[2].u.data);
272 if ((act->val[1].type == MODFIXUP_ST) && (act->val[1].u.data)) {
273 pkg_free(act->val[1].u.data);
278 return PyInt_FromLong(rval);
281 PyDoc_STRVAR(copy_doc,
282 "copy() -> msg object\n\
284 Return a copy (``clone'') of the msg object.");
286 static PyMethodDef msg_methods[] = {
287 {"copy", (PyCFunction)msg_copy, METH_NOARGS, copy_doc},
288 {"rewrite_ruri", (PyCFunction)msg_rewrite_ruri, METH_VARARGS,
289 "Rewrite Request-URI."},
290 {"set_dst_uri", (PyCFunction)msg_set_dst_uri, METH_VARARGS,
291 "Set destination URI."},
292 {"getHeader", (PyCFunction)msg_getHeader, METH_VARARGS,
293 "Get SIP header field by name."},
294 {"call_function", (PyCFunction)msg_call_function, METH_VARARGS,
295 "Invoke function exported by the other module."},
296 {NULL, NULL, 0, NULL} /* sentinel */
300 msg_getType(msgobject *self, PyObject *unused)
304 if (self->msg == NULL) {
305 PyErr_SetString(PyExc_RuntimeError, "self->msg is NULL");
310 switch ((self->msg->first_line).type) {
312 rval = "SIP_REQUEST";
320 /* Shouldn't happen */
323 return PyString_FromString(rval);
327 msg_getMethod(msgobject *self, PyObject *unused)
331 if (self->msg == NULL) {
332 PyErr_SetString(PyExc_RuntimeError, "self->msg is NULL");
337 if ((self->msg->first_line).type != SIP_REQUEST) {
338 PyErr_SetString(PyExc_RuntimeError, "Not a request message - "
339 "no method available.\n");
343 rval = &((self->msg->first_line).u.request.method);
344 return PyString_FromStringAndSize(rval->s, rval->len);
348 msg_getStatus(msgobject *self, PyObject *unused)
352 if (self->msg == NULL) {
353 PyErr_SetString(PyExc_RuntimeError, "self->msg is NULL");
358 if ((self->msg->first_line).type != SIP_REPLY) {
359 PyErr_SetString(PyExc_RuntimeError, "Not a non-reply message - "
360 "no status available.\n");
365 rval = &((self->msg->first_line).u.reply.status);
366 return PyString_FromStringAndSize(rval->s, rval->len);
370 msg_getRURI(msgobject *self, PyObject *unused)
374 if (self->msg == NULL) {
375 PyErr_SetString(PyExc_RuntimeError, "self->msg is NULL");
380 if ((self->msg->first_line).type != SIP_REQUEST) {
381 PyErr_SetString(PyExc_RuntimeError, "Not a request message - "
382 "RURI is not available.\n");
387 rval = &((self->msg->first_line).u.request.uri);
388 return PyString_FromStringAndSize(rval->s, rval->len);
392 msg_get_src_address(msgobject *self, PyObject *unused)
394 PyObject *src_ip, *src_port, *pyRval;
396 if (self->msg == NULL) {
397 PyErr_SetString(PyExc_RuntimeError, "self->msg is NULL");
402 src_ip = PyString_FromString(ip_addr2a(&self->msg->rcv.src_ip));
403 if (src_ip == NULL) {
408 src_port = PyInt_FromLong(self->msg->rcv.src_port);
409 if (src_port == NULL) {
415 pyRval = PyTuple_Pack(2, src_ip, src_port);
418 if (pyRval == NULL) {
427 msg_get_dst_address(msgobject *self, PyObject *unused)
429 PyObject *dst_ip, *dst_port, *pyRval;
431 if (self->msg == NULL) {
432 PyErr_SetString(PyExc_RuntimeError, "self->msg is NULL");
437 dst_ip = PyString_FromString(ip_addr2a(&self->msg->rcv.dst_ip));
438 if (dst_ip == NULL) {
443 dst_port = PyInt_FromLong(self->msg->rcv.dst_port);
444 if (dst_port == NULL) {
450 pyRval = PyTuple_Pack(2, dst_ip, dst_port);
453 if (pyRval == NULL) {
461 static PyGetSetDef msg_getseters[] = {
463 (getter)msg_getType, NULL, NULL,
464 "Get message type - \"SIP_REQUEST\" or \"SIP_REPLY\"."},
466 (getter)msg_getMethod, NULL, NULL,
467 "Get SIP method name."},
469 (getter)msg_getStatus, NULL, NULL,
470 "Get SIP status code string."},
472 (getter)msg_getRURI, NULL, NULL,
473 "Get SIP Request-URI."},
475 (getter)msg_get_src_address, NULL, NULL,
476 "Get (IP, port) tuple representing source address of the message."},
478 (getter)msg_get_dst_address, NULL, NULL,
479 "Get (IP, port) tuple representing destination address of the message."},
480 {NULL, NULL, NULL, NULL, NULL} /* Sentinel */
483 static PyTypeObject MSGtype = {
484 #if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION >= 6
485 PyVarObject_HEAD_INIT(NULL, 0)
487 PyObject_HEAD_INIT(NULL)
490 "Router.msg", /*tp_name*/
491 sizeof(msgobject), /*tp_size*/
494 (destructor)msg_dealloc, /*tp_dealloc*/
501 0, /*tp_as_sequence*/
509 Py_TPFLAGS_DEFAULT, /*tp_flags*/
513 0, /*tp_richcompare*/
514 0, /*tp_weaklistoffset*/
517 msg_methods, /*tp_methods*/
519 msg_getseters, /*tp_getset*/
523 python_msgobj_init(void)
526 Py_TYPE(&MSGtype) = &PyType_Type;
527 if (PyType_Ready(&MSGtype) < 0)