/src/opensips/msg_callbacks.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (C) 2010 Sippy Software, Inc., http://www.sippysoft.com |
3 | | * |
4 | | * This file is part of opensips, a free SIP server. |
5 | | * |
6 | | * opensips is free software; you can redistribute it and/or modify |
7 | | * it under the terms of the GNU General Public License as published by |
8 | | * the Free Software Foundation; either version 2 of the License, or |
9 | | * (at your option) any later version |
10 | | * |
11 | | * opensips is distributed in the hope that it will be useful, |
12 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | | * GNU General Public License for more details. |
15 | | * |
16 | | * You should have received a copy of the GNU General Public License |
17 | | * along with this program; if not, write to the Free Software |
18 | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
19 | | * |
20 | | */ |
21 | | |
22 | | #include "parser/msg_parser.h" |
23 | | #include "mem/mem.h" |
24 | | #include "msg_callbacks.h" |
25 | | |
26 | | struct msg_callback { |
27 | | cb_type_t cb_type; |
28 | | cb_func_t cb_func; |
29 | | void *cb_arg; |
30 | | struct msg_callback *next; |
31 | | }; |
32 | | |
33 | | int |
34 | | msg_callback_add(struct sip_msg *msg, cb_type_t cb_type, cb_func_t cb_func, void *cb_arg) |
35 | 0 | { |
36 | 0 | struct msg_callback *msg_cb; |
37 | |
|
38 | 0 | switch (cb_type) { |
39 | 0 | case REQ_PRE_FORWARD: |
40 | 0 | if (msg->first_line.type == SIP_REQUEST) |
41 | 0 | break; |
42 | 0 | LM_ERR("programmatic error - REQ_PRE_FORWARD can only be registered on requests!"); |
43 | 0 | return (-1); |
44 | | |
45 | 0 | default: |
46 | 0 | break; |
47 | 0 | } |
48 | | |
49 | 0 | msg_cb = pkg_malloc(sizeof(*msg_cb)); |
50 | 0 | if (msg_cb == NULL) { |
51 | 0 | LM_ERR("can't allocate memory\n"); |
52 | 0 | return (-1); |
53 | 0 | } |
54 | 0 | msg_cb->cb_type = cb_type; |
55 | 0 | msg_cb->cb_func = cb_func; |
56 | 0 | msg_cb->cb_arg = cb_arg; |
57 | 0 | msg_cb->next = msg->msg_cb; |
58 | 0 | msg->msg_cb = msg_cb; |
59 | 0 | return 0; |
60 | 0 | } |
61 | | |
62 | | void |
63 | | msg_callback_process(struct sip_msg *msg, cb_type_t cb_type, void *core_arg) |
64 | 0 | { |
65 | 0 | struct msg_callback *msg_cb; |
66 | 0 | struct msg_callback *msg_cb_pre; |
67 | |
|
68 | 0 | for (msg_cb = msg->msg_cb; msg_cb != NULL; msg_cb = msg_cb->next) { |
69 | 0 | if (msg_cb->cb_type != cb_type) { |
70 | 0 | continue; |
71 | 0 | } |
72 | | /* Execute callback */ |
73 | 0 | msg_cb->cb_func(msg, cb_type, msg_cb->cb_arg, core_arg); |
74 | 0 | } |
75 | 0 | if (cb_type != MSG_DESTROY) |
76 | 0 | return; |
77 | 0 | for (msg_cb_pre = msg->msg_cb; msg_cb_pre != NULL; msg_cb_pre = msg_cb) { |
78 | 0 | msg_cb = msg_cb_pre->next; |
79 | 0 | pkg_free(msg_cb_pre); |
80 | 0 | } |
81 | 0 | msg->msg_cb = NULL; |
82 | 0 | } |
83 | | |
84 | | int |
85 | | msg_callback_check(struct sip_msg *msg, cb_type_t cb_type, cb_func_t cb_func) |
86 | 0 | { |
87 | 0 | struct msg_callback *msg_cb; |
88 | |
|
89 | 0 | for (msg_cb = msg->msg_cb; msg_cb != NULL; msg_cb = msg_cb->next) { |
90 | 0 | if (msg_cb->cb_func == cb_func && msg_cb->cb_type == cb_type) |
91 | 0 | return (1); |
92 | 0 | } |
93 | 0 | return (0); |
94 | 0 | } |