modules/ims_qos: added patch for flow-description bug when request originates from...
[sip-router] / lib / cds / sip_utils.c
1 #ifdef SER
2
3 #include <cds/sip_utils.h>
4 #include <cds/sstr.h>
5 #include <parser/parse_expires.h>
6 #include <parser/parse_subscription_state.h>
7 #include <parser/parser_f.h>
8 #include <parser/parse_to.h>
9 #include <trim.h>
10
11
12 int get_expiration_value(struct sip_msg *m, int *value)
13 {
14         exp_body_t *expires = NULL;
15         int res = 1;
16
17         if (parse_headers(m, HDR_EXPIRES_F, 0) == -1) {
18                 /* can't parse expires header */
19                 return -1;
20         }
21         if (m->expires) {
22                 if (parse_expires(m->expires) < 0) {
23                         return -1;
24                 }
25
26                 res = 0;
27                 expires = (exp_body_t *)m->expires->parsed;
28                 if (expires) if (expires->valid && value) *value = expires->val;
29         }
30         /* ERR("subscription will expire in %d secs\n", e); */
31         return res;
32 }
33
34 int is_terminating_notify(struct sip_msg *m)
35 {
36         subscription_state_t *ss;
37
38         if (parse_headers(m, HDR_SUBSCRIPTION_STATE_F, 0) == -1) {
39                 ERR("Error while parsing headers\n");
40                 return 0; /* ignore */
41         }
42         if (!m->subscription_state) {
43                 ERR("Invalid NOTIFY request (without Subscription-State)\n");
44                 return 0; /* ignore */
45         }
46         if (parse_subscription_state(m->subscription_state) < 0) {
47                 ERR("can't parse Subscription-State\n");
48                 return 0; /* ignore */
49         }
50         ss = (subscription_state_t*)m->subscription_state->parsed;
51         if (!ss) {
52                 ERR("invalid Subscription-State\n");
53                 return 0; /* ignore */
54         }
55         
56         if (ss->value == ss_terminated) return 1;
57
58         return 0;
59 }
60
61 static inline int contains_extension_support(struct hdr_field *h, 
62                 str *extension)
63 {
64         /* "parses" Supported header and looks for extension */
65         str s, val;
66         char *c;
67         
68         if (!h) return 0;
69
70         s = h->body;
71         while (s.len > 0) {
72                 c = find_not_quoted(&s, ',');
73                 if (c) {
74                         val.s = s.s;
75                         val.len = c - val.s;
76                         trim(&val);
77                         if (str_case_equals(&val, extension) == 0) return 1;
78                         s.len = s.len - (c - s.s) - 1;
79                         s.s = c + 1;
80                 }
81                 else {
82                         trim(&s);
83                         if (str_case_equals(&s, extension) == 0) return 1;
84                         break;
85                 }
86         }
87         return 0;
88 }
89
90 int supports_extension(struct sip_msg *m, str *extension)
91 {
92         /* walk through all Supported headers */
93         struct hdr_field *h;
94         int res;
95
96         /* we need all Supported headers */
97         res = parse_headers(m, HDR_EOH_F, 0);
98         if (res == -1) {
99                 ERR("Error while parsing headers (%d)\n", res);
100                 return 0; /* what to return here ? */
101         }
102         
103         h = m->supported;
104         while (h) {
105                 if (h->type == HDR_SUPPORTED_T) {
106                         if (contains_extension_support(h, extension)) return 1;
107                 }
108                 h = h->next;
109         }
110         return 0;
111 }
112
113 int requires_extension(struct sip_msg *m, str *extension)
114 {
115         /* walk through all Require headers */
116         struct hdr_field *h;
117         int res;
118
119         /* we need all Require headers */
120         res = parse_headers(m, HDR_EOH_F, 0);
121         if (res == -1) {
122                 ERR("Error while parsing headers (%d)\n", res);
123                 return 0; /* what to return here ? */
124         }
125         
126         h = m->require;
127         while (h) {
128                 if (h->type == HDR_REQUIRE_T) {
129                         if (contains_extension_support(h, extension)) return 1;
130                 }
131                 h = h->next;
132         }
133         return 0;
134 }
135
136 /**
137  * Verifies presence of the To-tag in message. Returns 1 if
138  * the tag is present, 0 if not, -1 on error.
139  */
140 int has_to_tag(struct sip_msg *_m)
141 {
142         struct to_body *to = (struct to_body*)_m->to->parsed;
143         if (!to) return -1;
144         if (to->tag_value.len > 0) return 1;
145         return 0;
146 }
147
148
149 #endif