Bug Summary

File:src/mod/endpoints/mod_sofia/sofia_presence.c
Location:line 4024, column 9
Description:Value stored to 'contactstr' during its initialization is never read

Annotated Source Code

1/*
2 * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
3 * Copyright (C) 2005-2014, Anthony Minessale II <anthm@freeswitch.org>
4 *
5 * Version: MPL 1.1
6 *
7 * The contents of this file are subject to the Mozilla Public License Version
8 * 1.1 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://www.mozilla.org/MPL/
11 *
12 * Software distributed under the License is distributed on an "AS IS" basis,
13 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14 * for the specific language governing rights and limitations under the
15 * License.
16 *
17 * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
18 *
19 * The Initial Developer of the Original Code is
20 * Anthony Minessale II <anthm@freeswitch.org>
21 * Portions created by the Initial Developer are Copyright (C)
22 * the Initial Developer. All Rights Reserved.
23 *
24 * Contributor(s):
25 *
26 * Anthony Minessale II <anthm@freeswitch.org>
27 * Ken Rice <krice@freeswitch.org>
28 * Paul D. Tinsley <pdt at jackhammer.org>
29 * Bret McDanel <trixter AT 0xdecafbad.com>
30 * Raymond Chandler <intralanman@freeswitch.org>
31 * William King <william.king@quentustech.com>
32 * Emmanuel Schmidbauer <e.schmidbauer@gmail.com>
33 * David Knell <david.knell@telng.com>
34 *
35 * sofia_presence.c -- SOFIA SIP Endpoint (presence code)
36 *
37 */
38#include "mod_sofia.h"
39#include "switch_stun.h"
40
41#define SUB_OVERLAP300 300
42struct state_helper {
43 switch_hash_t *hash;
44 sofia_profile_t *profile;
45 switch_memory_pool_t *pool;
46 int total;
47};
48
49
50static int sofia_presence_mwi_callback(void *pArg, int argc, char **argv, char **columnNames);
51static int sofia_presence_mwi_callback2(void *pArg, int argc, char **argv, char **columnNames);
52static int sofia_presence_sub_reg_callback(void *pArg, int argc, char **argv, char **columnNames);
53static int sofia_presence_resub_callback(void *pArg, int argc, char **argv, char **columnNames);
54static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char **columnNames);
55static int broadsoft_sla_gather_state_callback(void *pArg, int argc, char **argv, char **columnNames);
56static int broadsoft_sla_notify_callback(void *pArg, int argc, char **argv, char **columnNames);
57static int sync_sla(sofia_profile_t *profile, const char *to_user, const char *to_host, switch_bool_t clear, switch_bool_t unseize, const char *call_id);
58static int sofia_dialog_probe_callback(void *pArg, int argc, char **argv, char **columnNames);
59static int sofia_dialog_probe_notify_callback(void *pArg, int argc, char **argv, char **columnNames);
60
61struct pres_sql_cb {
62 sofia_profile_t *profile;
63 int ttl;
64};
65
66static int sofia_presence_send_sql(void *pArg, int argc, char **argv, char **columnNames);
67
68struct dialog_helper {
69 char state[128];
70 char status[512];
71 char rpid[512];
72 char presence_id[1024];
73 int hits;
74};
75
76struct resub_helper {
77 sofia_profile_t *profile;
78 switch_event_t *event;
79 int rowcount;
80 int noreg;
81};
82
83struct rfc4235_helper {
84 switch_hash_t *hash;
85 sofia_profile_t *profile;
86 switch_memory_pool_t *pool;
87 switch_event_t *event;
88 int rowcount;
89};
90
91struct presence_helper {
92 sofia_profile_t *profile;
93 switch_event_t *event;
94 switch_stream_handle_t stream;
95 char last_uuid[512];
96 int hup;
97 int calls_up;
98
99};
100
101switch_status_t sofia_presence_chat_send(switch_event_t *message_event)
102
103{
104 char *prof = NULL((void*)0), *user = NULL((void*)0), *host = NULL((void*)0);
105 sofia_profile_t *profile = NULL((void*)0);
106 char *ffrom = NULL((void*)0);
107 nua_handle_t *msg_nh;
108 char *contact = NULL((void*)0);
109 char *dup = NULL((void*)0);
110 switch_status_t status = SWITCH_STATUS_FALSE;
111 const char *ct = "text/html";
112 sofia_destination_t *dst = NULL((void*)0);
113 char *to_uri = NULL((void*)0);
114 switch_console_callback_match_t *list = NULL((void*)0);
115 switch_console_callback_match_node_t *m;
116 char *remote_ip = NULL((void*)0);
117 char *user_via = NULL((void*)0);
118 //char *contact_str = NULL;
119 char *dup_dest = NULL((void*)0);
120 char *p = NULL((void*)0);
121 char *remote_host = NULL((void*)0);
122 const char *proto;
123 const char *from;
124 const char *to;
125 //const char *subject;
126 const char *body;
127 const char *type;
128 const char *from_full;
129 char header[256] = "";
130 char *route_uri = NULL((void*)0);
131 const char *network_ip = NULL((void*)0), *network_port = NULL((void*)0), *from_proto;
132 char *extra_headers = NULL((void*)0);
133 char uuid_str[SWITCH_UUID_FORMATTED_LENGTH256 + 1];
134 int mstatus = 0, sanity = 0;
135 const char *blocking;
136 int is_blocking = 0;
137
138 proto = switch_event_get_header(message_event, "proto")switch_event_get_header_idx(message_event, "proto", -1);
139 from_proto = switch_event_get_header(message_event, "from_proto")switch_event_get_header_idx(message_event, "from_proto", -1);
140 from = switch_event_get_header(message_event, "from")switch_event_get_header_idx(message_event, "from", -1);
141 to = switch_event_get_header(message_event, "to")switch_event_get_header_idx(message_event, "to", -1);
142 //subject = switch_event_get_header(message_event, "subject");
143 body = switch_event_get_body(message_event);
144 type = switch_event_get_header(message_event, "type")switch_event_get_header_idx(message_event, "type", -1);
145 from_full = switch_event_get_header(message_event, "from_full")switch_event_get_header_idx(message_event, "from_full", -1);
146 blocking = switch_event_get_header(message_event, "blocking")switch_event_get_header_idx(message_event, "blocking", -1);
147 is_blocking = switch_true(blocking);
148
149 network_ip = switch_event_get_header(message_event, "to_sip_ip")switch_event_get_header_idx(message_event, "to_sip_ip", -1);
150 network_port = switch_event_get_header(message_event, "to_sip_port")switch_event_get_header_idx(message_event, "to_sip_port", -1);
151
152 extra_headers = sofia_glue_get_extra_headers_from_event(message_event, SOFIA_SIP_HEADER_PREFIX"sip_h_");
153
154 if (!to) {
155 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 155, ((void*)0)
, SWITCH_LOG_ERROR, "Missing To: header.\n");
156 goto end;
157 }
158
159 if (!from) {
160 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 160, ((void*)0)
, SWITCH_LOG_ERROR, "Missing From: header.\n");
161 goto end;
162 }
163
164 if (!zstr(type)_zstr(type)) {
165 ct = type;
166 }
167
168 dup = strdup(to)(__extension__ (__builtin_constant_p (to) && ((size_t
)(const void *)((to) + 1) - (size_t)(const void *)(to) == 1) ?
(((const char *) (to))[0] == '\0' ? (char *) calloc ((size_t
) 1, (size_t) 1) : ({ size_t __len = strlen (to) + 1; char *__retval
= (char *) malloc (__len); if (__retval != ((void*)0)) __retval
= (char *) memcpy (__retval, to, __len); __retval; })) : __strdup
(to)))
;
169 switch_assert(dup)((dup) ? (void) (0) : __assert_fail ("dup", "sofia_presence.c"
, 169, __PRETTY_FUNCTION__))
;
170 prof = dup;
171
172 /* Do we have a user of the form profile/user[@host]? */
173 if ((user = strchr(prof, '/')(__extension__ (__builtin_constant_p ('/') && !__builtin_constant_p
(prof) && ('/') == '\0' ? (char *) __rawmemchr (prof
, '/') : __builtin_strchr (prof, '/')))
)) {
174 *user++ = '\0';
175 } else {
176 user = prof;
177 prof = NULL((void*)0);
178 }
179
180 if (!prof) {
181 prof = switch_event_get_header(message_event, "sip_profile")switch_event_get_header_idx(message_event, "sip_profile", -1);
182 }
183
184 if (!strncasecmp(user, "sip:", 4)) {
185 to_uri = user;
186 }
187
188 if ((host = strchr(user, '@')(__extension__ (__builtin_constant_p ('@') && !__builtin_constant_p
(user) && ('@') == '\0' ? (char *) __rawmemchr (user
, '@') : __builtin_strchr (user, '@')))
)) {
189 if (!to_uri) {
190 *host++ = '\0';
191 } else {
192 host++;
193 }
194 if (!prof) {
195 prof = host;
196 }
197 }
198
199 if (!prof || !(profile = sofia_glue_find_profile(prof)sofia_glue_find_profile__("sofia_presence.c", (const char *)__func__
, 199, prof)
)) {
200 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 200, ((void*)0)
, SWITCH_LOG_ERROR,
201 "Chat proto [%s]\nfrom [%s]\nto [%s]\n%s\nInvalid Profile %s\n", proto, from, to,
202 body ? body : "[no body]", prof ? prof : "NULL");
203 goto end;
204 }
205
206 if (zstr(host)_zstr(host)) {
207 host = profile->domain_name;
208 if (zstr(host)_zstr(host)) {
209 host = prof;
210 }
211 }
212
213
214 if (to_uri) {
215 switch_console_push_match(&list, to_uri);
216 } else if (!(list = sofia_reg_find_reg_url_multi(profile, user, host))) {
217 sofia_profile_t *test;
218
219 if ((test = sofia_glue_find_profile(host)sofia_glue_find_profile__("sofia_presence.c", (const char *)__func__
, 219, host)
)) {
220 sofia_glue_release_profile(test)sofia_glue_release_profile__("sofia_presence.c", (const char *
)__func__, 220, test)
;
221 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 221, ((void*)0)
, SWITCH_LOG_WARNING, "Not sending to local box for %s@%s\n", user, host);
222 /* our box let's not send it */
223 } else {
224 char *tmp;
225 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 225, ((void*)0)
, SWITCH_LOG_DEBUG, "Can't find registered user %s@%s\n", user, host);
226 tmp = switch_mprintf("sip:%s@%s", user, host);
227 switch_console_push_match(&list, tmp);
228 free(tmp);
229 }
230
231 }
232
233 if (!strcasecmp(proto, SOFIA_CHAT_PROTO"sip")) {
234 from = from_full;
235 } else {
236 char *fp, *p = NULL((void*)0);
237
238
239 fp = strdup(from)(__extension__ (__builtin_constant_p (from) && ((size_t
)(const void *)((from) + 1) - (size_t)(const void *)(from) ==
1) ? (((const char *) (from))[0] == '\0' ? (char *) calloc (
(size_t) 1, (size_t) 1) : ({ size_t __len = strlen (from) + 1
; char *__retval = (char *) malloc (__len); if (__retval != (
(void*)0)) __retval = (char *) memcpy (__retval, from, __len)
; __retval; })) : __strdup (from)))
;
240 switch_assert(fp)((fp) ? (void) (0) : __assert_fail ("fp", "sofia_presence.c",
240, __PRETTY_FUNCTION__))
;
241
242
243 if ((p = strchr(fp, '@')(__extension__ (__builtin_constant_p ('@') && !__builtin_constant_p
(fp) && ('@') == '\0' ? (char *) __rawmemchr (fp, '@'
) : __builtin_strchr (fp, '@')))
)) {
244 *p++ = '\0';
245 }
246
247 if (zstr(p)_zstr(p)) {
248 p = profile->domain_name;
249 if (zstr(p)_zstr(p)) {
250 p = host;
251 }
252 }
253
254 if (switch_stristr("global", proto)) {
255 if (!from_proto || !strcasecmp(from_proto, SOFIA_CHAT_PROTO"sip")) {
256 ffrom = switch_mprintf("\"%s\" <sip:%s@%s>", fp, fp, p);
257 } else {
258 ffrom = switch_mprintf("\"%s\" <sip:%s+%s@%s>", fp, from_proto, fp, p);
259 }
260
261 } else {
262 ffrom = switch_mprintf("\"%s\" <sip:%s+%s@%s>", fp, from_proto ? from_proto : proto, fp, p);
263 }
264
265 from = ffrom;
266 switch_safe_free(fp)if (fp) {free(fp);fp=((void*)0);};
267 }
268
269 if (!list) {
270 switch_event_t *event;
271
272 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 272, ((void*)0)
, SWITCH_LOG_ERROR,
273 "Chat proto [%s]\nfrom [%s]\nto [%s]\n%s\nNobody to send to: Profile %s\n", proto, from, to,
274 body ? body : "[no body]", prof ? prof : "NULL");
275 // emit no recipient event
276 if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_ERROR)switch_event_create_subclass_detailed("sofia_presence.c", (const
char * )(const char *)__func__, 276, &event, SWITCH_EVENT_CUSTOM
, "sofia::error")
== SWITCH_STATUS_SUCCESS) {
277 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Error-Type", "chat");
278 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Error-Reason", "no recipient");
279 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Chat-Send-To", to);
280 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Chat-Send-From", from);
281 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Chat-Send-Profile", prof ? prof : "NULL");
282 switch_event_add_body(event, "%s", body);
283 switch_event_fire(&event)switch_event_fire_detailed("sofia_presence.c", (const char * )
(const char *)__func__, 283, &event, ((void*)0))
;
284 }
285
286 goto end;
287 }
288
289 for (m = list->head; m; m = m->next) {
290
291 if (!(dst = sofia_glue_get_destination(m->val))) {
292 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 292, ((void*)0)
, SWITCH_LOG_CRIT, "Memory Error!\n");
293 break;
294 }
295
296 /* sofia_glue is running sofia_overcome_sip_uri_weakness we do not, not sure if it matters */
297
298 if (dst->route_uri) {
299 dup_dest = strdup(dst->route_uri)(__extension__ (__builtin_constant_p (dst->route_uri) &&
((size_t)(const void *)((dst->route_uri) + 1) - (size_t)(
const void *)(dst->route_uri) == 1) ? (((const char *) (dst
->route_uri))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t
) 1) : ({ size_t __len = strlen (dst->route_uri) + 1; char
*__retval = (char *) malloc (__len); if (__retval != ((void*
)0)) __retval = (char *) memcpy (__retval, dst->route_uri,
__len); __retval; })) : __strdup (dst->route_uri)))
;
300 } else {
301 dup_dest = strdup(dst->to)(__extension__ (__builtin_constant_p (dst->to) && (
(size_t)(const void *)((dst->to) + 1) - (size_t)(const void
*)(dst->to) == 1) ? (((const char *) (dst->to))[0] == '\0'
? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len
= strlen (dst->to) + 1; char *__retval = (char *) malloc (
__len); if (__retval != ((void*)0)) __retval = (char *) memcpy
(__retval, dst->to, __len); __retval; })) : __strdup (dst
->to)))
;
302 }
303
304
305 remote_host = strdup(dup_dest)(__extension__ (__builtin_constant_p (dup_dest) && ((
size_t)(const void *)((dup_dest) + 1) - (size_t)(const void *
)(dup_dest) == 1) ? (((const char *) (dup_dest))[0] == '\0' ?
(char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len =
strlen (dup_dest) + 1; char *__retval = (char *) malloc (__len
); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval
, dup_dest, __len); __retval; })) : __strdup (dup_dest)))
;
306 if (!zstr(remote_host)_zstr(remote_host)) {
307 switch_split_user_domain(remote_host, NULL((void*)0), &remote_ip);
308 }
309
310 if (!zstr(remote_ip)_zstr(remote_ip) && sofia_glue_check_nat(profile, remote_ip)) {
311 char *ptr = NULL((void*)0);
312 if ((ptr = sofia_glue_find_parameter(dst->contact, "transport="))) {
313 sofia_transport_t transport = sofia_glue_str2transport( ptr + 10 );
314 user_via = sofia_glue_create_external_via(NULL((void*)0), profile, transport);
315 } else {
316 user_via = sofia_glue_create_external_via(NULL((void*)0), profile, SOFIA_TRANSPORT_UDP);
317 }
318 }
319
320 status = SWITCH_STATUS_SUCCESS;
321
322 if (dup_dest && (p = strstr(dup_dest, ";fs_"))) {
323 *p = '\0';
324 }
325
326 /* if this cries, add contact here too, change the 1 to 0 and omit the safe_free */
327
328 //printf("DEBUG To: [%s] From: [%s] Contact: [%s] RURI [%s] ip [%s] port [%s]\n", to, from, contact, dst->route_uri, network_ip, network_port);
329
330 //DUMP_EVENT(message_event);
331
332 if (zstr(dst->route_uri)_zstr(dst->route_uri) && !zstr(user)_zstr(user) && !zstr(network_ip)_zstr(network_ip) && (zstr(host)_zstr(host) || strcmp(network_ip, host)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(network_ip) && __builtin_constant_p (host) &&
(__s1_len = __builtin_strlen (network_ip), __s2_len = __builtin_strlen
(host), (!((size_t)(const void *)((network_ip) + 1) - (size_t
)(const void *)(network_ip) == 1) || __s1_len >= 4) &&
(!((size_t)(const void *)((host) + 1) - (size_t)(const void *
)(host) == 1) || __s2_len >= 4)) ? __builtin_strcmp (network_ip
, host) : (__builtin_constant_p (network_ip) && ((size_t
)(const void *)((network_ip) + 1) - (size_t)(const void *)(network_ip
) == 1) && (__s1_len = __builtin_strlen (network_ip),
__s1_len < 4) ? (__builtin_constant_p (host) && (
(size_t)(const void *)((host) + 1) - (size_t)(const void *)(host
) == 1) ? __builtin_strcmp (network_ip, host) : (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) (host); int __result = (((const unsigned char *) (const
char *) (network_ip))[0] - __s2[0]); if (__s1_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (network_ip))[1] - __s2[1]); if (__s1_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (network_ip))[2] - __s2[2]); if (__s1_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (network_ip))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
(host) && ((size_t)(const void *)((host) + 1) - (size_t
)(const void *)(host) == 1) && (__s2_len = __builtin_strlen
(host), __s2_len < 4) ? (__builtin_constant_p (network_ip
) && ((size_t)(const void *)((network_ip) + 1) - (size_t
)(const void *)(network_ip) == 1) ? __builtin_strcmp (network_ip
, host) : (- (__extension__ ({ const unsigned char *__s2 = (const
unsigned char *) (const char *) (network_ip); int __result =
(((const unsigned char *) (const char *) (host))[0] - __s2[0
]); if (__s2_len > 0 && __result == 0) { __result =
(((const unsigned char *) (const char *) (host))[1] - __s2[1
]); if (__s2_len > 1 && __result == 0) { __result =
(((const unsigned char *) (const char *) (host))[2] - __s2[2
]); if (__s2_len > 2 && __result == 0) __result = (
((const unsigned char *) (const char *) (host))[3] - __s2[3])
; } } __result; })))) : __builtin_strcmp (network_ip, host)))
); })
)) {
333 route_uri = switch_mprintf("sip:%s@%s:%s", user, network_ip, network_port);
334 }
335
336 msg_nh = nua_handle(profile->nua, NULL((void*)0),
337 TAG_END()(tag_type_t)0, (tag_value_t)0);
338
339 nua_handle_bind(msg_nh, &mod_sofia_globals.destroy_private);
340
341 switch_snprintf(header, sizeof(header), "X-FS-Sending-Message: %s", switch_core_get_uuid());
342
343 switch_uuid_str(uuid_str, sizeof(uuid_str));
344
345 if (is_blocking) {
346 switch_mutex_lock(profile->flag_mutex);
347 switch_core_hash_insert(profile->chat_hash, uuid_str, &mstatus)switch_core_hash_insert_destructor(profile->chat_hash, uuid_str
, &mstatus, ((void*)0))
;
348 switch_mutex_unlock(profile->flag_mutex);
349 }
350
351 nua_message(msg_nh,
352 TAG_IF(dst->route_uri, NUTAG_PROXY(dst->route_uri))!(dst->route_uri) ? tag_skip : ntatag_default_proxy, urltag_url_v
((dst->route_uri))
,
353 TAG_IF(route_uri, NUTAG_PROXY(route_uri))!(route_uri) ? tag_skip : ntatag_default_proxy, urltag_url_v(
(route_uri))
,
354 TAG_IF(dst->route, SIPTAG_ROUTE_STR(dst->route))!(dst->route) ? tag_skip : siptag_route_str, tag_str_v(dst
->route)
,
355 SIPTAG_FROM_STR(from)siptag_from_str, tag_str_v(from),
356 TAG_IF(contact, NUTAG_URL(contact))!(contact) ? tag_skip : nutag_url, urltag_url_v(contact),
357 SIPTAG_TO_STR(dup_dest)siptag_to_str, tag_str_v(dup_dest),
358 SIPTAG_CALL_ID_STR(uuid_str)siptag_call_id_str, tag_str_v(uuid_str),
359 TAG_IF(user_via, SIPTAG_VIA_STR(user_via))!(user_via) ? tag_skip : siptag_via_str, tag_str_v(user_via),
360 SIPTAG_CONTENT_TYPE_STR(ct)siptag_content_type_str, tag_str_v(ct),
361 SIPTAG_PAYLOAD_STR(body)siptag_payload_str, tag_str_v(body),
362 SIPTAG_HEADER_STR(header)siptag_header_str, tag_str_v((header)),
363 TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers))!(!_zstr(extra_headers)) ? tag_skip : siptag_header_str, tag_str_v
((extra_headers))
,
364 TAG_END()(tag_type_t)0, (tag_value_t)0);
365
366
367 if (is_blocking) {
368 sanity = 200;
369
370 while(!mstatus && --sanity && !msg_nh->nh_destroyed) {
371 switch_yield(100000)switch_sleep(100000);;
372 }
373
374 if (!(mstatus > 199 && mstatus < 300)) {
375 status = SWITCH_STATUS_FALSE;
376 }
377
378 switch_event_add_header(message_event, SWITCH_STACK_BOTTOM, "Delivery-Result-Code", "%d", mstatus);
379
380 switch_mutex_lock(profile->flag_mutex);
381 switch_core_hash_delete(profile->chat_hash, uuid_str);
382 switch_mutex_unlock(profile->flag_mutex);
383 }
384
385 sofia_glue_free_destination(dst);
386 switch_safe_free(dup_dest)if (dup_dest) {free(dup_dest);dup_dest=((void*)0);};
387 switch_safe_free(remote_host)if (remote_host) {free(remote_host);remote_host=((void*)0);};
388 }
389
390 end:
391
392 if (list) {
393 switch_console_free_matches(&list);
394 }
395
396 switch_safe_free(contact)if (contact) {free(contact);contact=((void*)0);};
397 switch_safe_free(route_uri)if (route_uri) {free(route_uri);route_uri=((void*)0);};
398 switch_safe_free(ffrom)if (ffrom) {free(ffrom);ffrom=((void*)0);};
399 switch_safe_free(dup)if (dup) {free(dup);dup=((void*)0);};
400
401 if (profile) {
402 switch_thread_rwlock_unlock(profile->rwlock);
403 }
404
405 return status;
406}
407
408void sofia_presence_cancel(void)
409{
410 char *sql;
411 sofia_profile_t *profile;
412 struct presence_helper helper = { 0 };
413 switch_console_callback_match_t *matches;
414 switch_bool_t r;
415
416 if (!mod_sofia_globals.profile_hash) {
417 return;
418 }
419
420 if (list_profiles_full(NULL((void*)0), NULL((void*)0), &matches, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) {
421 switch_console_callback_match_node_t *m;
422
423
424 for (m = matches->head; m; m = m->next) {
425 if ((profile = sofia_glue_find_profile(m->val)sofia_glue_find_profile__("sofia_presence.c", (const char *)__func__
, 425, m->val)
)) {
426 if (profile->pres_type == PRES_TYPE_FULL) {
427 helper.profile = profile;
428 helper.event = NULL((void*)0);
429
430 sql = switch_mprintf("select proto,sip_user,sip_host,sub_to_user,sub_to_host,event,contact,call_id,full_from,"
431 "full_via,expires,user_agent,accept,profile_name,network_ip"
432 ",-1,'unavailable','unavailable' from sip_subscriptions where "
433 "event='presence' and hostname='%q' and profile_name='%q'",
434 mod_sofia_globals.hostname, profile->name);
435
436 r = sofia_glue_execute_sql_callback(profile, profile->dbh_mutex, sql, sofia_presence_sub_callback, &helper);
437 switch_safe_free(sql)if (sql) {free(sql);sql=((void*)0);};
438
439 if (r != SWITCH_TRUE) {
440 sofia_glue_release_profile(profile)sofia_glue_release_profile__("sofia_presence.c", (const char *
)__func__, 440, profile)
;
441 continue;
442 }
443 }
444 sofia_glue_release_profile(profile)sofia_glue_release_profile__("sofia_presence.c", (const char *
)__func__, 444, profile)
;
445 }
446 }
447
448 switch_console_free_matches(&matches);
449
450 }
451}
452
453char *sofia_presence_translate_rpid(char *in, char *ext)
454{
455 char *r = in;
456
457 if (in && (switch_stristr("null", in))) {
458 in = NULL((void*)0);
459 }
460
461 if (!in) {
462 in = ext;
463 }
464
465 if (!in) {
466 return NULL((void*)0);
467 }
468
469 if (!strcasecmp(in, "dnd") || !strcasecmp(in, "idle")) {
470 r = "busy";
471 }
472
473 return r;
474}
475
476struct mwi_helper {
477 sofia_profile_t *profile;
478 int total;
479};
480
481static void actual_sofia_presence_mwi_event_handler(switch_event_t *event)
482{
483 char *account, *dup_account, *yn, *host, *user;
484 char *sql;
485 sofia_profile_t *profile = NULL((void*)0);
486 switch_stream_handle_t stream = { 0 };
487 switch_event_header_t *hp;
488 struct mwi_helper h = { 0 };
489 const char *pname = NULL((void*)0);
490 const char *call_id;
491 const char *sub_call_id;
492 int for_everyone = 0;
493
494 switch_assert(event != NULL)((event != ((void*)0)) ? (void) (0) : __assert_fail ("event != ((void*)0)"
, "sofia_presence.c", 494, __PRETTY_FUNCTION__))
;
495
496 if (!(account = switch_event_get_header(event, "mwi-message-account")switch_event_get_header_idx(event, "mwi-message-account", -1))) {
497 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 497, ((void*)0)
, SWITCH_LOG_ERROR, "Missing required Header 'MWI-Message-Account'\n");
498 return;
499 }
500
501 if (!(yn = switch_event_get_header(event, "mwi-messages-waiting")switch_event_get_header_idx(event, "mwi-messages-waiting", -1
)
)) {
502 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 502, ((void*)0)
, SWITCH_LOG_ERROR, "Missing required Header 'MWI-Messages-Waiting'\n");
503 return;
504 }
505
506 call_id = switch_event_get_header(event, "call-id")switch_event_get_header_idx(event, "call-id", -1);
507 sub_call_id = switch_event_get_header(event, "sub-call-id")switch_event_get_header_idx(event, "sub-call-id", -1);
508
509 if (!call_id && !sub_call_id) {
510 for_everyone = 1;
511 }
512
513
514 dup_account = strdup(account)(__extension__ (__builtin_constant_p (account) && ((size_t
)(const void *)((account) + 1) - (size_t)(const void *)(account
) == 1) ? (((const char *) (account))[0] == '\0' ? (char *) calloc
((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (account
) + 1; char *__retval = (char *) malloc (__len); if (__retval
!= ((void*)0)) __retval = (char *) memcpy (__retval, account
, __len); __retval; })) : __strdup (account)))
;
515 switch_assert(dup_account != NULL)((dup_account != ((void*)0)) ? (void) (0) : __assert_fail ("dup_account != ((void*)0)"
, "sofia_presence.c", 515, __PRETTY_FUNCTION__))
;
516 switch_split_user_domain(dup_account, &user, &host);
517
518
519 if ((pname = switch_event_get_header(event, "sofia-profile")switch_event_get_header_idx(event, "sofia-profile", -1))) {
520 profile = sofia_glue_find_profile(pname)sofia_glue_find_profile__("sofia_presence.c", (const char *)__func__
, 520, pname)
;
521 }
522
523 if (!profile) {
524 if (!host || !(profile = sofia_glue_find_profile(host)sofia_glue_find_profile__("sofia_presence.c", (const char *)__func__
, 524, host)
)) {
525 char *sql;
526 char buf[512] = "";
527 switch_console_callback_match_t *matches;
528
529 sql = switch_mprintf("select profile_name from sip_registrations where hostname='%q' and (sip_host='%s' or mwi_host='%s')",
530 mod_sofia_globals.hostname, host, host);
531
532 if (list_profiles_full(NULL((void*)0), NULL((void*)0), &matches, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) {
533 switch_console_callback_match_node_t *m;
534
535 for (m = matches->head; m; m = m->next) {
536 if ((profile = sofia_glue_find_profile(m->val)sofia_glue_find_profile__("sofia_presence.c", (const char *)__func__
, 536, m->val)
)) {
537
538 sofia_glue_execute_sql2str(profile, profile->dbh_mutex, sql, buf, sizeof(buf));
539 if (!zstr(buf)_zstr(buf)) {
540 break;
541 }
542 sofia_glue_release_profile(profile)sofia_glue_release_profile__("sofia_presence.c", (const char *
)__func__, 542, profile)
;
543 }
544 }
545
546 switch_console_free_matches(&matches);
547 }
548
549 switch_safe_free(sql)if (sql) {free(sql);sql=((void*)0);};
550
551 if (!(profile = sofia_glue_find_profile(buf)sofia_glue_find_profile__("sofia_presence.c", (const char *)__func__
, 551, buf)
)) {
552 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 552, ((void*)0)
, SWITCH_LOG_ERROR, "Cannot find profile %s\n", switch_str_nil(host)(host ? host : ""));
553 switch_safe_free(dup_account)if (dup_account) {free(dup_account);dup_account=((void*)0);};
554 return;
555 }
556 }
557 }
558
559
560 if (profile->domain_name && strcasecmp(profile->domain_name, host)) {
561 host = profile->domain_name;
562 }
563
564 h.profile = profile;
565 h.total = 0;
566
567 SWITCH_STANDARD_STREAM(stream)memset(&stream, 0, sizeof(stream)); stream.data = malloc(
1024); ((stream.data) ? (void) (0) : __assert_fail ("stream.data"
, "sofia_presence.c", 567, __PRETTY_FUNCTION__)); memset(stream
.data, 0, 1024); stream.end = stream.data; stream.data_size =
1024; stream.write_function = switch_console_stream_write; stream
.raw_write_function = switch_console_stream_raw_write; stream
.alloc_len = 1024; stream.alloc_chunk = 1024
;
568
569 for (hp = event->headers; hp; hp = hp->next) {
570 if (!strncasecmp(hp->name, "mwi-", 4)) {
571 char *tmp = NULL((void*)0);
572 char *value = hp->value;
573 if (!strcasecmp(hp->name, "mwi-message-account") && strncasecmp(hp->value, "sip:", 4)) {
574 tmp = switch_mprintf("sip:%s", hp->value);
575 value = tmp;
576 }
577 stream.write_function(&stream, "%s: %s\r\n", hp->name + 4, value);
578 switch_safe_free(tmp)if (tmp) {free(tmp);tmp=((void*)0);};
579 }
580 }
581
582 stream.write_function(&stream, "\r\n");
583
584 sql = NULL((void*)0);
585
586 if (for_everyone) {
587 sql = switch_mprintf("select proto,sip_user,sip_host,sub_to_user,sub_to_host,event,contact,call_id,full_from,"
588 "full_via,expires,user_agent,accept,profile_name,network_ip"
589 ",'%q',full_to,network_ip,network_port from sip_subscriptions "
590 "where hostname='%q' and event='message-summary' "
591 "and sub_to_user='%q' and (sub_to_host='%q' or presence_hosts like '%%%q%%')",
592 stream.data, mod_sofia_globals.hostname, user, host, host);
593 } else if (sub_call_id) {
594 sql = switch_mprintf("select proto,sip_user,sip_host,sub_to_user,sub_to_host,event,contact,call_id,full_from,"
595 "full_via,expires,user_agent,accept,profile_name,network_ip"
596 ",'%q',full_to,network_ip,network_port from sip_subscriptions where "
597 "hostname='%q' and event='message-summary' "
598 "and sub_to_user='%q' and (sub_to_host='%q' or presence_hosts like '%%%q%%') and call_id='%q'",
599 stream.data, mod_sofia_globals.hostname, user, host, host, sub_call_id);
600 }
601
602
603 if (sql) {
604 sofia_glue_execute_sql_callback(profile, profile->dbh_mutex, sql, sofia_presence_mwi_callback, &h);
605 free(sql);
606 sql = NULL((void*)0);
607
608 }
609
610 if (for_everyone) {
611 sql = switch_mprintf("select sip_user,sip_host,contact,profile_name,network_ip,'%q',call_id "
612 "from sip_registrations where hostname='%q' and mwi_user='%q' and mwi_host='%q'",
613 stream.data, mod_sofia_globals.hostname, user, host);
614 } else if (call_id) {
615 sql = switch_mprintf("select sip_user,sip_host,contact,profile_name,network_ip,'%q',call_id "
616 "from sip_registrations where hostname='%q' and call_id='%q'",
617 stream.data, mod_sofia_globals.hostname, call_id);
618 }
619
620 if (sql) {
621 switch_assert(sql != NULL)((sql != ((void*)0)) ? (void) (0) : __assert_fail ("sql != ((void*)0)"
, "sofia_presence.c", 621, __PRETTY_FUNCTION__))
;
622 sofia_glue_execute_sql_callback(profile, profile->dbh_mutex, sql, sofia_presence_mwi_callback2, &h);
623 free(sql);
624 sql = NULL((void*)0);
625 }
626
627 switch_safe_free(stream.data)if (stream.data) {free(stream.data);stream.data=((void*)0);};
628 switch_safe_free(dup_account)if (dup_account) {free(dup_account);dup_account=((void*)0);};
629
630 if (profile) {
631 sofia_glue_release_profile(profile)sofia_glue_release_profile__("sofia_presence.c", (const char *
)__func__, 631, profile)
;
632 }
633}
634
635static int sofia_presence_dialog_callback(void *pArg, int argc, char **argv, char **columnNames)
636{
637 struct dialog_helper *helper = (struct dialog_helper *) pArg;
638 switch_core_session_t *session = NULL((void*)0);
639 switch_channel_t *channel = NULL((void*)0);
640 int done = 0;
641
642 if (argc >= 4) {
643
644 if (argc == 5 && !zstr(argv[4])_zstr(argv[4])) {
645 if ((session = switch_core_session_locate(argv[4])switch_core_session_perform_locate(argv[4], "sofia_presence.c"
, (const char *)__func__, 645)
)) {
646 channel = switch_core_session_get_channel(session);
647
648 if (!switch_channel_test_flag(channel, CF_ANSWERED) &&
649 switch_true(switch_channel_get_variable_dup(channel, "presence_disable_early", SWITCH_FALSE, -1))) {
650 done++;
651 }
652
653 switch_core_session_rwunlock(session);
654 } else {
655 return 0;
656 }
657 }
658
659 if (done) {
660 return 0;
661 }
662
663 if (mod_sofia_globals.debug_presence > 0) {
664 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 664, ((void*)0)
, SWITCH_LOG_CRIT, "CHECK DIALOG state[%s] status[%s] rpid[%s] pres[%s] uuid[%s]\n",
665 argv[0], argv[1], argv[2], argv[3], argv[4]);
666 }
667
668 if (!helper->hits) {
669 switch_set_string(helper->state, argv[0])switch_copy_string(helper->state, argv[0], sizeof(helper->
state))
;
670 switch_set_string(helper->status, argv[1])switch_copy_string(helper->status, argv[1], sizeof(helper->
status))
;
671 switch_set_string(helper->rpid, argv[2])switch_copy_string(helper->rpid, argv[2], sizeof(helper->
rpid))
;
672 switch_set_string(helper->presence_id, argv[3])switch_copy_string(helper->presence_id, argv[3], sizeof(helper
->presence_id))
;
673 }
674 helper->hits++;
675 }
676
677 return 0;
678}
679
680
681static void do_normal_probe(switch_event_t *event)
682{
683 char *sql;
684 struct resub_helper h = { 0 };
685 char *to = switch_event_get_header(event, "to")switch_event_get_header_idx(event, "to", -1);
686 char *proto = switch_event_get_header(event, "proto")switch_event_get_header_idx(event, "proto", -1);
687 char *profile_name = switch_event_get_header(event, "sip_profile")switch_event_get_header_idx(event, "sip_profile", -1);
688 char *probe_user = NULL((void*)0), *probe_euser, *probe_host, *p;
689 struct dialog_helper dh = { { 0 } };
690 char *sub_call_id = switch_event_get_header(event, "sub-call-id")switch_event_get_header_idx(event, "sub-call-id", -1);
691 sofia_profile_t *profile;
692
693 //DUMP_EVENT(event);
694
695 if (!proto || strcasecmp(proto, SOFIA_CHAT_PROTO"sip") != 0) {
696 return;
697 }
698
699 if (!to || !(probe_user = strdup(to)(__extension__ (__builtin_constant_p (to) && ((size_t
)(const void *)((to) + 1) - (size_t)(const void *)(to) == 1) ?
(((const char *) (to))[0] == '\0' ? (char *) calloc ((size_t
) 1, (size_t) 1) : ({ size_t __len = strlen (to) + 1; char *__retval
= (char *) malloc (__len); if (__retval != ((void*)0)) __retval
= (char *) memcpy (__retval, to, __len); __retval; })) : __strdup
(to)))
)) {
700 return;
701 }
702
703 if ((probe_host = strchr(probe_user, '@')(__extension__ (__builtin_constant_p ('@') && !__builtin_constant_p
(probe_user) && ('@') == '\0' ? (char *) __rawmemchr
(probe_user, '@') : __builtin_strchr (probe_user, '@')))
)) {
704 *probe_host++ = '\0';
705 }
706 probe_euser = probe_user;
707 if ((p = strchr(probe_euser, '+')(__extension__ (__builtin_constant_p ('+') && !__builtin_constant_p
(probe_euser) && ('+') == '\0' ? (char *) __rawmemchr
(probe_euser, '+') : __builtin_strchr (probe_euser, '+')))
) && p != probe_euser) {
708 probe_euser = (p + 1);
709 }
710
711 if (probe_euser && probe_host &&
712 ((profile = sofia_glue_find_profile(probe_host)sofia_glue_find_profile__("sofia_presence.c", (const char *)__func__
, 712, probe_host)
) || (profile_name && (profile = sofia_glue_find_profile(profile_name)sofia_glue_find_profile__("sofia_presence.c", (const char *)__func__
, 712, profile_name)
)))) {
713 sql = switch_mprintf("select state,status,rpid,presence_id,uuid from sip_dialogs "
714 "where hostname='%q' and profile_name='%q' and call_info_state != 'seized' and "
715 "((sip_from_user='%q' and sip_from_host='%q') or presence_id='%q@%q') order by rcd desc",
716 mod_sofia_globals.hostname, profile->name, probe_euser, probe_host, probe_euser, probe_host);
717
718
719 sofia_glue_execute_sql_callback(profile, profile->dbh_mutex, sql, sofia_presence_dialog_callback, &dh);
720
721 h.profile = profile;
722
723 switch_safe_free(sql)if (sql) {free(sql);sql=((void*)0);};
724
725 sql = switch_mprintf("select sip_registrations.sip_user, "
726 "sip_registrations.sub_host, "
727 "sip_registrations.status, "
728 "sip_registrations.rpid, "
729 "'', "
730 "sip_dialogs.uuid, "
731 "sip_dialogs.state, "
732 "sip_dialogs.direction, "
733 "sip_dialogs.sip_to_user, "
734 "sip_dialogs.sip_to_host, "
735
736 "sip_presence.status,"
737 "sip_presence.rpid,"
738 "sip_dialogs.presence_id, "
739 "sip_presence.open_closed,"
740 "'%q','%q','%q' "
741 "from sip_registrations "
742
743 "left join sip_dialogs on "
744 "sip_dialogs.hostname = sip_registrations.hostname and sip_dialogs.profile_name = sip_registrations.profile_name and ("
745 "sip_dialogs.presence_id = sip_registrations.sip_user %q '@' %q sip_registrations.sub_host "
746 "or (sip_dialogs.sip_from_user = sip_registrations.sip_user "
747 "and sip_dialogs.sip_from_host = sip_registrations.sip_host)) "
748
749 "left join sip_presence on "
750 "sip_presence.hostname=sip_registrations.hostname and "
751 "(sip_registrations.sip_user=sip_presence.sip_user and sip_registrations.orig_server_host=sip_presence.sip_host and "
752 "sip_registrations.profile_name=sip_presence.profile_name) "
753 "where sip_registrations.hostname='%q' and sip_registrations.profile_name='%q' and sip_dialogs.call_info_state != 'seized' "
754 "and sip_dialogs.presence_id='%q@%q' or (sip_registrations.sip_user='%q' and "
755 "(sip_registrations.orig_server_host='%q' or sip_registrations.sub_host='%q' "
756 "))",
757 dh.status, dh.rpid, switch_str_nil(sub_call_id)(sub_call_id ? sub_call_id : ""),
758 switch_sql_concat(), switch_sql_concat(),
759 mod_sofia_globals.hostname, profile->name, probe_euser, probe_host, probe_euser, probe_host, probe_host);
760
761
762
763 switch_assert(sql)((sql) ? (void) (0) : __assert_fail ("sql", "sofia_presence.c"
, 763, __PRETTY_FUNCTION__))
;
764
765 if (mod_sofia_globals.debug_presence > 0) {
766 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 766, ((void*)0)
, SWITCH_LOG_INFO, "%s START_PRESENCE_PROBE_SQL\n", profile->name);
767 }
768
769 if (mod_sofia_globals.debug_presence > 1) {
770 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 770, ((void*)0)
, SWITCH_LOG_ERROR, "%s DUMP PRESENCE_PROBE_SQL:\n%s\n", profile->name, sql);
771 }
772
773 sofia_glue_execute_sql_callback(profile, profile->dbh_mutex, sql, sofia_presence_resub_callback, &h);
774 switch_safe_free(sql)if (sql) {free(sql);sql=((void*)0);};
775
776 if (!h.rowcount) {
777 h.noreg++;
778
779 /* find ones with presence_id defined that are not registred */
780 sql = switch_mprintf("select sip_from_user, sip_from_host, 'Registered', '', '', "
781 "uuid, state, direction, "
782 "sip_to_user, sip_to_host,"
783 "'%q','%q',presence_id, '','','' "
784
785 "from sip_dialogs "
786
787 "where call_info_state != 'seized' and hostname='%q' and profile_name='%q' and (presence_id='%q@%q' or "
788 "(sip_from_user='%q' and (sip_from_host='%q' or sip_to_host='%q')))",
789 mod_sofia_globals.hostname, profile->name,
790 dh.status, dh.rpid, probe_euser, probe_host, probe_euser, probe_host, probe_host);
791
792 if (mod_sofia_globals.debug_presence > 0) {
793 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 793, ((void*)0)
, SWITCH_LOG_INFO, "%s START_PRESENCE_PROBE_SQL\n", profile->name);
794 }
795
796 if (mod_sofia_globals.debug_presence > 1) {
797 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 797, ((void*)0)
, SWITCH_LOG_ERROR, "%s DUMP PRESENCE_PROBE_SQL:\n%s\n", profile->name, sql);
798 }
799
800 sofia_glue_execute_sql_callback(profile, profile->dbh_mutex, sql, sofia_presence_resub_callback, &h);
801 switch_safe_free(sql)if (sql) {free(sql);sql=((void*)0);};
802
803 if (mod_sofia_globals.debug_presence > 0) {
804 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 804, ((void*)0)
, SWITCH_LOG_INFO, "%s END_PRESENCE_PROBE_SQL\n\n", profile->name);
805 }
806 }
807
808 if (!h.rowcount) {
809 switch_event_t *sevent;
810 if (switch_event_create(&sevent, SWITCH_EVENT_PRESENCE_IN)switch_event_create_subclass_detailed("sofia_presence.c", (const
char * )(const char *)__func__, 810, &sevent, SWITCH_EVENT_PRESENCE_IN
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
811 switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "proto", SOFIA_CHAT_PROTO"sip");
812 switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "login", profile->name);
813 switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "sip_profile", profile->name);
814 switch_event_add_header(sevent, SWITCH_STACK_BOTTOM, "from", "%s@%s", probe_euser, probe_host);
815 switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "status", "Unregistered");
816 switch_event_fire(&sevent)switch_event_fire_detailed("sofia_presence.c", (const char * )
(const char *)__func__, 816, &sevent, ((void*)0))
;
817 }
818 }
819
820
821 sofia_glue_release_profile(profile)sofia_glue_release_profile__("sofia_presence.c", (const char *
)__func__, 821, profile)
;
822 }
823
824
825 switch_safe_free(probe_user)if (probe_user) {free(probe_user);probe_user=((void*)0);};
826}
827
828static void do_dialog_probe(switch_event_t *event)
829{
830 // Received SUBSCRIBE for "dialog" events.
831 // Return a complete list of dialogs for the monitored entity.
832 char *sql;
833 char *to = switch_event_get_header(event, "to")switch_event_get_header_idx(event, "to", -1);
834 char *probe_user = NULL((void*)0), *probe_euser, *probe_host, *p;
835
836 if (!to || !(probe_user = strdup(to)(__extension__ (__builtin_constant_p (to) && ((size_t
)(const void *)((to) + 1) - (size_t)(const void *)(to) == 1) ?
(((const char *) (to))[0] == '\0' ? (char *) calloc ((size_t
) 1, (size_t) 1) : ({ size_t __len = strlen (to) + 1; char *__retval
= (char *) malloc (__len); if (__retval != ((void*)0)) __retval
= (char *) memcpy (__retval, to, __len); __retval; })) : __strdup
(to)))
)) {
837 return;
838 }
839
840 if ((probe_host = strchr(probe_user, '@')(__extension__ (__builtin_constant_p ('@') && !__builtin_constant_p
(probe_user) && ('@') == '\0' ? (char *) __rawmemchr
(probe_user, '@') : __builtin_strchr (probe_user, '@')))
)) {
841 *probe_host++ = '\0';
842 }
843 probe_euser = probe_user;
844 if ((p = strchr(probe_euser, '+')(__extension__ (__builtin_constant_p ('+') && !__builtin_constant_p
(probe_euser) && ('+') == '\0' ? (char *) __rawmemchr
(probe_euser, '+') : __builtin_strchr (probe_euser, '+')))
) && p != probe_euser) {
845 probe_euser = (p + 1);
846 }
847
848 if (probe_euser && probe_host) {
849 char *sub_call_id = switch_event_get_header(event, "sub-call-id")switch_event_get_header_idx(event, "sub-call-id", -1);
850 char *profile_name = switch_event_get_header(event, "sip_profile")switch_event_get_header_idx(event, "sip_profile", -1);
851 sofia_profile_t *profile = sofia_glue_find_profile(probe_host)sofia_glue_find_profile__("sofia_presence.c", (const char *)__func__
, 851, probe_host)
;
852 struct rfc4235_helper *h4235 = {0};
853 switch_memory_pool_t *pool;
854
855 if (!profile && profile_name) {
856 profile = sofia_glue_find_profile(profile_name)sofia_glue_find_profile__("sofia_presence.c", (const char *)__func__
, 856, profile_name)
;
857 }
858
859 if (!profile) {
860 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 860, ((void*)0)
, SWITCH_LOG_WARNING, "Cannot find profile for domain %s\n", probe_host);
861 goto end;
862 }
863
864 // We need all dialogs with presence_id matching the subscription entity,
865 // or from a registered set matching the subscription entity.
866 // We need the "proto" of the subscription in case it is for the special "conf" or "park".
867 sql = switch_mprintf(
868 "select sip_subscriptions.proto, '%q','%q',"
869 "sip_dialogs.uuid, sip_dialogs.call_id, sip_dialogs.state, sip_dialogs.direction, "
870 "sip_dialogs.sip_to_user, sip_dialogs.sip_to_host, "
871 "sip_dialogs.sip_from_user, sip_dialogs.sip_from_host, "
872 "sip_dialogs.contact, sip_dialogs.contact_user, sip_dialogs.contact_host, "
873 "sip_dialogs.sip_to_tag, sip_dialogs.sip_from_tag, sip_subscriptions.orig_proto "
874 "from sip_dialogs "
875 "left join sip_subscriptions on sip_subscriptions.hostname=sip_dialogs.hostname and "
876 "sip_subscriptions.profile_name=sip_dialogs.profile_name and "
877 "sip_subscriptions.call_id='%q' "
878 "left join sip_registrations on sip_registrations.hostname=sip_dialogs.hostname and "
879 "sip_registrations.profile_name=sip_dialogs.profile_name and "
880 "(sip_dialogs.sip_from_user = sip_registrations.sip_user and sip_dialogs.sip_from_host = '%q' and "
881 "(sip_dialogs.sip_from_host = sip_registrations.orig_server_host or "
882 "sip_dialogs.sip_from_host = sip_registrations.sip_host) ) "
883 "where sip_dialogs.hostname='%q' and sip_dialogs.profile_name='%q' and "
884 "sip_dialogs.call_info_state != 'seized' and sip_dialogs.presence_id='%q@%q' or (sip_registrations.sip_user='%q' and "
885 "(sip_registrations.orig_server_host='%q' or sip_registrations.sub_host='%q' "
886 "or sip_registrations.presence_hosts like '%%%q%%'))",
887 probe_euser, probe_host,
888 sub_call_id, probe_host,
889 mod_sofia_globals.hostname, profile->name,
890 probe_euser, probe_host,
891 probe_euser, probe_host, probe_host, probe_host);
892 switch_assert(sql)((sql) ? (void) (0) : __assert_fail ("sql", "sofia_presence.c"
, 892, __PRETTY_FUNCTION__))
;
893
894 if (mod_sofia_globals.debug_presence > 0) {
895 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 895, ((void*)0)
,SWITCH_LOG_INFO, "%s START DIALOG_PROBE_SQL %s@%s\n", profile->name,probe_euser, probe_host);
896 }
897
898 if (mod_sofia_globals.debug_presence > 1) {
899 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 899, ((void*)0)
, SWITCH_LOG_DEBUG, "%s DUMP DIALOG_PROBE_SQL:\n%s\n", profile->name, sql);
900 }
901
902 switch_core_new_memory_pool(&pool)switch_core_perform_new_memory_pool(&pool, "sofia_presence.c"
, (const char *)__func__, 902)
;
903 h4235 = switch_core_alloc(pool, sizeof(*h4235))switch_core_perform_alloc(pool, sizeof(*h4235), "sofia_presence.c"
, (const char *)__func__, 903)
;
904 h4235->pool = pool;
905 h4235->profile = profile;
906 switch_core_hash_init(&h4235->hash)switch_core_hash_init_case(&h4235->hash, SWITCH_TRUE);
907 sofia_glue_execute_sql_callback(profile, profile->dbh_mutex, sql, sofia_dialog_probe_callback, h4235);
908 switch_safe_free(sql)if (sql) {free(sql);sql=((void*)0);};
909 if (mod_sofia_globals.debug_presence > 0) {
910 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 910, ((void*)0)
, SWITCH_LOG_INFO, "%s END DIALOG_PROBE_SQL\n\n", profile->name);
911 }
912
913
914 sql = switch_mprintf("update sip_subscriptions set version=version+1 where call_id='%q'", sub_call_id);
915
916 if (mod_sofia_globals.debug_presence > 1) {
917 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 917, ((void*)0)
, SWITCH_LOG_DEBUG, "%s DUMP DIALOG_PROBE set version sql:\n%s\n", profile->name, sql);
918 }
919 sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
920 switch_safe_free(sql)if (sql) {free(sql);sql=((void*)0);};
921
922
923 // The dialog_probe_callback has built up the dialogs to be included in the NOTIFY.
924 // Now send the "full" dialog event to the triggering subscription.
925 sql = switch_mprintf("select call_id,expires,sub_to_user,sub_to_host,event,version, "
926 "'full',full_to,full_from,contact,network_ip,network_port "
927 "from sip_subscriptions "
928 "where hostname='%q' and profile_name='%q' and sub_to_user='%q' and sub_to_host='%q' and call_id='%q'",
929 mod_sofia_globals.hostname, profile->name, probe_euser, probe_host, sub_call_id);
930
931 if (mod_sofia_globals.debug_presence > 1) {
932 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 932, ((void*)0)
, SWITCH_LOG_DEBUG, "%s DUMP DIALOG_PROBE subscription sql:\n%s\n", profile->name, sql);
933 }
934
935 sofia_glue_execute_sql_callback(profile, profile->dbh_mutex, sql, sofia_dialog_probe_notify_callback, h4235);
936 switch_safe_free(sql)if (sql) {free(sql);sql=((void*)0);};
937
938 sofia_glue_release_profile(profile)sofia_glue_release_profile__("sofia_presence.c", (const char *
)__func__, 938, profile)
;
939 switch_core_hash_destroy(&h4235->hash);
940 h4235 = NULL((void*)0);
941 switch_core_destroy_memory_pool(&pool)switch_core_perform_destroy_memory_pool(&pool, "sofia_presence.c"
, (const char *)__func__, 941)
;
942 }
943
944 end:
945
946 switch_safe_free(probe_user)if (probe_user) {free(probe_user);probe_user=((void*)0);};
947}
948
949static void send_conference_data(sofia_profile_t *profile, switch_event_t *event)
950{
951 char *sql;
952 struct pres_sql_cb cb = {profile, 0};
953 const char *call_id = switch_event_get_header(event, "call_id")switch_event_get_header_idx(event, "call_id", -1);
954 const char *from_user = switch_event_get_header(event, "conference-name")switch_event_get_header_idx(event, "conference-name", -1);
955 const char *from_host = switch_event_get_header(event, "conference-domain")switch_event_get_header_idx(event, "conference-domain", -1);
956 const char *event_str = switch_event_get_header(event, "conference-event")switch_event_get_header_idx(event, "conference-event", -1);
957 const char *notfound = switch_event_get_header(event, "notfound")switch_event_get_header_idx(event, "notfound", -1);
958 const char *body = switch_event_get_body(event);
959 const char *type = "application/conference-info+xml";
960 const char *final = switch_event_get_header(event, "final")switch_event_get_header_idx(event, "final", -1);
961
962 if (!event_str) {
963 event_str = "conference";
964 }
965
966 if (!strcasecmp(event_str, "refer")) {
967 type = "message/sipfrag";
968 }
969
970
971 if (!(from_user && from_host)) {
972 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 972, ((void*)0)
, SWITCH_LOG_ERROR, "Event information not given\n");
973 return;
974 }
975
976 if (switch_true(notfound)) {
977 sql = switch_mprintf("update sip_subscriptions set expires=%ld where "
978 "hostname='%q' and profile_name='%q' and sub_to_user='%q' and sub_to_host='%q' and event='%q'",
979 (long)switch_epoch_time_now(NULL((void*)0)),
980 mod_sofia_globals.hostname, profile->name,
981 from_user, from_host, event_str);
982
983 sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
984 }
985
986 if (call_id) {
987 if (switch_true(final)) {
988 sql = switch_mprintf("update sip_subscriptions set expires=%ld where "
989 "hostname='%q' and profile_name='%q' and sub_to_user='%q' and sub_to_host='%q' and event='%q' "
990 "and call_id = '%q' ",
991 (long)0,
992 mod_sofia_globals.hostname, profile->name,
993 from_user, from_host, event_str, call_id);
994
995 sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
996 }
997
998 sql = switch_mprintf("select full_to, full_from, contact %q ';_;isfocus', expires, call_id, event, network_ip, network_port, "
999 "'%q' as ct,'%q' as pt "
1000 " from sip_subscriptions where "
1001 "hostname='%q' and profile_name='%q' and sub_to_user='%q' and sub_to_host='%q' and event='%q' "
1002 "and call_id = '%q' ",
1003 switch_sql_concat(),
1004 type,
1005 switch_str_nil(body)(body ? body : ""),
1006 mod_sofia_globals.hostname, profile->name,
1007 from_user, from_host, event_str, call_id);
1008 } else {
1009 if (switch_true(final)) {
1010 sql = switch_mprintf("update sip_subscriptions set expires=%ld where "
1011 "hostname='%q' and profile_name='%q' and sub_to_user='%q' and sub_to_host='%q' and event='%q'",
1012 (long)0,
1013 mod_sofia_globals.hostname, profile->name,
1014 from_user, from_host, event_str);
1015
1016 sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
1017 }
1018
1019 sql = switch_mprintf("select full_to, full_from, contact %q ';_;isfocus', expires, call_id, event, network_ip, network_port, "
1020 "'%q' as ct,'%q' as pt "
1021 " from sip_subscriptions where "
1022 "hostname='%q' and profile_name='%q' and sub_to_user='%q' and sub_to_host='%q' and event='%q'",
1023 switch_sql_concat(),
1024 type,
1025 switch_str_nil(body)(body ? body : ""),
1026 mod_sofia_globals.hostname, profile->name,
1027 from_user, from_host, event_str);
1028 }
1029
1030 sofia_glue_execute_sql_callback(profile, profile->dbh_mutex, sql, sofia_presence_send_sql, &cb);
1031 switch_safe_free(sql)if (sql) {free(sql);sql=((void*)0);};
1032
1033 if (switch_true(final)) {
1034 if (call_id) {
1035 sql = switch_mprintf("delete from sip_subscriptions where "
1036 "hostname='%q' and profile_name='%q' and sub_to_user='%q' and sub_to_host='%q' and event='%q' "
1037 "and call_id = '%q' ",
1038 mod_sofia_globals.hostname, profile->name,
1039 from_user, from_host, event_str, call_id);
1040
1041 } else {
1042 sql = switch_mprintf("delete from sip_subscriptions where "
1043 "hostname='%q' and profile_name='%q' and sub_to_user='%q' and sub_to_host='%q' and event='%q'",
1044 mod_sofia_globals.hostname, profile->name,
1045 from_user, from_host, event_str);
1046 }
1047
1048 sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
1049 }
1050
1051
1052}
1053
1054static void conference_data_event_handler(switch_event_t *event)
1055{
1056 const char *pname;
1057 //const char *from_user = switch_event_get_header(event, "conference-name");
1058 //const char *from_host = switch_event_get_header(event, "conference-domain");
1059 const char *host = switch_event_get_header(event, "conference-domain")switch_event_get_header_idx(event, "conference-domain", -1);
1060 char *dup_domain = NULL((void*)0);
1061 sofia_profile_t *profile = NULL((void*)0);
1062
1063 if (zstr(host)_zstr(host)) {
1064 dup_domain = switch_core_get_domain(SWITCH_TRUE);
1065 host = dup_domain;
1066 }
1067
1068 if ((pname = switch_event_get_header(event, "sofia-profile")switch_event_get_header_idx(event, "sofia-profile", -1))) {
1069 profile = sofia_glue_find_profile(pname)sofia_glue_find_profile__("sofia_presence.c", (const char *)__func__
, 1069, pname)
;
1070 }
1071
1072 if (host && !profile) {
1073 profile = sofia_glue_find_profile(host)sofia_glue_find_profile__("sofia_presence.c", (const char *)__func__
, 1073, host)
;
1074 }
1075
1076 if (profile) {
1077 send_conference_data(profile, event);
1078 sofia_glue_release_profile(profile)sofia_glue_release_profile__("sofia_presence.c", (const char *
)__func__, 1078, profile)
;
1079 } else {
1080 switch_console_callback_match_t *matches;
1081
1082 if (list_profiles_full(NULL((void*)0), NULL((void*)0), &matches, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) {
1083 switch_console_callback_match_node_t *m;
1084
1085 for (m = matches->head; m; m = m->next) {
1086 if ((profile = sofia_glue_find_profile(m->val)sofia_glue_find_profile__("sofia_presence.c", (const char *)__func__
, 1086, m->val)
)) {
1087 send_conference_data(profile, event);
1088 sofia_glue_release_profile(profile)sofia_glue_release_profile__("sofia_presence.c", (const char *
)__func__, 1088, profile)
;
1089 }
1090 }
1091
1092 switch_console_free_matches(&matches);
1093 }
1094 }
1095
1096 switch_safe_free(dup_domain)if (dup_domain) {free(dup_domain);dup_domain=((void*)0);};
1097}
1098
1099static switch_event_t *actual_sofia_presence_event_handler(switch_event_t *event)
1100{
1101 sofia_profile_t *profile = NULL((void*)0);
1102 char *from = switch_event_get_header(event, "from")switch_event_get_header_idx(event, "from", -1);
1103 char *proto = switch_event_get_header(event, "proto")switch_event_get_header_idx(event, "proto", -1);
1104 char *rpid = switch_event_get_header(event, "rpid")switch_event_get_header_idx(event, "rpid", -1);
1105 char *status = switch_event_get_header(event, "status")switch_event_get_header_idx(event, "status", -1);
1106 char *event_type = switch_event_get_header(event, "event_type")switch_event_get_header_idx(event, "event_type", -1);
1107 char *alt_event_type = switch_event_get_header(event, "alt_event_type")switch_event_get_header_idx(event, "alt_event_type", -1);
1108 //char *event_subtype = switch_event_get_header(event, "event_subtype");
1109 char *sql = NULL((void*)0);
1110 char *euser = NULL((void*)0), *user = NULL((void*)0), *host = NULL((void*)0);
1111 char *call_info = switch_event_get_header(event, "presence-call-info")switch_event_get_header_idx(event, "presence-call-info", -1);
1112 char *call_id = switch_event_get_header(event, "call-id")switch_event_get_header_idx(event, "call-id", -1);
1113 char *presence_source = switch_event_get_header(event, "presence-source")switch_event_get_header_idx(event, "presence-source", -1);
1114 char *call_info_state = switch_event_get_header(event, "presence-call-info-state")switch_event_get_header_idx(event, "presence-call-info-state"
, -1)
;
1115 const char *uuid = switch_event_get_header(event, "unique-id")switch_event_get_header_idx(event, "unique-id", -1);
1116 switch_console_callback_match_t *matches = NULL((void*)0);
1117 struct presence_helper helper = { 0 };
1118 int hup = 0;
1119 switch_event_t *s_event = NULL((void*)0);
1120
1121 if (!mod_sofia_globals.running) {
1122 goto done;
1123 }
1124
1125 if (zstr(proto)_zstr(proto) || !strcasecmp(proto, "any")) {
1126 proto = SOFIA_CHAT_PROTO"sip";
1127 }
1128
1129 //DUMP_EVENT(event);
1130
1131 if (rpid && !strcasecmp(rpid, "n/a")) {
1132 rpid = NULL((void*)0);
1133 }
1134
1135 if (status && !strcasecmp(status, "n/a")) {
1136 status = NULL((void*)0);
1137 }
1138
1139 if (!zstr(uuid)_zstr(uuid) && !switch_ivr_uuid_exists(uuid)) {
1140 status = "CS_HANGUP";
1141 }
1142
1143
1144 if ((status && switch_stristr("CS_HANGUP", status)) || (!zstr(uuid)_zstr(uuid) && !switch_ivr_uuid_exists(uuid))) {
1145 status = "Available";
1146 hup = 1;
1147 }
1148
1149 if (rpid) {
1150 rpid = sofia_presence_translate_rpid(rpid, status);
1151 }
1152
1153 if (event->event_id == SWITCH_EVENT_ROSTER) {
1154 if (list_profiles_full(NULL((void*)0), NULL((void*)0), &matches, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) {
1155 switch_console_callback_match_node_t *m;
1156
1157 for (m = matches->head; m; m = m->next) {
1158 if ((profile = sofia_glue_find_profile(m->val)sofia_glue_find_profile__("sofia_presence.c", (const char *)__func__
, 1158, m->val)
)) {
1159 if (profile->pres_type != PRES_TYPE_FULL) {
1160
1161
1162 if (!mod_sofia_globals.profile_hash) {
1163 switch_console_free_matches(&matches);
1164 goto done;
1165 }
1166
1167 if (from) {
1168
1169 sql = switch_mprintf("update sip_subscriptions set version=version+1 where hostname='%q' and profile_name='%q' and "
1170 "sip_subscriptions.event='presence' and sip_subscriptions.full_from like '%%%q%%'",
1171 mod_sofia_globals.hostname, profile->name, from);
1172
1173 if (mod_sofia_globals.debug_presence > 1) {
1174 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 1174, ((void*)0)
, SWITCH_LOG_ERROR, "PRES SQL %s\n", sql);
1175 }
1176
1177 sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
1178
1179
1180 sql = switch_mprintf("select sip_subscriptions.proto,sip_subscriptions.sip_user,sip_subscriptions.sip_host,"
1181 "sip_subscriptions.sub_to_user,sip_subscriptions.sub_to_host,sip_subscriptions.event,"
1182 "sip_subscriptions.contact,sip_subscriptions.call_id,sip_subscriptions.full_from,"
1183 "sip_subscriptions.full_via,sip_subscriptions.expires,sip_subscriptions.user_agent,"
1184 "sip_subscriptions.accept,sip_subscriptions.profile_name,sip_subscriptions.network_ip"
1185 ",1,'%q','%q',sip_presence.status,sip_presence.rpid,sip_presence.open_closed,'','','','','sip',"
1186 " sip_subscriptions.full_to,sip_subscriptions.network_ip,sip_subscriptions.network_port "
1187 "from sip_subscriptions left join sip_presence on "
1188 "(sip_subscriptions.sub_to_user=sip_presence.sip_user and "
1189 "sip_subscriptions.sub_to_host=sip_presence.sip_host and "
1190 "sip_subscriptions.profile_name=sip_presence.profile_name and "
1191 "sip_presence.profile_name=sip_subscriptions.profile_name) "
1192 "where sip_subscriptions.hostname='%q' and sip_subscriptions.profile_name='%q' and "
1193 "sip_subscriptions.event='presence' and sip_subscriptions.full_from like '%%%q%%'",
1194 switch_str_nil(status)(status ? status : ""), switch_str_nil(rpid)(rpid ? rpid : ""), mod_sofia_globals.hostname, profile->name, from);
1195 } else {
1196
1197 sql = switch_mprintf("update sip_subscriptions set version=version+1 where hostname='%q' and profile_name='%q' and "
1198 "sip_subscriptions.event='presence'", mod_sofia_globals.hostname, profile->name);
1199
1200 if (mod_sofia_globals.debug_presence > 1) {
1201 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 1201, ((void*)0)
, SWITCH_LOG_ERROR, "PRES SQL %s\n", sql);
1202 }
1203
1204 sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
1205
1206 sql = switch_mprintf("select sip_subscriptions.proto,sip_subscriptions.sip_user,sip_subscriptions.sip_host,"
1207 "sip_subscriptions.sub_to_user,sip_subscriptions.sub_to_host,sip_subscriptions.event,"
1208 "sip_subscriptions.contact,sip_subscriptions.call_id,sip_subscriptions.full_from,"
1209 "sip_subscriptions.full_via,sip_subscriptions.expires,sip_subscriptions.user_agent,"
1210 "sip_subscriptions.accept,sip_subscriptions.profile_name,sip_subscriptions.network_ip"
1211 ",1,'%q','%q',sip_presence.status,sip_presence.rpid,sip_presence.open_closed,'','','','','sip',"
1212 "sip_subscriptions.full_to,sip_subscriptions.network_ip,sip_subscriptions.network_port "
1213 "from sip_subscriptions left join sip_presence on "
1214 "(sip_subscriptions.sub_to_user=sip_presence.sip_user and "
1215 "sip_subscriptions.sub_to_host=sip_presence.sip_host and "
1216 "sip_subscriptions.profile_name=sip_presence.profile_name and "
1217 "sip_subscriptions.hostname = sip_presence.hostname) "
1218 "where sip_subscriptions.hostname='%q' and sip_subscriptions.profile_name='%q' and "
1219 "sip_subscriptions.event='presence'", switch_str_nil(status)(status ? status : ""),
1220 switch_str_nil(rpid)(rpid ? rpid : ""), mod_sofia_globals.hostname, profile->name);
1221 }
1222
1223 switch_assert(sql != NULL)((sql != ((void*)0)) ? (void) (0) : __assert_fail ("sql != ((void*)0)"
, "sofia_presence.c", 1223, __PRETTY_FUNCTION__))
;
1224
1225
1226 if (mod_sofia_globals.debug_presence > 0) {
1227 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 1227, ((void*)0)
, SWITCH_LOG_WARNING, "%s is passive, skipping\n", (char *) profile->name);
1228 }
1229 sofia_glue_release_profile(profile)sofia_glue_release_profile__("sofia_presence.c", (const char *
)__func__, 1229, profile)
;
1230 continue;
1231 }
1232 memset(&helper, 0, sizeof(helper));
1233 helper.profile = profile;
1234 helper.event = NULL((void*)0);
1235 sofia_glue_execute_sql_callback(profile, profile->dbh_mutex, sql, sofia_presence_sub_callback, &helper);
1236 switch_safe_free(sql)if (sql) {free(sql);sql=((void*)0);};
1237 sofia_glue_release_profile(profile)sofia_glue_release_profile__("sofia_presence.c", (const char *
)__func__, 1237, profile)
;
1238 }
1239 }
1240 switch_console_free_matches(&matches);
1241 }
1242
1243 switch_safe_free(sql)if (sql) {free(sql);sql=((void*)0);};
1244 goto done;
1245 }
1246
1247 if (zstr(event_type)_zstr(event_type)) {
1248 event_type = "presence";
1249 }
1250
1251 if (zstr(alt_event_type)_zstr(alt_event_type)) {
1252 if (!strcasecmp(event_type, "presence")) {
1253 alt_event_type = "dialog";
1254 } else {
1255 alt_event_type = "presence";
1256 }
1257 }
1258
1259 if (from && (user = strdup(from)(__extension__ (__builtin_constant_p (from) && ((size_t
)(const void *)((from) + 1) - (size_t)(const void *)(from) ==
1) ? (((const char *) (from))[0] == '\0' ? (char *) calloc (
(size_t) 1, (size_t) 1) : ({ size_t __len = strlen (from) + 1
; char *__retval = (char *) malloc (__len); if (__retval != (
(void*)0)) __retval = (char *) memcpy (__retval, from, __len)
; __retval; })) : __strdup (from)))
)) {
1260 if ((host = strchr(user, '@')(__extension__ (__builtin_constant_p ('@') && !__builtin_constant_p
(user) && ('@') == '\0' ? (char *) __rawmemchr (user
, '@') : __builtin_strchr (user, '@')))
)) {
1261 char *p;
1262 *host++ = '\0';
1263 if ((p = strchr(host, '/')(__extension__ (__builtin_constant_p ('/') && !__builtin_constant_p
(host) && ('/') == '\0' ? (char *) __rawmemchr (host
, '/') : __builtin_strchr (host, '/')))
)) {
1264 *p = '\0';
1265 }
1266 } else {
1267 switch_safe_free(user)if (user) {free(user);user=((void*)0);};
1268 goto done;
1269 }
1270 if ((euser = strchr(user, '+')(__extension__ (__builtin_constant_p ('+') && !__builtin_constant_p
(user) && ('+') == '\0' ? (char *) __rawmemchr (user
, '+') : __builtin_strchr (user, '+')))
) && euser != user) {
1271 euser++;
1272 } else {
1273 euser = user;
1274 }
1275 } else {
1276 goto done;
1277 }
1278
1279 switch (event->event_id) {
1280 case SWITCH_EVENT_PRESENCE_PROBE:
1281 {
1282 char *probe_type = switch_event_get_header(event, "probe-type")switch_event_get_header_idx(event, "probe-type", -1);
1283
1284 if (!probe_type || strcasecmp(probe_type, "dialog")) {
1285 /* NORMAL PROBE */
1286 do_normal_probe(event);
1287 } else {
1288 /* DIALOG PROBE */
1289 do_dialog_probe(event);
1290 }
1291 }
1292 goto done;
1293
1294 default:
1295 break;
1296 }
1297
1298 if (!mod_sofia_globals.profile_hash) {
1299 goto done;
1300 }
1301
1302 if (list_profiles_full(NULL((void*)0), NULL((void*)0), &matches, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) {
1303 switch_console_callback_match_node_t *m;
1304
1305 for (m = matches->head; m; m = m->next) {
1306 struct dialog_helper dh = { { 0 } };
1307
1308 if ((profile = sofia_glue_find_profile(m->val)sofia_glue_find_profile__("sofia_presence.c", (const char *)__func__
, 1308, m->val)
)) {
1309 if (profile->pres_type != PRES_TYPE_FULL) {
1310 if (mod_sofia_globals.debug_presence > 0) {
1311 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 1311, ((void*)0)
, SWITCH_LOG_WARNING, "%s is passive, skipping\n", (char *) profile->name);
1312 }
1313 sofia_glue_release_profile(profile)sofia_glue_release_profile__("sofia_presence.c", (const char *
)__func__, 1313, profile)
;
1314 continue;
1315 }
1316
1317
1318 if (mod_sofia_globals.debug_sla > 1) {
1319 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 1319, ((void*)0)
, SWITCH_LOG_ERROR, "SLA EVENT:\n");
1320 DUMP_EVENT(event){char *event_str;switch_event_serialize(event, &event_str
, SWITCH_FALSE);switch_log_printf(SWITCH_CHANNEL_ID_LOG, "sofia_presence.c"
, (const char *)__func__, 1320, ((void*)0), SWITCH_LOG_CRIT, "DUMP\n%s\n"
, event_str);free(event_str);}
;
1321
1322 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 1322, ((void*)0)
, SWITCH_LOG_ERROR, "CHECK CALL_INFO [%s]\n", switch_str_nil(call_info)(call_info ? call_info : ""));
1323 }
1324
1325 if (call_info) {
1326
1327 if (uuid) {
1328 sql = switch_mprintf("update sip_dialogs set call_info='%q',call_info_state='%q' where "
1329 "hostname='%q' and profile_name='%q' and uuid='%q'",
1330 call_info, call_info_state, mod_sofia_globals.hostname, profile->name, uuid);
1331 } else {
1332 sql = switch_mprintf("update sip_dialogs set call_info='%q', call_info_state='%q' where hostname='%q' and profile_name='%q' and "
1333 "((sip_dialogs.sip_from_user='%q' and sip_dialogs.sip_from_host='%q') or presence_id='%q@%q') and call_info='%q'",
1334
1335 call_info, call_info_state, mod_sofia_globals.hostname, profile->name, euser, host, euser, host, call_info);
1336
1337 }
1338
1339 if (mod_sofia_globals.debug_sla > 1) {
1340 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 1340, ((void*)0)
, SWITCH_LOG_ERROR, "STATE SQL %s\n", sql);
1341 }
1342 sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
1343
1344
1345
1346 if (mod_sofia_globals.debug_sla > 1) {
1347 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 1347, ((void*)0)
, SWITCH_LOG_ERROR, "PROCESS PRESENCE EVENT\n");
1348 }
1349
1350 sync_sla(profile, euser, host, SWITCH_TRUE, SWITCH_TRUE, call_id);
1351 }
1352
1353 if (!strcmp(proto, "dp")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(proto) && __builtin_constant_p ("dp") && (__s1_len
= __builtin_strlen (proto), __s2_len = __builtin_strlen ("dp"
), (!((size_t)(const void *)((proto) + 1) - (size_t)(const void
*)(proto) == 1) || __s1_len >= 4) && (!((size_t)(
const void *)(("dp") + 1) - (size_t)(const void *)("dp") == 1
) || __s2_len >= 4)) ? __builtin_strcmp (proto, "dp") : (__builtin_constant_p
(proto) && ((size_t)(const void *)((proto) + 1) - (size_t
)(const void *)(proto) == 1) && (__s1_len = __builtin_strlen
(proto), __s1_len < 4) ? (__builtin_constant_p ("dp") &&
((size_t)(const void *)(("dp") + 1) - (size_t)(const void *)
("dp") == 1) ? __builtin_strcmp (proto, "dp") : (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) ("dp"); int __result = (((const unsigned char *) (const
char *) (proto))[0] - __s2[0]); if (__s1_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (proto))[1] - __s2[1]); if (__s1_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (proto))[2] - __s2[2]); if (__s1_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (proto))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
("dp") && ((size_t)(const void *)(("dp") + 1) - (size_t
)(const void *)("dp") == 1) && (__s2_len = __builtin_strlen
("dp"), __s2_len < 4) ? (__builtin_constant_p (proto) &&
((size_t)(const void *)((proto) + 1) - (size_t)(const void *
)(proto) == 1) ? __builtin_strcmp (proto, "dp") : (- (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) (proto); int __result = (((const unsigned char *) (const
char *) ("dp"))[0] - __s2[0]); if (__s2_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) ("dp"))[1] - __s2[1]); if (__s2_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) ("dp"))[2] - __s2[2]); if (__s2_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) ("dp"))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp
(proto, "dp")))); })
) {
1354 sql = switch_mprintf("update sip_presence set rpid='%q',status='%q' where hostname='%q' and profile_name='%q' and "
1355 "sip_user='%q' and sip_host='%q'",
1356 rpid, status, mod_sofia_globals.hostname, profile->name, euser, host);
1357 sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
1358 proto = SOFIA_CHAT_PROTO"sip";
1359 }
1360
1361 if (zstr(uuid)_zstr(uuid)) {
1362
1363 sql = switch_mprintf("select state,status,rpid,presence_id,uuid from sip_dialogs "
1364 "where call_info_state != 'seized' and hostname='%q' and profile_name='%q' and "
1365 "((sip_from_user='%q' and sip_from_host='%q') or presence_id='%q@%q') order by rcd desc",
1366 mod_sofia_globals.hostname, profile->name, euser, host, euser, host);
1367 } else {
1368 sql = switch_mprintf("select state,status,rpid,presence_id,uuid from sip_dialogs "
1369 "where uuid != '%q' and call_info_state != 'seized' and hostname='%q' and profile_name='%q' and "
1370 "((sip_from_user='%q' and sip_from_host='%q') or presence_id='%q@%q') order by rcd desc",
1371 uuid, mod_sofia_globals.hostname, profile->name, euser, host, euser, host);
1372 }
1373
1374 sofia_glue_execute_sql_callback(profile, profile->dbh_mutex, sql, sofia_presence_dialog_callback, &dh);
1375
1376 if (mod_sofia_globals.debug_presence > 0) {
1377 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 1377, ((void*)0)
, SWITCH_LOG_CRIT, "CHECK SQL: %s@%s [%s]\nhits: %d\n", euser, host, sql, dh.hits);
1378 }
1379
1380 switch_safe_free(sql)if (sql) {free(sql);sql=((void*)0);};
1381
1382 if (hup && dh.hits > 0) {
1383 /* sigh, mangle this packet to simulate a call that is up instead of hungup */
1384 hup = 0;
1385 event->flags |= EF_UNIQ_HEADERS;
1386
1387 if (!strcasecmp(dh.state, "early")) {
1388 status = "CS_ROUTING";
1389 if (rpid) {
1390 rpid = sofia_presence_translate_rpid(rpid, status);
1391 }
1392
1393 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Answer-State", "early");
1394 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "status", status);
1395 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Channel-State", status);
1396 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Channel-Call-State", "EARLY");
1397 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "astate", "early");
1398 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "answer-state", "early");
1399 } else {
1400 status = "CS_EXECUTE";
1401 if (rpid) {
1402 rpid = sofia_presence_translate_rpid(rpid, status);
1403 }
1404
1405 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Answer-State", "answered");
1406 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "status", status);
1407 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Channel-State", status);
1408 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Channel-Call-State", "ACTIVE");
1409 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "astate", "confirmed");
1410 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "answer-state", "confirmed");
1411 }
1412 }
1413
1414
1415
1416 if (zstr(call_id)_zstr(call_id) && (dh.hits && presence_source && (!strcasecmp(presence_source, "register") || switch_stristr("register", status)))) {
1417 goto done;
1418 }
1419
1420 if (zstr(call_id)_zstr(call_id)) {
1421
1422 sql = switch_mprintf("update sip_subscriptions set version=version+1 where hostname='%q' and profile_name='%q' and "
1423 "sip_subscriptions.event != 'line-seize' "
1424 "and sip_subscriptions.proto='%q' and (event='%q' or event='%q') and sub_to_user='%q' and "
1425 "(sub_to_host='%q' or sub_to_host='%q' or sub_to_host='%q' or "
1426 "presence_hosts like '%%%q%%') and "
1427 "(sip_subscriptions.profile_name = '%q' or presence_hosts like '%%%q%%')",
1428 mod_sofia_globals.hostname, profile->name,
1429 proto, event_type, alt_event_type, euser, host, profile->sipip,
1430 profile->extsipip ? profile->extsipip : "N/A", host, profile->name, host);
1431
1432
1433 if (mod_sofia_globals.debug_presence > 1) {
1434 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 1434, ((void*)0)
, SWITCH_LOG_ERROR, "PRES SQL %s\n", sql);
1435 }
1436
1437 sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
1438
1439
1440
1441 sql = switch_mprintf("select distinct sip_subscriptions.proto,sip_subscriptions.sip_user,sip_subscriptions.sip_host,"
1442 "sip_subscriptions.sub_to_user,sip_subscriptions.sub_to_host,sip_subscriptions.event,"
1443 "sip_subscriptions.contact,sip_subscriptions.call_id,sip_subscriptions.full_from,"
1444 "sip_subscriptions.full_via,sip_subscriptions.expires,sip_subscriptions.user_agent,"
1445 "sip_subscriptions.accept,sip_subscriptions.profile_name"
1446 ",'%q','%q','%q',sip_presence.status,sip_presence.rpid,sip_presence.open_closed,'%q','%q',"
1447 "sip_subscriptions.version, '%q',sip_subscriptions.orig_proto,sip_subscriptions.full_to,"
1448 "sip_subscriptions.network_ip, sip_subscriptions.network_port "
1449 "from sip_subscriptions "
1450 "left join sip_presence on "
1451 "(sip_subscriptions.sub_to_user=sip_presence.sip_user and sip_subscriptions.sub_to_host=sip_presence.sip_host and "
1452 "sip_subscriptions.profile_name=sip_presence.profile_name and sip_subscriptions.hostname=sip_presence.hostname) "
1453
1454 "where sip_subscriptions.hostname='%q' and sip_subscriptions.profile_name='%q' and "
1455 "sip_subscriptions.event != 'line-seize' and "
1456 "sip_subscriptions.proto='%q' and "
1457 "(event='%q' or event='%q') and sub_to_user='%q' "
1458 "and (sub_to_host='%q' or sub_to_host='%q' or sub_to_host='%q' or presence_hosts like '%%%q%%') ",
1459
1460
1461 switch_str_nil(status)(status ? status : ""), switch_str_nil(rpid)(rpid ? rpid : ""), host,
1462 dh.status,dh.rpid,dh.presence_id, mod_sofia_globals.hostname, profile->name, proto,
1463 event_type, alt_event_type, euser, host, profile->sipip,
1464 profile->extsipip ? profile->extsipip : "N/A", host);
1465 } else {
1466
1467 sql = switch_mprintf("update sip_subscriptions set version=version+1 where sip_subscriptions.event != 'line-seize' and "
1468 "sip_subscriptions.call_id='%q'", call_id);
1469
1470
1471
1472 if (mod_sofia_globals.debug_presence > 1) {
1473 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 1473, ((void*)0)
, SWITCH_LOG_ERROR, "PRES SQL %s\n", sql);
1474 }
1475
1476 sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
1477
1478
1479 sql = switch_mprintf("select distinct sip_subscriptions.proto,sip_subscriptions.sip_user,sip_subscriptions.sip_host,"
1480 "sip_subscriptions.sub_to_user,sip_subscriptions.sub_to_host,sip_subscriptions.event,"
1481 "sip_subscriptions.contact,sip_subscriptions.call_id,sip_subscriptions.full_from,"
1482 "sip_subscriptions.full_via,sip_subscriptions.expires,sip_subscriptions.user_agent,"
1483 "sip_subscriptions.accept,sip_subscriptions.profile_name"
1484 ",'%q','%q','%q',sip_presence.status,sip_presence.rpid,sip_presence.open_closed,'%q','%q',"
1485 "sip_subscriptions.version, '%q',sip_subscriptions.orig_proto,sip_subscriptions.full_to,"
1486 "sip_subscriptions.network_ip, sip_subscriptions.network_port "
1487 "from sip_subscriptions "
1488 "left join sip_presence on "
1489 "(sip_subscriptions.sub_to_user=sip_presence.sip_user and sip_subscriptions.sub_to_host=sip_presence.sip_host and "
1490 "sip_subscriptions.profile_name=sip_presence.profile_name and sip_subscriptions.hostname=sip_presence.hostname) "
1491
1492 "where sip_subscriptions.hostname='%q' and sip_subscriptions.profile_name='%q' and "
1493 "sip_subscriptions.event != 'line-seize' and "
1494 "sip_subscriptions.call_id='%q'",
1495
1496 switch_str_nil(status)(status ? status : ""), switch_str_nil(rpid)(rpid ? rpid : ""), host,
1497 dh.status,dh.rpid,dh.presence_id, mod_sofia_globals.hostname, profile->name, call_id);
1498
1499 }
1500
1501 helper.hup = hup;
1502 helper.calls_up = dh.hits;
1503 helper.profile = profile;
1504 helper.event = event;
1505 SWITCH_STANDARD_STREAM(helper.stream)memset(&helper.stream, 0, sizeof(helper.stream)); helper.
stream.data = malloc(1024); ((helper.stream.data) ? (void) (0
) : __assert_fail ("helper.stream.data", "sofia_presence.c", 1505
, __PRETTY_FUNCTION__)); memset(helper.stream.data, 0, 1024);
helper.stream.end = helper.stream.data; helper.stream.data_size
= 1024; helper.stream.write_function = switch_console_stream_write
; helper.stream.raw_write_function = switch_console_stream_raw_write
; helper.stream.alloc_len = 1024; helper.stream.alloc_chunk =
1024
;
1506 switch_assert(helper.stream.data)((helper.stream.data) ? (void) (0) : __assert_fail ("helper.stream.data"
, "sofia_presence.c", 1506, __PRETTY_FUNCTION__))
;
1507
1508 if (mod_sofia_globals.debug_presence > 0) {
1509 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 1509, ((void*)0)
, SWITCH_LOG_INFO, "%s START_PRESENCE_SQL (%s)\n",
1510 event->event_id == SWITCH_EVENT_PRESENCE_IN ? "IN" : "OUT", profile->name);
1511 }
1512
1513 if (mod_sofia_globals.debug_presence) {
1514 char *buf;
1515 switch_event_serialize(event, &buf, SWITCH_FALSE);
1516 switch_assert(buf)((buf) ? (void) (0) : __assert_fail ("buf", "sofia_presence.c"
, 1516, __PRETTY_FUNCTION__))
;
1517 if (mod_sofia_globals.debug_presence > 1) {
1518 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 1518, ((void*)0)
, SWITCH_LOG_ERROR, "DUMP PRESENCE SQL:\n%s\nEVENT DUMP:\n%s\n", sql, buf);
1519 } else {
1520 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 1520, ((void*)0)
, SWITCH_LOG_ERROR, "EVENT DUMP:\n%s\n", buf);
1521 }
1522 free(buf);
1523 }
1524
1525 sofia_glue_execute_sql_callback(profile, profile->dbh_mutex, sql, sofia_presence_sub_callback, &helper);
1526 switch_safe_free(sql)if (sql) {free(sql);sql=((void*)0);};
1527
1528 if (mod_sofia_globals.debug_presence > 0) {
1529 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 1529, ((void*)0)
, SWITCH_LOG_INFO, "%s END_PRESENCE_SQL (%s)\n",
1530 event->event_id == SWITCH_EVENT_PRESENCE_IN ? "IN" : "OUT", profile->name);
1531 }
1532
1533#if 0
1534 if (hup && dh.hits < 1) {
1535 /* so many phones get confused when whe hangup we have to reprobe to get them all to reset to absolute states so the lights stay correct */
1536 if (switch_event_create(&s_event, SWITCH_EVENT_PRESENCE_PROBE)switch_event_create_subclass_detailed("sofia_presence.c", (const
char * )(const char *)__func__, 1536, &s_event, SWITCH_EVENT_PRESENCE_PROBE
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
1537 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "proto", SOFIA_CHAT_PROTO"sip");
1538 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "login", profile->name);
1539 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "sip_profile", profile->name);
1540 switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "from", "%s@%s", euser, host);
1541 switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "to", "%s@%s", euser, host);
1542 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "event_type", "presence");
1543 switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "alt_event_type", "dialog");
1544 sofia_event_fire(profile, &s_event);
1545 }
1546 }
1547#endif
1548
1549 if (!zstr((char *) helper.stream.data)_zstr((char *) helper.stream.data)) {
1550 char *this_sql = (char *) helper.stream.data;
1551 char *next = NULL((void*)0);
1552 char *last = NULL((void*)0);
1553
1554 do {
1555 if ((next = strchr(this_sql, ';')(__extension__ (__builtin_constant_p (';') && !__builtin_constant_p
(this_sql) && (';') == '\0' ? (char *) __rawmemchr (
this_sql, ';') : __builtin_strchr (this_sql, ';')))
)) {
1556 *next++ = '\0';
1557 while (*next == '\n' || *next == ' ' || *next == '\r') {
1558 *next++ = '\0';
1559 }
1560 }
1561
1562 if (!zstr(this_sql)_zstr(this_sql) && (!last || strcmp(last, this_sql)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(last) && __builtin_constant_p (this_sql) &&
(__s1_len = __builtin_strlen (last), __s2_len = __builtin_strlen
(this_sql), (!((size_t)(const void *)((last) + 1) - (size_t)
(const void *)(last) == 1) || __s1_len >= 4) && (!
((size_t)(const void *)((this_sql) + 1) - (size_t)(const void
*)(this_sql) == 1) || __s2_len >= 4)) ? __builtin_strcmp (
last, this_sql) : (__builtin_constant_p (last) && ((size_t
)(const void *)((last) + 1) - (size_t)(const void *)(last) ==
1) && (__s1_len = __builtin_strlen (last), __s1_len <
4) ? (__builtin_constant_p (this_sql) && ((size_t)(const
void *)((this_sql) + 1) - (size_t)(const void *)(this_sql) ==
1) ? __builtin_strcmp (last, this_sql) : (__extension__ ({ const
unsigned char *__s2 = (const unsigned char *) (const char *)
(this_sql); int __result = (((const unsigned char *) (const char
*) (last))[0] - __s2[0]); if (__s1_len > 0 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
last))[1] - __s2[1]); if (__s1_len > 1 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
last))[2] - __s2[2]); if (__s1_len > 2 && __result
== 0) __result = (((const unsigned char *) (const char *) (last
))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p (
this_sql) && ((size_t)(const void *)((this_sql) + 1) -
(size_t)(const void *)(this_sql) == 1) && (__s2_len =
__builtin_strlen (this_sql), __s2_len < 4) ? (__builtin_constant_p
(last) && ((size_t)(const void *)((last) + 1) - (size_t
)(const void *)(last) == 1) ? __builtin_strcmp (last, this_sql
) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (last); int __result = (((const unsigned
char *) (const char *) (this_sql))[0] - __s2[0]); if (__s2_len
> 0 && __result == 0) { __result = (((const unsigned
char *) (const char *) (this_sql))[1] - __s2[1]); if (__s2_len
> 1 && __result == 0) { __result = (((const unsigned
char *) (const char *) (this_sql))[2] - __s2[2]); if (__s2_len
> 2 && __result == 0) __result = (((const unsigned
char *) (const char *) (this_sql))[3] - __s2[3]); } } __result
; })))) : __builtin_strcmp (last, this_sql)))); })
)) {
1563 sofia_glue_execute_sql(profile, &this_sql, SWITCH_FALSE);
1564 last = this_sql;
1565 }
1566 this_sql = next;
1567 } while (this_sql);
1568 }
1569 switch_safe_free(helper.stream.data)if (helper.stream.data) {free(helper.stream.data);helper.stream
.data=((void*)0);}
;
1570 helper.stream.data = NULL((void*)0);
1571
1572 sofia_glue_release_profile(profile)sofia_glue_release_profile__("sofia_presence.c", (const char *
)__func__, 1572, profile)
;
1573 }
1574 }
1575 switch_console_free_matches(&matches);
1576 }
1577
1578 done:
1579
1580 switch_safe_free(sql)if (sql) {free(sql);sql=((void*)0);};
1581 switch_safe_free(user)if (user) {free(user);user=((void*)0);};
1582
1583 return s_event;
1584}
1585
1586static int EVENT_THREAD_RUNNING = 0;
1587static int EVENT_THREAD_STARTED = 0;
1588
1589static void do_flush(void)
1590{
1591 void *pop = NULL((void*)0);
1592
1593 while (mod_sofia_globals.presence_queue && switch_queue_trypop(mod_sofia_globals.presence_queue, &pop) == SWITCH_STATUS_SUCCESS && pop) {
1594 switch_event_t *event = (switch_event_t *) pop;
1595 switch_event_destroy(&event);
1596 }
1597
1598}
1599
1600void *SWITCH_THREAD_FUNC sofia_presence_event_thread_run(switch_thread_t *thread, void *obj)
1601{
1602 void *pop;
1603 int done = 0;
1604
1605 switch_mutex_lock(mod_sofia_globals.mutex);
1606 if (!EVENT_THREAD_RUNNING) {
1607 EVENT_THREAD_RUNNING++;
1608 mod_sofia_globals.threads++;
1609 } else {
1610 done = 1;
1611 }
1612 switch_mutex_unlock(mod_sofia_globals.mutex);
1613
1614 if (done) {
1615 return NULL((void*)0);
1616 }
1617
1618 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 1618, ((void*)0)
, SWITCH_LOG_CONSOLE, "Event Thread Started\n");
1619
1620 while (mod_sofia_globals.running == 1) {
1621 int count = 0;
1622
1623 if (switch_queue_pop(mod_sofia_globals.presence_queue, &pop) == SWITCH_STATUS_SUCCESS) {
1624 switch_event_t *event = (switch_event_t *) pop;
1625
1626 if (!pop) {
1627 break;
1628 }
1629
1630 if (mod_sofia_globals.presence_flush) {
1631 switch_mutex_lock(mod_sofia_globals.mutex);
1632 if (mod_sofia_globals.presence_flush) {
1633 do_flush();
1634 mod_sofia_globals.presence_flush = 0;
1635 }
1636 switch_mutex_unlock(mod_sofia_globals.mutex);
1637 }
1638
1639 switch(event->event_id) {
1640 case SWITCH_EVENT_MESSAGE_WAITING:
1641 actual_sofia_presence_mwi_event_handler(event);
1642 break;
1643 case SWITCH_EVENT_CONFERENCE_DATA:
1644 conference_data_event_handler(event);
1645 break;
1646 default:
1647 do {
1648 switch_event_t *ievent = event;
1649 event = actual_sofia_presence_event_handler(ievent);
1650 switch_event_destroy(&ievent);
1651 } while (event);
1652 break;
1653 }
1654
1655 switch_event_destroy(&event);
1656 count++;
1657 }
1658 }
1659
1660 do_flush();
1661
1662 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 1662, ((void*)0)
, SWITCH_LOG_CONSOLE, "Event Thread Ended\n");
1663
1664 switch_mutex_lock(mod_sofia_globals.mutex);
1665 mod_sofia_globals.threads--;
1666 EVENT_THREAD_RUNNING = EVENT_THREAD_STARTED = 0;
1667 switch_mutex_unlock(mod_sofia_globals.mutex);
1668
1669 return NULL((void*)0);
1670}
1671
1672void sofia_presence_event_thread_start(void)
1673{
1674 //switch_thread_t *thread;
1675 switch_threadattr_t *thd_attr = NULL((void*)0);
1676 int done = 0;
1677
1678 switch_mutex_lock(mod_sofia_globals.mutex);
1679 if (!EVENT_THREAD_STARTED) {
1680 EVENT_THREAD_STARTED++;
1681 } else {
1682 done = 1;
1683 }
1684 switch_mutex_unlock(mod_sofia_globals.mutex);
1685
1686 if (done) {
1687 return;
1688 }
1689
1690 switch_threadattr_create(&thd_attr, mod_sofia_globals.pool);
1691 //switch_threadattr_detach_set(thd_attr, 1);
1692 switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE240 * 1024);
1693 switch_threadattr_priority_set(thd_attr, SWITCH_PRI_IMPORTANT);
1694 switch_thread_create(&mod_sofia_globals.presence_thread, thd_attr, sofia_presence_event_thread_run, NULL((void*)0), mod_sofia_globals.pool);
1695}
1696
1697
1698void sofia_presence_event_handler(switch_event_t *event)
1699{
1700 switch_event_t *cloned_event;
1701
1702 if (!EVENT_THREAD_STARTED) {
1703 sofia_presence_event_thread_start();
1704 switch_yield(500000)switch_sleep(500000);;
1705 }
1706
1707 switch_event_dup(&cloned_event, event);
1708 switch_assert(cloned_event)((cloned_event) ? (void) (0) : __assert_fail ("cloned_event",
"sofia_presence.c", 1708, __PRETTY_FUNCTION__))
;
1709
1710 if (switch_queue_trypush(mod_sofia_globals.presence_queue, cloned_event) != SWITCH_STATUS_SUCCESS) {
1711 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 1711, ((void*)0)
, SWITCH_LOG_ERROR, "Presence queue overloaded.... Flushing queue\n");
1712 switch_mutex_lock(mod_sofia_globals.mutex);
1713 mod_sofia_globals.presence_flush = 1;
1714 switch_mutex_unlock(mod_sofia_globals.mutex);
1715 switch_event_destroy(&cloned_event);
1716 }
1717
1718
1719}
1720
1721
1722static int sofia_presence_sub_reg_callback(void *pArg, int argc, char **argv, char **columnNames)
1723{
1724 sofia_profile_t *profile = (sofia_profile_t *) pArg;
1725 char *user = argv[3];
1726 char *host = argv[2];
1727 switch_event_t *event;
1728 char *event_name = argv[5];
1729 char *expires = argv[10];
1730
1731
1732
1733 if (!strcasecmp(event_name, "message-summary")) {
1734
1735 if (switch_event_create(&event, SWITCH_EVENT_MESSAGE_QUERY)switch_event_create_subclass_detailed("sofia_presence.c", (const
char * )(const char *)__func__, 1735, &event, SWITCH_EVENT_MESSAGE_QUERY
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
1736 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Message-Account", "sip:%s@%s", user, host);
1737 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "VM-Sofia-Profile", profile->name);
1738 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "VM-sub-call-id", argv[7]);
1739
1740 if (mod_sofia_globals.debug_presence > 0) {
1741 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 1741, ((void*)0)
, SWITCH_LOG_ERROR, "Create MESSAGE QUERY EVENT...\n");
1742 DUMP_EVENT(event){char *event_str;switch_event_serialize(event, &event_str
, SWITCH_FALSE);switch_log_printf(SWITCH_CHANNEL_ID_LOG, "sofia_presence.c"
, (const char *)__func__, 1742, ((void*)0), SWITCH_LOG_CRIT, "DUMP\n%s\n"
, event_str);free(event_str);}
;
1743 }
1744
1745
1746 sofia_event_fire(profile, &event);
1747 }
1748 return 0;
1749 }
1750
1751 if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_PROBE)switch_event_create_subclass_detailed("sofia_presence.c", (const
char * )(const char *)__func__, 1751, &event, SWITCH_EVENT_PRESENCE_PROBE
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
1752 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", SOFIA_CHAT_PROTO"sip");
1753 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "login", profile->url);
1754 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "sip_profile", profile->name);
1755 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s@%s", user, host);
1756 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "event_type", "presence");
1757 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "event_subtype", "probe");
1758 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto-specific-event-name", event_name);
1759 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "expires", expires);
1760 sofia_event_fire(profile, &event);
1761 }
1762
1763 return 0;
1764}
1765
1766static int sofia_presence_resub_callback(void *pArg, int argc, char **argv, char **columnNames)
1767{
1768 struct resub_helper *h = (struct resub_helper *) pArg;
1769 sofia_profile_t *profile = h->profile;
1770 char *user = argv[0];
1771 char *host = argv[1];
1772 char *status = argv[2];
1773 char *rpid = argv[3];
1774 char *proto = argv[4];
1775 char *call_id = NULL((void*)0);
1776 char *presence_id = NULL((void*)0);
1777 char *to_user = NULL((void*)0);
1778 char *uuid = NULL((void*)0);
1779 char *state = NULL((void*)0);
1780 char *direction = NULL((void*)0);
1781 switch_event_t *event;
1782 char to_buf[128] = "";
1783 switch_event_header_t *hp;
1784 char *free_me = NULL((void*)0);
1785 int do_event = 1, i;
1786
1787
1788 if (mod_sofia_globals.debug_presence > 1) {
1789 for (i = 0; i < argc; i++) {
1790 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 1790, ((void*)0)
,SWITCH_LOG_WARNING, "sofia_presence_resub_callback: %d [%s]=[%s]\n", i, columnNames[i], argv[i]);
1791 }
1792 }
1793
1794 if (argc > 5) {
1795 uuid = argv[5];
1796 state = switch_str_nil(argv[6])(argv[6] ? argv[6] : "");
1797 direction = switch_str_nil(argv[7])(argv[7] ? argv[7] : "");
1798 if (argc > 8) {
1799 switch_set_string(to_buf, argv[8])switch_copy_string(to_buf, argv[8], sizeof(to_buf));
1800 switch_url_decode(to_buf);
1801 to_user = to_buf;
1802 }
1803 if (argc > 10 && !zstr(argv[10])_zstr(argv[10]) && !zstr(argv[11])_zstr(argv[11])) {
1804 status = argv[10];
1805 rpid = argv[11];
1806 }
1807
1808 if (argc > 12 && !zstr(argv[12])_zstr(argv[12]) && strchr(argv[12], '@')(__extension__ (__builtin_constant_p ('@') && !__builtin_constant_p
(argv[12]) && ('@') == '\0' ? (char *) __rawmemchr (
argv[12], '@') : __builtin_strchr (argv[12], '@')))
) {
1809 char *p;
1810
1811 presence_id = argv[12];
1812 free_me = strdup(presence_id)(__extension__ (__builtin_constant_p (presence_id) &&
((size_t)(const void *)((presence_id) + 1) - (size_t)(const void
*)(presence_id) == 1) ? (((const char *) (presence_id))[0] ==
'\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len
= strlen (presence_id) + 1; char *__retval = (char *) malloc
(__len); if (__retval != ((void*)0)) __retval = (char *) memcpy
(__retval, presence_id, __len); __retval; })) : __strdup (presence_id
)))
;
1813 if ((p = strchr(free_me, '@')(__extension__ (__builtin_constant_p ('@') && !__builtin_constant_p
(free_me) && ('@') == '\0' ? (char *) __rawmemchr (free_me
, '@') : __builtin_strchr (free_me, '@')))
)) *p = '\0';
1814 user = free_me;
1815 }
1816
1817 if (argc > 16) {
1818 call_id = argv[16];
1819 }
1820
1821 }
1822
1823 if (!zstr(uuid)_zstr(uuid) && !switch_ivr_uuid_exists(uuid)) {
1824 if (mod_sofia_globals.debug_presence > 0) {
1825 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 1825, ((void*)0)
, SWITCH_LOG_NOTICE, "%s SKIPPING NOT FOUND UUID %s\n", profile->name, uuid);
1826 }
1827 do_event = 0;
1828 }
1829
1830 if (zstr(proto)_zstr(proto)) {
1831 proto = NULL((void*)0);
1832 }
1833
1834 if (mod_sofia_globals.debug_presence > 0) {
1835 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 1835, ((void*)0)
, SWITCH_LOG_NOTICE, "%s PRESENCE_PROBE %s@%s\n", profile->name, user, host);
1836 }
1837
1838 if (do_event && switch_event_create(&event, SWITCH_EVENT_PRESENCE_IN)switch_event_create_subclass_detailed("sofia_presence.c", (const
char * )(const char *)__func__, 1838, &event, SWITCH_EVENT_PRESENCE_IN
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
1839 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", proto ? proto : SOFIA_CHAT_PROTO"sip");
1840 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "login", profile->url);
1841 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "sip_profile", profile->name);
1842
1843 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s@%s", user, host);
1844
1845 if (h->noreg) {
1846 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Force-Direction", "inbound");
1847 }
1848
1849 if (!zstr(call_id)_zstr(call_id)) {
1850 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call-id", call_id);
1851 }
1852
1853 //switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "resub", "true");
1854 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "status", status);
1855 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "rpid", rpid);
1856 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "event_type", "presence");
1857 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alt_event_type", "dialog");
1858 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "event_count", "%d", 0);
1859
1860 if (!zstr(to_user)_zstr(to_user)) {
1861 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "to-user", to_user);
1862 }
1863
1864 if (zstr(state)_zstr(state)) {
1865 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "channel-state", "CS_HANGUP");
1866 //switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "answer-state", "resubscribe");
1867 } else {
1868 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "channel-state", "CS_ROUTING");
1869 if (uuid) {
1870 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "unique-id", uuid);
1871 }
1872 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "answer-state", state);
1873 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "astate", state);
1874 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "presence-call-direction", direction);
1875 }
1876
1877 if (h->event) {
1878 for (hp = h->event->headers; hp; hp = hp->next) {
1879 if (!strncasecmp(hp->name, "fwd-", 4)) {
1880 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, hp->name + 4, hp->value);
1881 }
1882 }
1883 }
1884
1885 sofia_event_fire(profile, &event);
1886 }
1887
1888 switch_safe_free(free_me)if (free_me) {free(free_me);free_me=((void*)0);};
1889
1890
1891 h->rowcount++;
1892
1893
1894 return 0;
1895}
1896
1897char *get_display_name_from_contact(const char *in, char* dst)
1898{
1899 // name-addr = [ display-name ] LAQUOT addr-spec RAQUOT
1900 // display-name = *(token LWS)/ quoted-string
1901 // return whatever comes before the left angle bracket, stripped of whitespace and quotes
1902 char *p;
1903 char *buf;
1904
1905 strcpy(dst, "");
1906 if (strchr(in, '<')(__extension__ (__builtin_constant_p ('<') && !__builtin_constant_p
(in) && ('<') == '\0' ? (char *) __rawmemchr (in,
'<') : __builtin_strchr (in, '<')))
&& strchr(in, '>')(__extension__ (__builtin_constant_p ('>') && !__builtin_constant_p
(in) && ('>') == '\0' ? (char *) __rawmemchr (in,
'>') : __builtin_strchr (in, '>')))
) {
1907 buf = strdup(in)(__extension__ (__builtin_constant_p (in) && ((size_t
)(const void *)((in) + 1) - (size_t)(const void *)(in) == 1) ?
(((const char *) (in))[0] == '\0' ? (char *) calloc ((size_t
) 1, (size_t) 1) : ({ size_t __len = strlen (in) + 1; char *__retval
= (char *) malloc (__len); if (__retval != ((void*)0)) __retval
= (char *) memcpy (__retval, in, __len); __retval; })) : __strdup
(in)))
;
1908 p = strchr(buf, '<')(__extension__ (__builtin_constant_p ('<') && !__builtin_constant_p
(buf) && ('<') == '\0' ? (char *) __rawmemchr (buf
, '<') : __builtin_strchr (buf, '<')))
;
1909 *p = '\0';
1910 if (!zstr(buf)_zstr(buf)) {
1911 p = switch_strip_whitespace(buf);
1912 if (p) {
1913 if (*p == '"') {
1914 if (end_of(p+1)*(*p+1 == '\0' ? p+1 : p+1 + strlen(p+1) - 1) == '"') {
1915 char *q = strdup(p + 1)(__extension__ (__builtin_constant_p (p + 1) && ((size_t
)(const void *)((p + 1) + 1) - (size_t)(const void *)(p + 1) ==
1) ? (((const char *) (p + 1))[0] == '\0' ? (char *) calloc (
(size_t) 1, (size_t) 1) : ({ size_t __len = strlen (p + 1) + 1
; char *__retval = (char *) malloc (__len); if (__retval != (
(void*)0)) __retval = (char *) memcpy (__retval, p + 1, __len
); __retval; })) : __strdup (p + 1)))
;
1916 end_of(q)*(*q == '\0' ? q : q + strlen(q) - 1) = '\0';
1917 strcpy(dst, q);
1918 switch_safe_free(q)if (q) {free(q);q=((void*)0);};
1919 }
1920 } else {
1921 strcpy(dst, p);
1922 }
1923 switch_safe_free(p)if (p) {free(p);p=((void*)0);};
1924 }
1925 }
1926 switch_safe_free(buf)if (buf) {free(buf);buf=((void*)0);};
1927 }
1928 return dst;
1929}
1930
1931static int sofia_dialog_probe_callback(void *pArg, int argc, char **argv, char **columnNames)
1932{
1933 struct rfc4235_helper *h = (struct rfc4235_helper *) pArg;
1934
1935 char *proto = argv[0];
1936 char *user = argv[1];
1937 char *host = argv[2];
1938 char *uuid = argv[3];
1939 char *call_id = argv[4];
1940 char *state = argv[5];
1941 char *direction = argv[6];
1942 char *to_user = argv[7];
1943 char *to_host = argv[8];
1944 char *from_user = argv[9];
1945 // char *from_host = argv[10];
1946 char *contact = switch_str_nil(argv[11])(argv[11] ? argv[11] : "");
1947 char *contact_user = switch_str_nil(argv[12])(argv[12] ? argv[12] : "");
1948 char *contact_host = switch_str_nil(argv[13])(argv[13] ? argv[13] : "");
1949 char *to_tag = switch_str_nil(argv[14])(argv[14] ? argv[14] : "");
1950 char *from_tag = switch_str_nil(argv[15])(argv[15] ? argv[15] : "");
1951 char *orig_proto = switch_str_nil(argv[16])(argv[16] ? argv[16] : "");
1952
1953 const char *event_status = "";
1954 char *data = NULL((void*)0), *tmp;
1955 char key[256] = "";
1956 char *local_user;
1957 char *local_host;
1958 char *remote_user;
1959 char *remote_host;
1960 char *remote_uri;
1961 char *local_user_param = "";
1962 char remote_display_buf[512];
1963 char *buf_to_free = NULL((void*)0);
1964 int bInternal = 0;
1965 int i;
1966 int skip_proto = 0;
1967
1968 if (mod_sofia_globals.debug_presence > 1) {
1969 for (i = 0; i < argc; i++) {
1970 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 1970, ((void*)0)
,SWITCH_LOG_WARNING, "sofia_dialog_probe_callback: %d [%s]=[%s]\n", i, columnNames[i], argv[i]);
1971 }
1972 }
1973
1974 if (zstr(to_user)_zstr(to_user) || zstr(contact_user)_zstr(contact_user)) {
1975 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 1975, ((void*)0)
, SWITCH_LOG_WARNING, "sofia_dialog_probe_callback: not enough info to generate a dialog entry\n");
1976 return 0;
1977 }
1978
1979 // Usually we report the dialogs FROM the probed user. The exception is when the monitored endpoint is internal,
1980 // and its presence_id is set in the dialplan. Reverse the direction if this is not a registered entity.
1981 if (!strcmp(direction, "inbound")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(direction) && __builtin_constant_p ("inbound") &&
(__s1_len = __builtin_strlen (direction), __s2_len = __builtin_strlen
("inbound"), (!((size_t)(const void *)((direction) + 1) - (size_t
)(const void *)(direction) == 1) || __s1_len >= 4) &&
(!((size_t)(const void *)(("inbound") + 1) - (size_t)(const void
*)("inbound") == 1) || __s2_len >= 4)) ? __builtin_strcmp
(direction, "inbound") : (__builtin_constant_p (direction) &&
((size_t)(const void *)((direction) + 1) - (size_t)(const void
*)(direction) == 1) && (__s1_len = __builtin_strlen (
direction), __s1_len < 4) ? (__builtin_constant_p ("inbound"
) && ((size_t)(const void *)(("inbound") + 1) - (size_t
)(const void *)("inbound") == 1) ? __builtin_strcmp (direction
, "inbound") : (__extension__ ({ const unsigned char *__s2 = (
const unsigned char *) (const char *) ("inbound"); int __result
= (((const unsigned char *) (const char *) (direction))[0] -
__s2[0]); if (__s1_len > 0 && __result == 0) { __result
= (((const unsigned char *) (const char *) (direction))[1] -
__s2[1]); if (__s1_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) (direction))[2] -
__s2[2]); if (__s1_len > 2 && __result == 0) __result
= (((const unsigned char *) (const char *) (direction))[3] -
__s2[3]); } } __result; }))) : (__builtin_constant_p ("inbound"
) && ((size_t)(const void *)(("inbound") + 1) - (size_t
)(const void *)("inbound") == 1) && (__s2_len = __builtin_strlen
("inbound"), __s2_len < 4) ? (__builtin_constant_p (direction
) && ((size_t)(const void *)((direction) + 1) - (size_t
)(const void *)(direction) == 1) ? __builtin_strcmp (direction
, "inbound") : (- (__extension__ ({ const unsigned char *__s2
= (const unsigned char *) (const char *) (direction); int __result
= (((const unsigned char *) (const char *) ("inbound"))[0] -
__s2[0]); if (__s2_len > 0 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("inbound"))[1] -
__s2[1]); if (__s2_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("inbound"))[2] -
__s2[2]); if (__s2_len > 2 && __result == 0) __result
= (((const unsigned char *) (const char *) ("inbound"))[3] -
__s2[3]); } } __result; })))) : __builtin_strcmp (direction,
"inbound")))); })
&& strcmp(user, from_user)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(user) && __builtin_constant_p (from_user) &&
(__s1_len = __builtin_strlen (user), __s2_len = __builtin_strlen
(from_user), (!((size_t)(const void *)((user) + 1) - (size_t
)(const void *)(user) == 1) || __s1_len >= 4) && (
!((size_t)(const void *)((from_user) + 1) - (size_t)(const void
*)(from_user) == 1) || __s2_len >= 4)) ? __builtin_strcmp
(user, from_user) : (__builtin_constant_p (user) && (
(size_t)(const void *)((user) + 1) - (size_t)(const void *)(user
) == 1) && (__s1_len = __builtin_strlen (user), __s1_len
< 4) ? (__builtin_constant_p (from_user) && ((size_t
)(const void *)((from_user) + 1) - (size_t)(const void *)(from_user
) == 1) ? __builtin_strcmp (user, from_user) : (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) (from_user); int __result = (((const unsigned char *
) (const char *) (user))[0] - __s2[0]); if (__s1_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (user))[1] - __s2[1]); if (__s1_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (user))[2] - __s2[2]); if (__s1_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (user))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
(from_user) && ((size_t)(const void *)((from_user) +
1) - (size_t)(const void *)(from_user) == 1) && (__s2_len
= __builtin_strlen (from_user), __s2_len < 4) ? (__builtin_constant_p
(user) && ((size_t)(const void *)((user) + 1) - (size_t
)(const void *)(user) == 1) ? __builtin_strcmp (user, from_user
) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (user); int __result = (((const unsigned
char *) (const char *) (from_user))[0] - __s2[0]); if (__s2_len
> 0 && __result == 0) { __result = (((const unsigned
char *) (const char *) (from_user))[1] - __s2[1]); if (__s2_len
> 1 && __result == 0) { __result = (((const unsigned
char *) (const char *) (from_user))[2] - __s2[2]); if (__s2_len
> 2 && __result == 0) __result = (((const unsigned
char *) (const char *) (from_user))[3] - __s2[3]); } } __result
; })))) : __builtin_strcmp (user, from_user)))); })
) {
1982 // If inbound and the entity is not the caller (i.e. internal to FS), then the direction is reversed
1983 // because it is not going through the B2BUA
1984 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 1984, ((void*)0)
, SWITCH_LOG_DEBUG, "sofia_dialog_probe_callback: endpt is internal\n");
1985 direction = !strcasecmp(direction, "outbound") ? "inbound" : "outbound";
1986 bInternal = 1;
1987 }
1988
1989 if (!strcasecmp(direction, "outbound")) {
1990 direction = "recipient";
1991 }
1992 else {
1993 direction = "initiator";
1994 }
1995
1996 if (!zstr(orig_proto)_zstr(orig_proto) && !strcmp(orig_proto, SOFIA_CHAT_PROTO)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(orig_proto) && __builtin_constant_p ("sip") &&
(__s1_len = __builtin_strlen (orig_proto), __s2_len = __builtin_strlen
("sip"), (!((size_t)(const void *)((orig_proto) + 1) - (size_t
)(const void *)(orig_proto) == 1) || __s1_len >= 4) &&
(!((size_t)(const void *)(("sip") + 1) - (size_t)(const void
*)("sip") == 1) || __s2_len >= 4)) ? __builtin_strcmp (orig_proto
, "sip") : (__builtin_constant_p (orig_proto) && ((size_t
)(const void *)((orig_proto) + 1) - (size_t)(const void *)(orig_proto
) == 1) && (__s1_len = __builtin_strlen (orig_proto),
__s1_len < 4) ? (__builtin_constant_p ("sip") && (
(size_t)(const void *)(("sip") + 1) - (size_t)(const void *)(
"sip") == 1) ? __builtin_strcmp (orig_proto, "sip") : (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) ("sip"); int __result = (((const unsigned char *) (const
char *) (orig_proto))[0] - __s2[0]); if (__s1_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (orig_proto))[1] - __s2[1]); if (__s1_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (orig_proto))[2] - __s2[2]); if (__s1_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (orig_proto))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
("sip") && ((size_t)(const void *)(("sip") + 1) - (size_t
)(const void *)("sip") == 1) && (__s2_len = __builtin_strlen
("sip"), __s2_len < 4) ? (__builtin_constant_p (orig_proto
) && ((size_t)(const void *)((orig_proto) + 1) - (size_t
)(const void *)(orig_proto) == 1) ? __builtin_strcmp (orig_proto
, "sip") : (- (__extension__ ({ const unsigned char *__s2 = (
const unsigned char *) (const char *) (orig_proto); int __result
= (((const unsigned char *) (const char *) ("sip"))[0] - __s2
[0]); if (__s2_len > 0 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("sip"))[1] - __s2
[1]); if (__s2_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("sip"))[2] - __s2
[2]); if (__s2_len > 2 && __result == 0) __result =
(((const unsigned char *) (const char *) ("sip"))[3] - __s2[
3]); } } __result; })))) : __builtin_strcmp (orig_proto, "sip"
)))); })
) {
1997 skip_proto = 1;
1998 }
1999
2000 local_host = to_host;
2001 if (proto && !strcasecmp(proto, "queue")) {
2002 local_user = to_user;
2003 local_user_param = switch_mprintf(";proto=%s", proto);
2004 event_status = "hold";
2005 if (skip_proto) {
2006 buf_to_free = switch_mprintf("sip:%s", to_user);
2007 } else {
2008 buf_to_free = switch_mprintf("sip:queue+%s", to_user);
2009 }
2010 remote_uri = buf_to_free;
2011 strcpy(remote_display_buf, "queue");
2012 remote_user = to_user;
2013 remote_host = local_host;
2014 }
2015 else if (proto && !strcasecmp(proto, "park")) {
2016 local_user = to_user;
2017 local_user_param = switch_mprintf(";proto=%s", proto);
2018 event_status = "hold";
2019 if (skip_proto) {
2020 buf_to_free = switch_mprintf("sip:%s", to_user);
2021 } else {
2022 buf_to_free = switch_mprintf("sip:park+%s", to_user);
2023 }
2024 remote_uri = buf_to_free;
2025 strcpy(remote_display_buf, "park");
2026 remote_user = to_user;
2027 remote_host = local_host;
2028 }
2029 else if (proto && !strcasecmp(proto, "pickup")) {
2030 local_user = to_user;
2031 local_user_param = switch_mprintf(";proto=%s", proto);
2032 event_status = "hold";
2033 if (skip_proto) {
2034 buf_to_free = switch_mprintf("sip:%s", to_user);
2035 } else {
2036 buf_to_free = switch_mprintf("sip:pickup+%s", to_user);
2037 }
2038 remote_uri = buf_to_free;
2039 strcpy(remote_display_buf, "pickup");
2040 remote_user = to_user;
2041 remote_host = local_host;
2042 }
2043 else if (proto && !strcasecmp(proto, "conf")) {
2044 local_user = to_user;
2045 local_user_param = switch_mprintf(";proto=%s", proto);
2046 if (skip_proto) {
2047 buf_to_free = switch_mprintf("sip:%s@%s", to_user, host);
2048 } else {
2049 buf_to_free = switch_mprintf("sip:conf+%s@%s", to_user, host);
2050 }
2051 remote_uri = buf_to_free;
2052 strcpy(remote_display_buf, "conference");
2053 remote_user = to_user;
2054 remote_host = local_host;
2055 }
2056 else if (bInternal) {
2057 local_user = to_user;
2058 get_display_name_from_contact(contact, remote_display_buf);
2059 buf_to_free = sofia_glue_strip_uri(contact);
2060 remote_uri = buf_to_free;
2061 remote_user = contact_user;
2062 remote_host = contact_host;
2063 } else {
2064 local_user = from_user;
2065 buf_to_free = switch_mprintf("**%s@%s", from_user, local_host);
2066 remote_uri = buf_to_free;
2067 strcpy(remote_display_buf, to_user);
2068 remote_user = to_user;
2069 remote_host = local_host;
2070 }
2071
2072 switch_snprintf(key, sizeof(key), "%s%s", user, host);
2073 data = switch_core_hash_find(h->hash, key);
2074 if (!data) {
2075 data = "";
2076 }
2077 tmp = switch_core_sprintf(h->pool, "%s"
2078 "<dialog id=\"%s\" call-id=\"%s\" local-tag=\"%s\" remote-tag=\"%s\" direction=\"%s\">\n"
2079 " <state>%s</state>\n"
2080 " <local>\n"
2081 " <identity display=\"%s\">sip:%s@%s%s</identity>\n"
2082 " <target uri=\"sip:%s@%s\">\n"
2083 " <param pname=\"+sip.rendering\" pvalue=\"%s\"/>\n"
2084 " </target>\n"
2085 " </local>\n"
2086 " <remote>\n"
2087 " <identity display=\"%s\">sip:%s@%s</identity>\n"
2088 " <target uri=\"%s\"/>\n"
2089 " </remote>\n"
2090 "</dialog>\n",
2091 data,
2092 uuid, call_id, to_tag, from_tag, direction,
2093 state,
2094 local_user, local_user, local_host, local_user_param,
2095 local_user, local_host,
2096 !strcasecmp(event_status, "hold") ? "no" : "yes",
2097 remote_display_buf, remote_user, remote_host,
2098 remote_uri
2099 );
2100 switch_core_hash_insert(h->hash, key, tmp)switch_core_hash_insert_destructor(h->hash, key, tmp, ((void
*)0))
;
2101 switch_safe_free(buf_to_free)if (buf_to_free) {free(buf_to_free);buf_to_free=((void*)0);};
2102
2103 h->rowcount++;
2104
2105 return 0;
2106}
2107
2108#define SOFIA_PRESENCE_COLLISION_DELTA50 50
2109#define SOFIA_PRESENCE_ROLLOVER_YEAR(86400 * 365 * 50) (86400 * 365 * SOFIA_PRESENCE_COLLISION_DELTA50)
2110static uint32_t check_presence_epoch(void)
2111{
2112 struct tm tm = {0};
2113 time_t now = switch_epoch_time_now(NULL((void*)0));
2114 uint32_t callsequence = (now - mod_sofia_globals.presence_epoch) * SOFIA_PRESENCE_COLLISION_DELTA50;
2115
2116 if (!mod_sofia_globals.presence_year || callsequence >= SOFIA_PRESENCE_ROLLOVER_YEAR(86400 * 365 * 50)) {
2117 switch_mutex_lock(mod_sofia_globals.mutex);
2118 tm = *(localtime(&now));
2119
2120 if (tm.tm_year != mod_sofia_globals.presence_year) {
2121 mod_sofia_globals.presence_epoch = (uint32_t)now - (tm.tm_yday * 86400) - (tm.tm_hour * 60 * 60) - (tm.tm_min * 60) - tm.tm_sec;
2122 mod_sofia_globals.presence_year = tm.tm_year;
2123 callsequence = ((uint32_t)now - mod_sofia_globals.presence_epoch) * SOFIA_PRESENCE_COLLISION_DELTA50;
2124 }
2125
2126 switch_mutex_unlock(mod_sofia_globals.mutex);
2127 }
2128
2129 return callsequence;
2130}
2131
2132uint32_t sofia_presence_get_cseq(sofia_profile_t *profile)
2133{
2134 uint32_t callsequence;
2135 int diff = 0;
2136
2137 switch_mutex_lock(profile->ireg_mutex);
2138
2139 callsequence = check_presence_epoch();
2140
2141 if (profile->last_cseq) {
2142 diff = callsequence - profile->last_cseq;
2143 if (diff <= 0 && diff > -100000) {
2144 callsequence = ++profile->last_cseq;
2145 }
2146 }
2147
2148 profile->last_cseq = callsequence;
2149
2150 switch_mutex_unlock(profile->ireg_mutex);
2151
2152 return callsequence;
2153
2154}
2155
2156
2157#define send_presence_notify(_a,_b,_c,_d,_e,_f,_g,_h,_i,_j,_k,_l)_send_presence_notify(_a,_b,_c,_d,_e,_f,_g,_h,_i,_j,_k,_l,"sofia_presence.c"
, (const char *)__func__, 2157)
\
2158_send_presence_notify(_a,_b,_c,_d,_e,_f,_g,_h,_i,_j,_k,_l,__FILE__"sofia_presence.c", __SWITCH_FUNC__(const char *)__func__, __LINE__2158)
2159
2160static void _send_presence_notify(sofia_profile_t *profile,
2161 const char *full_to,
2162 const char *full_from,
2163 const char *o_contact,
2164 const char *expires,
2165 const char *call_id,
2166 const char *event,
2167 const char *remote_ip,
2168 const char *remote_port,
2169 const char *ct,
2170 const char *pl,
2171 const char *call_info,
2172 const char *file, const char *func, int line
2173 )
2174{
2175 char sstr[128] = "";
2176 nua_handle_t *nh;
2177 int exptime = 0;
2178 char expires_str[10] = "";
2179 sip_cseq_t *cseq = NULL((void*)0);
2180 uint32_t callsequence;
2181 uint32_t now = (uint32_t) switch_epoch_time_now(NULL((void*)0));
2182 char *our_contact = profile->url, *our_contact_dup = NULL((void*)0);
2183
2184 sofia_destination_t *dst = NULL((void*)0);
2185 char *contact_str, *contact, *user_via = NULL((void*)0), *send_contact = NULL((void*)0);
2186 char *route_uri = NULL((void*)0), *o_contact_dup = NULL((void*)0), *tmp, *to_uri, *dcs = NULL((void*)0);
2187 const char *tp;
2188 char *cparams = NULL((void*)0);
2189 char *path = NULL((void*)0);
2190
2191 if (zstr(full_to)_zstr(full_to) || zstr(full_from)_zstr(full_from) || zstr(o_contact)_zstr(o_contact)) {
2192 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 2192, ((void*)0)
, SWITCH_LOG_WARNING, "MISSING DATA TO SEND NOTIFY.\n");
2193 return;
2194 }
2195
2196 if ((cparams = strstr(o_contact, ";_;"))) {
2197 cparams += 3;
2198 }
2199
2200 if (!switch_stristr("fs_nat=yes", o_contact)) {
2201 path = sofia_glue_get_path_from_contact((char *) o_contact);
2202 }
2203
2204 tmp = (char *)o_contact;
2205 o_contact_dup = sofia_glue_get_url_from_contact(tmp, 1);
2206
2207
2208 if ((tp = switch_stristr("transport=", o_contact_dup))) {
2209 tp += 10;
2210 }
2211
2212 if (zstr(tp)_zstr(tp)) {
2213 tp = "udp";
2214 }
2215
2216 if (!switch_stristr("transport=", our_contact)) {
2217 our_contact_dup = switch_mprintf("<%s;transport=%s>", our_contact, tp);
2218 our_contact = our_contact_dup;
2219 }
2220
2221
2222 if (!zstr(remote_ip)_zstr(remote_ip) && sofia_glue_check_nat(profile, remote_ip)) {
2223 sofia_transport_t transport = sofia_glue_str2transport(tp);
2224
2225 switch (transport) {
2226 case SOFIA_TRANSPORT_TCP:
2227 contact_str = profile->tcp_public_contact;
2228 break;
2229 case SOFIA_TRANSPORT_TCP_TLS:
2230 contact_str = sofia_test_pflag(profile, PFLAG_TLS)((profile)->pflags[PFLAG_TLS] ? 1 : 0) ?
2231 profile->tls_public_contact : profile->tcp_public_contact;
2232 break;
2233 default:
2234 contact_str = profile->public_url;
2235 break;
2236 }
2237 user_via = sofia_glue_create_external_via(NULL((void*)0), profile, transport);
2238 } else {
2239 sofia_transport_t transport = sofia_glue_str2transport(tp);
2240 switch (transport) {
2241 case SOFIA_TRANSPORT_TCP:
2242 contact_str = profile->tcp_contact;
2243 break;
2244 case SOFIA_TRANSPORT_TCP_TLS:
2245 contact_str = sofia_test_pflag(profile, PFLAG_TLS)((profile)->pflags[PFLAG_TLS] ? 1 : 0) ?
2246 profile->tls_contact : profile->tcp_contact;
2247 break;
2248 default:
2249 contact_str = profile->url;
2250 break;
2251 }
2252 }
2253
2254
2255 if ((to_uri = sofia_glue_get_url_from_contact((char *)full_to, 1))) {
2256 char *p;
2257
2258 if ((p = strstr(to_uri, "sip:"))) {
2259 char *q;
2260
2261 p += 4;
2262 if ((q = strchr(p, '@')(__extension__ (__builtin_constant_p ('@') && !__builtin_constant_p
(p) && ('@') == '\0' ? (char *) __rawmemchr (p, '@')
: __builtin_strchr (p, '@')))
)) {
2263 *q++ = '\0';
2264
2265 if ((dcs = switch_string_replace(contact_str, "mod_sofia", p))) {
2266 contact_str = dcs;
2267 }
2268
2269 }
2270 }
2271
2272 free(to_uri);
2273 }
2274
2275 dst = sofia_glue_get_destination((char *) o_contact);
2276 switch_assert(dst)((dst) ? (void) (0) : __assert_fail ("dst", "sofia_presence.c"
, 2276, __PRETTY_FUNCTION__))
;
2277
2278 if (!zstr(dst->contact)_zstr(dst->contact)) {
2279 contact = sofia_glue_get_url_from_contact(dst->contact, 1);
2280 } else {
2281 contact = strdup(o_contact)(__extension__ (__builtin_constant_p (o_contact) && (
(size_t)(const void *)((o_contact) + 1) - (size_t)(const void
*)(o_contact) == 1) ? (((const char *) (o_contact))[0] == '\0'
? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len
= strlen (o_contact) + 1; char *__retval = (char *) malloc (
__len); if (__retval != ((void*)0)) __retval = (char *) memcpy
(__retval, o_contact, __len); __retval; })) : __strdup (o_contact
)))
;
2282 }
2283
2284 if (dst->route_uri) {
2285 route_uri = sofia_glue_strip_uri(dst->route_uri);
2286 }
2287
2288 if (expires) {
2289 long ltmp = atol(expires);
2290
2291 if (ltmp > 0) {
2292 exptime = (ltmp - now);
2293 } else {
2294 exptime = 0;
2295 }
2296 }
2297
2298 if (exptime <= 0) {
2299 switch_snprintf(sstr, sizeof(sstr), "terminated;reason=noresource");
2300 } else {
2301 switch_snprintf(sstr, sizeof(sstr), "active;expires=%u", (unsigned) exptime);
2302 }
2303
2304 if (mod_sofia_globals.debug_presence > 1 || mod_sofia_globals.debug_sla > 1) {
2305 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 2305, ((void*)0)
, SWITCH_LOG_ERROR, "SEND PRES NOTIFY:\n"
2306 "file[%s]\nfunc[%s]\nline[%d]\n"
2307 "profile[%s]\nvia[%s]\nip[%s]\nport[%s]\nroute[%s]\ncontact[%s]\nto[%s]\nfrom[%s]\nurl[%s]\ncall_id[%s]\nexpires_str[%s]\n"
2308 "event[%s]\nct[%s]\npl[%s]\ncall_info[%s]\nexptime[%ld]\n",
2309 file, func, line,
2310 profile->name,
2311 switch_str_nil(user_via)(user_via ? user_via : ""),
2312 remote_ip,
2313 remote_port,
2314 route_uri,
2315 o_contact,
2316 full_to,
2317 full_from,
2318 contact,
2319 call_id,
2320 expires_str,
2321 event,
2322 switch_str_nil(ct)(ct ? ct : ""),
2323 switch_str_nil(pl)(pl ? pl : ""),
2324 switch_str_nil(call_info)(call_info ? call_info : ""),
2325 (long)exptime
2326 );
2327 }
2328
2329
2330 callsequence = sofia_presence_get_cseq(profile);
2331
2332 if (cparams) {
2333 send_contact = switch_mprintf("%s;%s", contact_str, cparams);
2334 contact_str = send_contact;
2335 }
2336
2337 nh = nua_handle(profile->nua, NULL((void*)0), NUTAG_URL(contact)nutag_url, urltag_url_v(contact), SIPTAG_CONTACT_STR(contact_str)siptag_contact_str, tag_str_v(contact_str), TAG_END()(tag_type_t)0, (tag_value_t)0);
2338 cseq = sip_cseq_create(nh->nh_home, callsequence, SIP_METHOD_NOTIFYsip_method_notify, "NOTIFY");
2339 nua_handle_bind(nh, &mod_sofia_globals.destroy_private);
2340
2341
2342 nua_notify(nh,
2343 NUTAG_NEWSUB(1)nutag_newsub, tag_bool_v(1),
2344 TAG_IF(route_uri, NUTAG_PROXY(route_uri))!(route_uri) ? tag_skip : ntatag_default_proxy, urltag_url_v(
(route_uri))
,
2345 TAG_IF(dst->route, SIPTAG_ROUTE_STR(dst->route))!(dst->route) ? tag_skip : siptag_route_str, tag_str_v(dst
->route)
,
2346 TAG_IF(user_via, SIPTAG_VIA_STR(user_via))!(user_via) ? tag_skip : siptag_via_str, tag_str_v(user_via),
2347 TAG_IF(path, SIPTAG_RECORD_ROUTE_STR(path))!(path) ? tag_skip : siptag_record_route_str, tag_str_v(path),
2348
2349 SIPTAG_FROM_STR(full_to)siptag_from_str, tag_str_v(full_to),
2350 SIPTAG_TO_STR(full_from)siptag_to_str, tag_str_v(full_from),
2351
2352 SIPTAG_CALL_ID_STR(call_id)siptag_call_id_str, tag_str_v(call_id),
2353 TAG_IF(*expires_str, SIPTAG_EXPIRES_STR(expires_str))!(*expires_str) ? tag_skip : siptag_expires_str, tag_str_v(expires_str
)
,
2354 SIPTAG_SUBSCRIPTION_STATE_STR(sstr)siptag_subscription_state_str, tag_str_v(sstr),
2355 SIPTAG_EVENT_STR(event)siptag_event_str, tag_str_v(event),
2356 TAG_IF(!zstr(ct), SIPTAG_CONTENT_TYPE_STR(ct))!(!_zstr(ct)) ? tag_skip : siptag_content_type_str, tag_str_v
(ct)
,
2357 TAG_IF(!zstr(pl), SIPTAG_PAYLOAD_STR(pl))!(!_zstr(pl)) ? tag_skip : siptag_payload_str, tag_str_v(pl),
2358 TAG_IF(!zstr(call_info), SIPTAG_CALL_INFO_STR(call_info))!(!_zstr(call_info)) ? tag_skip : siptag_call_info_str, tag_str_v
(call_info)
,
2359 TAG_IF(!exptime, SIPTAG_EXPIRES_STR("0"))!(!exptime) ? tag_skip : siptag_expires_str, tag_str_v("0"),
2360 SIPTAG_CSEQ(cseq)siptag_cseq, siptag_cseq_v(cseq),
2361 TAG_END()(tag_type_t)0, (tag_value_t)0);
2362
2363
2364 switch_safe_free(route_uri)if (route_uri) {free(route_uri);route_uri=((void*)0);};
2365 switch_safe_free(dcs)if (dcs) {free(dcs);dcs=((void*)0);};
2366 switch_safe_free(contact)if (contact) {free(contact);contact=((void*)0);};
2367
2368 sofia_glue_free_destination(dst);
2369 switch_safe_free(user_via)if (user_via) {free(user_via);user_via=((void*)0);};
2370 switch_safe_free(o_contact_dup)if (o_contact_dup) {free(o_contact_dup);o_contact_dup=((void*
)0);}
;
2371 switch_safe_free(send_contact)if (send_contact) {free(send_contact);send_contact=((void*)0)
;}
;
2372 switch_safe_free(our_contact_dup)if (our_contact_dup) {free(our_contact_dup);our_contact_dup=(
(void*)0);}
;
2373 switch_safe_free(path)if (path) {free(path);path=((void*)0);};
2374}
2375
2376
2377static int sofia_dialog_probe_notify_callback(void *pArg, int argc, char **argv, char **columnNames)
2378{
2379 struct rfc4235_helper *sh = (struct rfc4235_helper *) pArg;
2380 char key[256] = "";
2381 char *data = NULL((void*)0);
2382 char *call_id = argv[0];
2383 char *expires = argv[1];
2384 char *user = argv[2];
2385 char *host = argv[3];
2386 char *event = argv[4];
2387 char *version = argv[5];
2388 char *notify_state = argv[6];
2389 char *full_to = argv[7];
2390 char *full_from = argv[8];
2391 char *contact = argv[9];
2392 char *remote_ip = argv[10];
2393 char *remote_port = argv[11];
2394
2395 switch_stream_handle_t stream = { 0 };
2396 char *to;
2397 const char *pl = NULL((void*)0);
2398 const char *ct = "application/dialog-info+xml";
2399
2400 if (mod_sofia_globals.debug_presence > 0) {
2401 int i;
2402 for(i = 0; i < argc; i++) {
2403 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 2403, ((void*)0)
, SWITCH_LOG_CRIT, "arg %d[%s] = [%s]\n", i, columnNames[i], argv[i]);
2404 }
2405 }
2406
2407
2408 if (mod_sofia_globals.debug_presence > 0) {
2409 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 2409, ((void*)0)
, SWITCH_LOG_NOTICE,
2410 "SEND DIALOG\nTo: \t%s@%s\nFrom: \t%s@%s\nCall-ID: \t%s\n",
2411 user, host, user, host, call_id);
2412 }
2413
2414 to = switch_mprintf("sip:%s@%s", user, host);
2415
2416 SWITCH_STANDARD_STREAM(stream)memset(&stream, 0, sizeof(stream)); stream.data = malloc(
1024); ((stream.data) ? (void) (0) : __assert_fail ("stream.data"
, "sofia_presence.c", 2416, __PRETTY_FUNCTION__)); memset(stream
.data, 0, 1024); stream.end = stream.data; stream.data_size =
1024; stream.write_function = switch_console_stream_write; stream
.raw_write_function = switch_console_stream_raw_write; stream
.alloc_len = 1024; stream.alloc_chunk = 1024
;
2417
2418 if (zstr(version)_zstr(version)) {
2419 version = "0";
2420 }
2421
2422 stream.write_function(&stream,
2423 "<?xml version=\"1.0\"?>\n"
2424 "<dialog-info xmlns=\"urn:ietf:params:xml:ns:dialog-info\" "
2425 "version=\"%s\" state=\"%s\" entity=\"%s\">\n",
2426 version,
2427 notify_state, to);
2428
2429 switch_snprintf(key, sizeof(key), "%s%s", user, host);
2430
2431 data = switch_core_hash_find(sh->hash, key);
2432
2433 if (data) {
2434 stream.write_function(&stream, "%s\n", data);
2435 }
2436
2437 stream.write_function(&stream, "</dialog-info>\n");
2438 pl = stream.data;
2439 ct = "application/dialog-info+xml";
2440
2441 if (mod_sofia_globals.debug_presence > 0 && pl) {
2442 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 2442, ((void*)0)
, SWITCH_LOG_DEBUG, "send payload:\n%s\n", pl);
2443 }
2444
2445
2446 send_presence_notify(sh->profile,_send_presence_notify(sh->profile,full_to,full_from,contact
,expires,call_id,event,remote_ip,remote_port,ct,pl,((void*)0)
,"sofia_presence.c", (const char *)__func__, 2458)
2447 full_to,_send_presence_notify(sh->profile,full_to,full_from,contact
,expires,call_id,event,remote_ip,remote_port,ct,pl,((void*)0)
,"sofia_presence.c", (const char *)__func__, 2458)
2448 full_from,_send_presence_notify(sh->profile,full_to,full_from,contact
,expires,call_id,event,remote_ip,remote_port,ct,pl,((void*)0)
,"sofia_presence.c", (const char *)__func__, 2458)
2449 contact,_send_presence_notify(sh->profile,full_to,full_from,contact
,expires,call_id,event,remote_ip,remote_port,ct,pl,((void*)0)
,"sofia_presence.c", (const char *)__func__, 2458)
2450 expires,_send_presence_notify(sh->profile,full_to,full_from,contact
,expires,call_id,event,remote_ip,remote_port,ct,pl,((void*)0)
,"sofia_presence.c", (const char *)__func__, 2458)
2451 call_id,_send_presence_notify(sh->profile,full_to,full_from,contact
,expires,call_id,event,remote_ip,remote_port,ct,pl,((void*)0)
,"sofia_presence.c", (const char *)__func__, 2458)
2452 event,_send_presence_notify(sh->profile,full_to,full_from,contact
,expires,call_id,event,remote_ip,remote_port,ct,pl,((void*)0)
,"sofia_presence.c", (const char *)__func__, 2458)
2453 remote_ip,_send_presence_notify(sh->profile,full_to,full_from,contact
,expires,call_id,event,remote_ip,remote_port,ct,pl,((void*)0)
,"sofia_presence.c", (const char *)__func__, 2458)
2454 remote_port,_send_presence_notify(sh->profile,full_to,full_from,contact
,expires,call_id,event,remote_ip,remote_port,ct,pl,((void*)0)
,"sofia_presence.c", (const char *)__func__, 2458)
2455 ct,_send_presence_notify(sh->profile,full_to,full_from,contact
,expires,call_id,event,remote_ip,remote_port,ct,pl,((void*)0)
,"sofia_presence.c", (const char *)__func__, 2458)
2456 pl,_send_presence_notify(sh->profile,full_to,full_from,contact
,expires,call_id,event,remote_ip,remote_port,ct,pl,((void*)0)
,"sofia_presence.c", (const char *)__func__, 2458)
2457 NULL_send_presence_notify(sh->profile,full_to,full_from,contact
,expires,call_id,event,remote_ip,remote_port,ct,pl,((void*)0)
,"sofia_presence.c", (const char *)__func__, 2458)
2458 )_send_presence_notify(sh->profile,full_to,full_from,contact
,expires,call_id,event,remote_ip,remote_port,ct,pl,((void*)0)
,"sofia_presence.c", (const char *)__func__, 2458)
;
2459
2460
2461 switch_safe_free(to)if (to) {free(to);to=((void*)0);};
2462 switch_safe_free(stream.data)if (stream.data) {free(stream.data);stream.data=((void*)0);};
2463
2464 return 0;
2465}
2466
2467static char *translate_rpid(char *in)
2468{
2469 char *r = in;
2470
2471 if (in && (strstr(in, "null") || strstr(in, "NULL"))) {
2472 in = NULL((void*)0);
2473 }
2474
2475 if (zstr(in)_zstr(in)) {
2476 return NULL((void*)0);
2477 }
2478
2479 if (!strcasecmp(in, "unknown")) {
2480 r = NULL((void*)0);
2481 goto end;
2482 }
2483
2484 if (!strcasecmp(in, "busy")) {
2485 r = in;
2486 goto end;
2487 }
2488
2489 if (!strcasecmp(in, "unavailable")) {
2490 r = "away";
2491 goto end;
2492 }
2493
2494 if (!strcasecmp(in, "idle")) {
2495 r = "busy";
2496 }
2497
2498 end:
2499 return r;
2500}
2501
2502
2503static char *gen_pidf(char *user_agent, char *id, char *url, char *open, char *rpid, char *prpid, char *status, const char **ct)
2504{
2505 char *ret = NULL((void*)0);
2506
2507 if (switch_stristr("polycom", user_agent)) {
2508 *ct = "application/xpidf+xml";
2509
2510 /* If unknown/none prpid is provided, just show the user as online. */
2511 if (!prpid || !strcasecmp(prpid, "unknown")) {
2512 prpid = "online";
2513 }
2514
2515 /* of course!, lets make a big deal over dashes. Now the stupidity is complete. */
2516 if (!strcmp(prpid, "on-the-phone")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(prpid) && __builtin_constant_p ("on-the-phone") &&
(__s1_len = __builtin_strlen (prpid), __s2_len = __builtin_strlen
("on-the-phone"), (!((size_t)(const void *)((prpid) + 1) - (
size_t)(const void *)(prpid) == 1) || __s1_len >= 4) &&
(!((size_t)(const void *)(("on-the-phone") + 1) - (size_t)(const
void *)("on-the-phone") == 1) || __s2_len >= 4)) ? __builtin_strcmp
(prpid, "on-the-phone") : (__builtin_constant_p (prpid) &&
((size_t)(const void *)((prpid) + 1) - (size_t)(const void *
)(prpid) == 1) && (__s1_len = __builtin_strlen (prpid
), __s1_len < 4) ? (__builtin_constant_p ("on-the-phone") &&
((size_t)(const void *)(("on-the-phone") + 1) - (size_t)(const
void *)("on-the-phone") == 1) ? __builtin_strcmp (prpid, "on-the-phone"
) : (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) ("on-the-phone"); int __result = (((const
unsigned char *) (const char *) (prpid))[0] - __s2[0]); if (
__s1_len > 0 && __result == 0) { __result = (((const
unsigned char *) (const char *) (prpid))[1] - __s2[1]); if (
__s1_len > 1 && __result == 0) { __result = (((const
unsigned char *) (const char *) (prpid))[2] - __s2[2]); if (
__s1_len > 2 && __result == 0) __result = (((const
unsigned char *) (const char *) (prpid))[3] - __s2[3]); } } __result
; }))) : (__builtin_constant_p ("on-the-phone") && ((
size_t)(const void *)(("on-the-phone") + 1) - (size_t)(const void
*)("on-the-phone") == 1) && (__s2_len = __builtin_strlen
("on-the-phone"), __s2_len < 4) ? (__builtin_constant_p (
prpid) && ((size_t)(const void *)((prpid) + 1) - (size_t
)(const void *)(prpid) == 1) ? __builtin_strcmp (prpid, "on-the-phone"
) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (prpid); int __result = (((const unsigned
char *) (const char *) ("on-the-phone"))[0] - __s2[0]); if (
__s2_len > 0 && __result == 0) { __result = (((const
unsigned char *) (const char *) ("on-the-phone"))[1] - __s2[
1]); if (__s2_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("on-the-phone"))
[2] - __s2[2]); if (__s2_len > 2 && __result == 0)
__result = (((const unsigned char *) (const char *) ("on-the-phone"
))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (prpid
, "on-the-phone")))); })
) {
2517 prpid = "onthephone";
2518 }
2519
2520 if (zstr(open)_zstr(open)) {
2521 open = "open";
2522 }
2523
2524 ret = switch_mprintf("<?xml version=\"1.0\"?>\n"
2525 "<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n"
2526 "<presence>\n"
2527 " <status>\n"
2528 " <note>%s</note>\n"
2529 " </status>\n"
2530 " <presentity uri=\"%s;method=SUBSCRIBE\" />\n"
2531 " <atom id=\"%s\">\n"
2532 " <address uri=\"%s;user=ip\" priority=\"0.800000\">\n"
2533 " <status status=\"%s\" />\n"
2534 " <msnsubstatus substatus=\"%s\" />\n"
2535 " </address>\n"
2536 " </atom>\n"
2537 "</presence>\n", status, id, id, url, open, prpid);
2538 } else {
2539 char *xml_rpid = NULL((void*)0);
2540
2541 *ct = "application/pidf+xml";
2542
2543 if (!strcasecmp(open, "closed")) {
2544 status = "Unregistered";
2545 prpid = NULL((void*)0);
2546 }
2547
2548 if (!strncasecmp(status, "Registered", 10)) {
2549 status = "Available";
2550 }
2551
2552 if (!strcasecmp(status, "Available")) {
2553 prpid = NULL((void*)0);
2554 }
2555
2556
2557 if (!strcasecmp(status, "Unregistered")) {
2558 prpid = NULL((void*)0);
2559 open = "closed";
2560 }
2561
2562 if (zstr(rpid)_zstr(rpid)) {
2563 prpid = NULL((void*)0);
2564 }
2565
2566
2567 if (zstr(status)_zstr(status) && !zstr(prpid)_zstr(prpid)) {
2568 status = "Available";
2569 prpid = NULL((void*)0);
2570 }
2571
2572 if (prpid) {
2573 xml_rpid = switch_mprintf(" <rpid:activities>\r\n"
2574 " <rpid:%s/>\n"
2575 " </rpid:activities>\n", prpid);
2576 }
2577
2578 ret = switch_mprintf("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?> \n"
2579 "<presence xmlns='urn:ietf:params:xml:ns:pidf' \n"
2580 "xmlns:dm='urn:ietf:params:xml:ns:pidf:data-model' \n"
2581 "xmlns:rpid='urn:ietf:params:xml:ns:pidf:rpid' \n"
2582 "xmlns:c='urn:ietf:params:xml:ns:pidf:cipid' entity='%s'>\n"
2583 " <tuple id='t6a5ed77e'>\n"
2584 " <status>\r\n"
2585 " <basic>%s</basic>\n"
2586 " </status>\n"
2587 " </tuple>\n"
2588 " <dm:person id='p06360c4a'>\n"
2589 "%s"
2590 " <dm:note>%s</dm:note>\n"
2591 " </dm:person>\n"
2592 "</presence>", id, open, switch_str_nil(xml_rpid)(xml_rpid ? xml_rpid : ""), status);
2593
2594
2595 switch_safe_free(xml_rpid)if (xml_rpid) {free(xml_rpid);xml_rpid=((void*)0);};
2596 }
2597
2598
2599 return ret;
2600}
2601
2602static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char **columnNames)
2603{
2604 struct presence_helper *helper = (struct presence_helper *) pArg;
2605 char *pl = NULL((void*)0);
2606 char *clean_id = NULL((void*)0), *id = NULL((void*)0);
2607 char *proto = argv[0];
2608 char *user = argv[1];
2609 char *host = argv[2];
2610 char *sub_to_user = argv[3];
2611 char *event = argv[5];
2612 char *contact = argv[6];
2613 char *call_id = argv[7];
2614 char *full_from = argv[8];
2615 //char *full_via = argv[9];
2616 char *expires = argv[10];
2617 char *user_agent = argv[11];
2618 char *profile_name = argv[13];
2619 uint32_t in = 0;
2620 char *status = argv[14];
2621 char *rpid = argv[15];
2622 char *sub_to_host = argv[16];
2623 char *open_closed = NULL((void*)0);
2624 char *dialog_status = NULL((void*)0);
2625 char *dialog_rpid = NULL((void*)0);
2626 //char *default_dialog = "partial";
2627 char *default_dialog = "full";
2628 const char *ct = "no/idea";
2629
2630 char *to = NULL((void*)0);
2631 char *open;
2632 char *prpid;
2633
2634 int is_dialog = 0;
2635 sofia_profile_t *ext_profile = NULL((void*)0), *profile = helper->profile;
2636
2637 char status_line[256] = "";
2638 char *version = "0";
2639 char *presence_id = NULL((void*)0);
2640 char *free_me = NULL((void*)0);
2641 int holding = 0;
2642 char *orig_proto = NULL((void*)0);
2643 int skip_proto = 0;
2644 char *full_to = NULL((void*)0);
2645 char *ip = NULL((void*)0);
2646 char *port = 0;
2647 const char *call_state = NULL((void*)0);
2648 const char *astate = NULL((void*)0);
2649 const char *event_status = NULL((void*)0);
2650 const char *force_event_status = NULL((void*)0);
2651 char *contact_str, *contact_stripped;
2652
2653 if (mod_sofia_globals.debug_presence > 0) {
2654 int i;
2655 for(i = 0; i < argc; i++) {
2656 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 2656, ((void*)0)
, SWITCH_LOG_CRIT, "arg %d[%s] = [%s]\n", i, columnNames[i], argv[i]);
2657 }
2658 DUMP_EVENT(helper->event){char *event_str;switch_event_serialize(helper->event, &
event_str, SWITCH_FALSE);switch_log_printf(SWITCH_CHANNEL_ID_LOG
, "sofia_presence.c", (const char *)__func__, 2658, ((void*)0
), SWITCH_LOG_CRIT, "DUMP\n%s\n", event_str);free(event_str);
}
;
2659 }
2660
2661 if (argc > 18) {
2662 if (!zstr(argv[17])_zstr(argv[17])) {
2663 status = argv[17];
2664 }
2665 if (!zstr(argv[18])_zstr(argv[18])) {
2666 rpid = argv[18];
2667 }
2668 open_closed = argv[19];
2669 }
2670
2671 if (argc > 20) {
2672 dialog_status = argv[20];
2673 dialog_rpid = argv[21];
2674 version = argv[22];
2675 presence_id = argv[23];
2676 orig_proto = argv[24];
2677 full_to = argv[25];
2678 ip = argv[26];
2679 port = argv[27];
2680 }
2681
2682 if (!zstr(ip)_zstr(ip) && sofia_glue_check_nat(profile, ip)) {
2683 char *ptr;
2684 if ((ptr = sofia_glue_find_parameter(contact, "transport="))) {
2685 sofia_transport_t transport = sofia_glue_str2transport( ptr + 10 );
2686
2687 switch (transport) {
2688 case SOFIA_TRANSPORT_TCP:
2689 contact_str = profile->tcp_public_contact;
2690 break;
2691 case SOFIA_TRANSPORT_TCP_TLS:
2692 contact_str = sofia_test_pflag(profile, PFLAG_TLS)((profile)->pflags[PFLAG_TLS] ? 1 : 0) ?
2693 profile->tls_public_contact : profile->tcp_public_contact;
2694 break;
2695 default:
2696 contact_str = profile->public_url;
2697 break;
2698 }
2699 } else {
2700 contact_str = profile->public_url;
2701 }
2702 } else {
2703 char *ptr;
2704 if ((ptr = sofia_glue_find_parameter(contact, "transport="))) {
2705 sofia_transport_t transport = sofia_glue_str2transport( ptr + 10 );
2706
2707 switch (transport) {
2708 case SOFIA_TRANSPORT_TCP:
2709 contact_str = profile->tcp_contact;
2710 break;
2711 case SOFIA_TRANSPORT_TCP_TLS:
2712 contact_str = sofia_test_pflag(profile, PFLAG_TLS)((profile)->pflags[PFLAG_TLS] ? 1 : 0) ?
2713 profile->tls_contact : profile->tcp_contact;
2714 break;
2715 default:
2716 contact_str = profile->url;
2717 break;
2718 }
2719 } else {
2720 contact_str = profile->url;
2721 }
2722 }
2723
2724
2725 if (!zstr(presence_id)_zstr(presence_id) && strchr(presence_id, '@')(__extension__ (__builtin_constant_p ('@') && !__builtin_constant_p
(presence_id) && ('@') == '\0' ? (char *) __rawmemchr
(presence_id, '@') : __builtin_strchr (presence_id, '@')))
) {
2726 char *p;
2727
2728 free_me = strdup(presence_id)(__extension__ (__builtin_constant_p (presence_id) &&
((size_t)(const void *)((presence_id) + 1) - (size_t)(const void
*)(presence_id) == 1) ? (((const char *) (presence_id))[0] ==
'\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len
= strlen (presence_id) + 1; char *__retval = (char *) malloc
(__len); if (__retval != ((void*)0)) __retval = (char *) memcpy
(__retval, presence_id, __len); __retval; })) : __strdup (presence_id
)))
;
2729
2730 if ((p = strchr(free_me, '@')(__extension__ (__builtin_constant_p ('@') && !__builtin_constant_p
(free_me) && ('@') == '\0' ? (char *) __rawmemchr (free_me
, '@') : __builtin_strchr (free_me, '@')))
)) {
2731 *p = '\0';
2732 }
2733
2734 user = free_me;
2735 }
2736
2737
2738 if (!zstr(orig_proto)_zstr(orig_proto) && !strcmp(orig_proto, SOFIA_CHAT_PROTO)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(orig_proto) && __builtin_constant_p ("sip") &&
(__s1_len = __builtin_strlen (orig_proto), __s2_len = __builtin_strlen
("sip"), (!((size_t)(const void *)((orig_proto) + 1) - (size_t
)(const void *)(orig_proto) == 1) || __s1_len >= 4) &&
(!((size_t)(const void *)(("sip") + 1) - (size_t)(const void
*)("sip") == 1) || __s2_len >= 4)) ? __builtin_strcmp (orig_proto
, "sip") : (__builtin_constant_p (orig_proto) && ((size_t
)(const void *)((orig_proto) + 1) - (size_t)(const void *)(orig_proto
) == 1) && (__s1_len = __builtin_strlen (orig_proto),
__s1_len < 4) ? (__builtin_constant_p ("sip") && (
(size_t)(const void *)(("sip") + 1) - (size_t)(const void *)(
"sip") == 1) ? __builtin_strcmp (orig_proto, "sip") : (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) ("sip"); int __result = (((const unsigned char *) (const
char *) (orig_proto))[0] - __s2[0]); if (__s1_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (orig_proto))[1] - __s2[1]); if (__s1_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (orig_proto))[2] - __s2[2]); if (__s1_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (orig_proto))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
("sip") && ((size_t)(const void *)(("sip") + 1) - (size_t
)(const void *)("sip") == 1) && (__s2_len = __builtin_strlen
("sip"), __s2_len < 4) ? (__builtin_constant_p (orig_proto
) && ((size_t)(const void *)((orig_proto) + 1) - (size_t
)(const void *)(orig_proto) == 1) ? __builtin_strcmp (orig_proto
, "sip") : (- (__extension__ ({ const unsigned char *__s2 = (
const unsigned char *) (const char *) (orig_proto); int __result
= (((const unsigned char *) (const char *) ("sip"))[0] - __s2
[0]); if (__s2_len > 0 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("sip"))[1] - __s2
[1]); if (__s2_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("sip"))[2] - __s2
[2]); if (__s2_len > 2 && __result == 0) __result =
(((const unsigned char *) (const char *) ("sip"))[3] - __s2[
3]); } } __result; })))) : __builtin_strcmp (orig_proto, "sip"
)))); })
) {
2739 skip_proto = 1;
2740 }
2741
2742 in = helper->event && helper->event->event_id == SWITCH_EVENT_PRESENCE_IN;
2743
2744 if (zstr(rpid)_zstr(rpid)) {
2745 rpid = "unknown";
2746 }
2747
2748 if (zstr(status)_zstr(status)) {
2749 if (!strcasecmp(rpid, "busy")) {
2750 status = "Busy";
2751 } else if (!strcasecmp(rpid, "unavailable")) {
2752 status = "Idle";
2753 } else if (!strcasecmp(rpid, "away")) {
2754 status = "Idle";
2755 } else {
2756 status = "Available";
2757 }
2758 }
2759
2760 if (status && !strncasecmp(status, "hold", 4)) {
2761 holding = 1;
2762 }
2763
2764 if (profile_name && strcasecmp(profile_name, helper->profile->name)) {
2765 if ((ext_profile = sofia_glue_find_profile(profile_name)sofia_glue_find_profile__("sofia_presence.c", (const char *)__func__
, 2765, profile_name)
)) {
2766 profile = ext_profile;
2767 }
2768 }
2769
2770
2771 if (!strcasecmp(proto, SOFIA_CHAT_PROTO"sip") || skip_proto) {
2772 clean_id = switch_mprintf("sip:%s@%s", sub_to_user, sub_to_host);
2773 } else {
2774 clean_id = switch_mprintf("sip:%s+%s@%s", proto, sub_to_user, sub_to_host);
2775 }
2776
2777
2778
2779 if (!rpid) {
2780 rpid = "unknown";
2781 }
2782
2783 // if (!strcasecmp(proto, SOFIA_CHAT_PROTO) || skip_proto) {
2784 // clean_id = switch_mprintf("sip:%s@%s", sub_to_user, sub_to_host);
2785 //} else {
2786 // clean_id = switch_mprintf("sip:%s+%s@%s", proto, sub_to_user, sub_to_host);
2787 //}
2788
2789 if (mod_sofia_globals.debug_presence > 0) {
2790 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 2790, ((void*)0)
, SWITCH_LOG_NOTICE,
2791 "SEND PRESENCE\nTo: \t%s@%s\nFrom: \t%s@%s\nCall-ID: \t%s\nProfile:\t%s [%s]\n\n",
2792 user, host, sub_to_user, sub_to_host, call_id, profile_name, helper->profile->name);
2793 }
2794
2795 if (!strcasecmp(sub_to_host, host) && !skip_proto) {
2796 /* same host */
2797 id = switch_mprintf("sip:%s+%s@%s", proto, sub_to_user, sub_to_host);
2798 } else if (strcasecmp(proto, SOFIA_CHAT_PROTO"sip") && !skip_proto) {
2799 /*encapsulate */
2800 id = switch_mprintf("sip:%s+%s+%s@%s", proto, sub_to_user, sub_to_host, host);
2801 } else {
2802 id = switch_mprintf("sip:%s@%s", sub_to_user, sub_to_host);
2803 }
2804
2805 to = switch_mprintf("sip:%s@%s", user, host);
2806
2807 is_dialog = !strcmp(event, "dialog")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(event) && __builtin_constant_p ("dialog") &&
(__s1_len = __builtin_strlen (event), __s2_len = __builtin_strlen
("dialog"), (!((size_t)(const void *)((event) + 1) - (size_t
)(const void *)(event) == 1) || __s1_len >= 4) && (
!((size_t)(const void *)(("dialog") + 1) - (size_t)(const void
*)("dialog") == 1) || __s2_len >= 4)) ? __builtin_strcmp (
event, "dialog") : (__builtin_constant_p (event) && (
(size_t)(const void *)((event) + 1) - (size_t)(const void *)(
event) == 1) && (__s1_len = __builtin_strlen (event),
__s1_len < 4) ? (__builtin_constant_p ("dialog") &&
((size_t)(const void *)(("dialog") + 1) - (size_t)(const void
*)("dialog") == 1) ? __builtin_strcmp (event, "dialog") : (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) ("dialog"); int __result = (((const unsigned char *)
(const char *) (event))[0] - __s2[0]); if (__s1_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (event))[1] - __s2[1]); if (__s1_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (event))[2] - __s2[2]); if (__s1_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (event))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
("dialog") && ((size_t)(const void *)(("dialog") + 1
) - (size_t)(const void *)("dialog") == 1) && (__s2_len
= __builtin_strlen ("dialog"), __s2_len < 4) ? (__builtin_constant_p
(event) && ((size_t)(const void *)((event) + 1) - (size_t
)(const void *)(event) == 1) ? __builtin_strcmp (event, "dialog"
) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (event); int __result = (((const unsigned
char *) (const char *) ("dialog"))[0] - __s2[0]); if (__s2_len
> 0 && __result == 0) { __result = (((const unsigned
char *) (const char *) ("dialog"))[1] - __s2[1]); if (__s2_len
> 1 && __result == 0) { __result = (((const unsigned
char *) (const char *) ("dialog"))[2] - __s2[2]); if (__s2_len
> 2 && __result == 0) __result = (((const unsigned
char *) (const char *) ("dialog"))[3] - __s2[3]); } } __result
; })))) : __builtin_strcmp (event, "dialog")))); })
;
2808
2809 if (helper->hup && helper->calls_up > 0) {
2810 call_state = "CS_EXECUTE";
2811 astate = "active";
2812 event_status = "Active";
2813 force_event_status = NULL((void*)0);
2814 } else {
2815 if (helper->event) {
2816 call_state = switch_event_get_header(helper->event, "channel-state")switch_event_get_header_idx(helper->event, "channel-state"
, -1)
;
2817 astate = switch_str_nil(switch_event_get_header(helper->event, "astate"))(switch_event_get_header_idx(helper->event, "astate", -1) ?
switch_event_get_header_idx(helper->event, "astate", -1) :
"")
;
2818 event_status = switch_str_nil(switch_event_get_header(helper->event, "status"))(switch_event_get_header_idx(helper->event, "status", -1) ?
switch_event_get_header_idx(helper->event, "status", -1) :
"")
;
2819 force_event_status = switch_str_nil(switch_event_get_header(helper->event, "force-status"))(switch_event_get_header_idx(helper->event, "force-status"
, -1) ? switch_event_get_header_idx(helper->event, "force-status"
, -1) : "")
;
2820 }
2821 }
2822
2823 if (helper->event) {
2824 switch_stream_handle_t stream = { 0 };
2825 const char *direction = switch_str_nil(switch_event_get_header(helper->event, "presence-call-direction"))(switch_event_get_header_idx(helper->event, "presence-call-direction"
, -1) ? switch_event_get_header_idx(helper->event, "presence-call-direction"
, -1) : "")
;
2826 //const char *force_direction = switch_str_nil(switch_event_get_header(helper->event, "force-direction"));
2827 const char *uuid = switch_str_nil(switch_event_get_header(helper->event, "unique-id"))(switch_event_get_header_idx(helper->event, "unique-id", -
1) ? switch_event_get_header_idx(helper->event, "unique-id"
, -1) : "")
;
2828 const char *resub = switch_str_nil(switch_event_get_header(helper->event, "resub"))(switch_event_get_header_idx(helper->event, "resub", -1) ?
switch_event_get_header_idx(helper->event, "resub", -1) :
"")
;
2829 const char *answer_state = switch_str_nil(switch_event_get_header(helper->event, "answer-state"))(switch_event_get_header_idx(helper->event, "answer-state"
, -1) ? switch_event_get_header_idx(helper->event, "answer-state"
, -1) : "")
;
2830 const char *dft_state;
2831 const char *from_id = NULL((void*)0), *from_name = NULL((void*)0);
2832 const char *to_user = switch_str_nil(switch_event_get_header(helper->event, "variable_sip_to_user"))(switch_event_get_header_idx(helper->event, "variable_sip_to_user"
, -1) ? switch_event_get_header_idx(helper->event, "variable_sip_to_user"
, -1) : "")
;
2833 const char *from_user = switch_str_nil(switch_event_get_header(helper->event, "variable_sip_from_user"))(switch_event_get_header_idx(helper->event, "variable_sip_from_user"
, -1) ? switch_event_get_header_idx(helper->event, "variable_sip_from_user"
, -1) : "")
;
2834 const char *disable_early = switch_str_nil(switch_event_get_header(helper->event, "variable_presence_disable_early"))(switch_event_get_header_idx(helper->event, "variable_presence_disable_early"
, -1) ? switch_event_get_header_idx(helper->event, "variable_presence_disable_early"
, -1) : "")
;
2835 const char *answer_epoch = switch_str_nil(switch_event_get_header(helper->event, "variable_answer_epoch"))(switch_event_get_header_idx(helper->event, "variable_answer_epoch"
, -1) ? switch_event_get_header_idx(helper->event, "variable_answer_epoch"
, -1) : "")
;
2836 int answered = 0;
2837 char *clean_to_user = NULL((void*)0);
2838 char *clean_from_user = NULL((void*)0);
2839 int force_status = 0;
2840 int term = 0;
2841
2842 if (answer_epoch) {
2843 answered = atoi(answer_epoch);
2844 }
2845
2846
2847 //if (user_agent && switch_stristr("snom", user_agent) && uuid) {
2848 // default_dialog = "full" ;
2849 //}
2850
2851 if (call_state && !strcasecmp(call_state, "cs_hangup")) {
2852 astate = "hangup";
2853 holding = 0;
2854 term = 1;
2855 } else {
2856
2857 if (event_status && !strncasecmp(event_status, "hold", 4)) {
2858 holding = 1;
2859 }
2860
2861 if (force_event_status && !event_status) {
2862 event_status = force_event_status;
2863 }
2864
2865 if (event_status && !strncasecmp(event_status, "hold", 4)) {
2866 holding = 1;
2867 }
2868 }
2869
2870 if (!strcasecmp(direction, "inbound")) {
2871 from_id = switch_str_nil(switch_event_get_header(helper->event, "Caller-Destination-Number"))(switch_event_get_header_idx(helper->event, "Caller-Destination-Number"
, -1) ? switch_event_get_header_idx(helper->event, "Caller-Destination-Number"
, -1) : "")
;
2872
2873 } else {
2874 from_id = switch_str_nil(switch_event_get_header(helper->event, "Caller-Caller-ID-Number"))(switch_event_get_header_idx(helper->event, "Caller-Caller-ID-Number"
, -1) ? switch_event_get_header_idx(helper->event, "Caller-Caller-ID-Number"
, -1) : "")
;
2875 from_name = switch_event_get_header(helper->event, "Caller-Caller-ID-Name")switch_event_get_header_idx(helper->event, "Caller-Caller-ID-Name"
, -1)
;
2876
2877 if (zstr(from_id)_zstr(from_id)) {
2878 from_id = switch_str_nil(switch_event_get_header(helper->event, "Other-Leg-Caller-ID-Number"))(switch_event_get_header_idx(helper->event, "Other-Leg-Caller-ID-Number"
, -1) ? switch_event_get_header_idx(helper->event, "Other-Leg-Caller-ID-Number"
, -1) : "")
;
2879 }
2880
2881 if (zstr(from_name)_zstr(from_name)) {
2882 from_name = switch_event_get_header(helper->event, "Other-Leg-Caller-ID-Name")switch_event_get_header_idx(helper->event, "Other-Leg-Caller-ID-Name"
, -1)
;
2883 }
2884
2885 }
2886
2887#if 0
2888 char *buf;
2889 switch_event_serialize(helper->event, &buf, SWITCH_FALSE);
2890 switch_assert(buf)((buf) ? (void) (0) : __assert_fail ("buf", "sofia_presence.c"
, 2890, __PRETTY_FUNCTION__))
;
2891 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 2891, ((void*)0)
, SWITCH_LOG_INFO, "CHANNEL_DATA:\n%s\n", buf);
2892 free(buf);
2893#endif
2894
2895 if (is_dialog) {
2896 SWITCH_STANDARD_STREAM(stream)memset(&stream, 0, sizeof(stream)); stream.data = malloc(
1024); ((stream.data) ? (void) (0) : __assert_fail ("stream.data"
, "sofia_presence.c", 2896, __PRETTY_FUNCTION__)); memset(stream
.data, 0, 1024); stream.end = stream.data; stream.data_size =
1024; stream.write_function = switch_console_stream_write; stream
.raw_write_function = switch_console_stream_raw_write; stream
.alloc_len = 1024; stream.alloc_chunk = 1024
;
2897 }
2898
2899 if (is_dialog) {
2900 // Usually we report the dialogs FROM the probed user. The exception is when the monitored endpoint is internal,
2901 // and its presence_id is set in the dialplan. Reverse the direction if this is not a registered entity.
2902 const char *caller = switch_str_nil(switch_event_get_header(helper->event, "caller-username"))(switch_event_get_header_idx(helper->event, "caller-username"
, -1) ? switch_event_get_header_idx(helper->event, "caller-username"
, -1) : "")
;
2903 if (!strcmp(direction, "inbound")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(direction) && __builtin_constant_p ("inbound") &&
(__s1_len = __builtin_strlen (direction), __s2_len = __builtin_strlen
("inbound"), (!((size_t)(const void *)((direction) + 1) - (size_t
)(const void *)(direction) == 1) || __s1_len >= 4) &&
(!((size_t)(const void *)(("inbound") + 1) - (size_t)(const void
*)("inbound") == 1) || __s2_len >= 4)) ? __builtin_strcmp
(direction, "inbound") : (__builtin_constant_p (direction) &&
((size_t)(const void *)((direction) + 1) - (size_t)(const void
*)(direction) == 1) && (__s1_len = __builtin_strlen (
direction), __s1_len < 4) ? (__builtin_constant_p ("inbound"
) && ((size_t)(const void *)(("inbound") + 1) - (size_t
)(const void *)("inbound") == 1) ? __builtin_strcmp (direction
, "inbound") : (__extension__ ({ const unsigned char *__s2 = (
const unsigned char *) (const char *) ("inbound"); int __result
= (((const unsigned char *) (const char *) (direction))[0] -
__s2[0]); if (__s1_len > 0 && __result == 0) { __result
= (((const unsigned char *) (const char *) (direction))[1] -
__s2[1]); if (__s1_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) (direction))[2] -
__s2[2]); if (__s1_len > 2 && __result == 0) __result
= (((const unsigned char *) (const char *) (direction))[3] -
__s2[3]); } } __result; }))) : (__builtin_constant_p ("inbound"
) && ((size_t)(const void *)(("inbound") + 1) - (size_t
)(const void *)("inbound") == 1) && (__s2_len = __builtin_strlen
("inbound"), __s2_len < 4) ? (__builtin_constant_p (direction
) && ((size_t)(const void *)((direction) + 1) - (size_t
)(const void *)(direction) == 1) ? __builtin_strcmp (direction
, "inbound") : (- (__extension__ ({ const unsigned char *__s2
= (const unsigned char *) (const char *) (direction); int __result
= (((const unsigned char *) (const char *) ("inbound"))[0] -
__s2[0]); if (__s2_len > 0 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("inbound"))[1] -
__s2[1]); if (__s2_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("inbound"))[2] -
__s2[2]); if (__s2_len > 2 && __result == 0) __result
= (((const unsigned char *) (const char *) ("inbound"))[3] -
__s2[3]); } } __result; })))) : __builtin_strcmp (direction,
"inbound")))); })
&& strcmp(sub_to_user, caller)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(sub_to_user) && __builtin_constant_p (caller) &&
(__s1_len = __builtin_strlen (sub_to_user), __s2_len = __builtin_strlen
(caller), (!((size_t)(const void *)((sub_to_user) + 1) - (size_t
)(const void *)(sub_to_user) == 1) || __s1_len >= 4) &&
(!((size_t)(const void *)((caller) + 1) - (size_t)(const void
*)(caller) == 1) || __s2_len >= 4)) ? __builtin_strcmp (sub_to_user
, caller) : (__builtin_constant_p (sub_to_user) && ((
size_t)(const void *)((sub_to_user) + 1) - (size_t)(const void
*)(sub_to_user) == 1) && (__s1_len = __builtin_strlen
(sub_to_user), __s1_len < 4) ? (__builtin_constant_p (caller
) && ((size_t)(const void *)((caller) + 1) - (size_t)
(const void *)(caller) == 1) ? __builtin_strcmp (sub_to_user,
caller) : (__extension__ ({ const unsigned char *__s2 = (const
unsigned char *) (const char *) (caller); int __result = (((
const unsigned char *) (const char *) (sub_to_user))[0] - __s2
[0]); if (__s1_len > 0 && __result == 0) { __result
= (((const unsigned char *) (const char *) (sub_to_user))[1]
- __s2[1]); if (__s1_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) (sub_to_user))[2]
- __s2[2]); if (__s1_len > 2 && __result == 0) __result
= (((const unsigned char *) (const char *) (sub_to_user))[3]
- __s2[3]); } } __result; }))) : (__builtin_constant_p (caller
) && ((size_t)(const void *)((caller) + 1) - (size_t)
(const void *)(caller) == 1) && (__s2_len = __builtin_strlen
(caller), __s2_len < 4) ? (__builtin_constant_p (sub_to_user
) && ((size_t)(const void *)((sub_to_user) + 1) - (size_t
)(const void *)(sub_to_user) == 1) ? __builtin_strcmp (sub_to_user
, caller) : (- (__extension__ ({ const unsigned char *__s2 = (
const unsigned char *) (const char *) (sub_to_user); int __result
= (((const unsigned char *) (const char *) (caller))[0] - __s2
[0]); if (__s2_len > 0 && __result == 0) { __result
= (((const unsigned char *) (const char *) (caller))[1] - __s2
[1]); if (__s2_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) (caller))[2] - __s2
[2]); if (__s2_len > 2 && __result == 0) __result =
(((const unsigned char *) (const char *) (caller))[3] - __s2
[3]); } } __result; })))) : __builtin_strcmp (sub_to_user, caller
)))); })
) {
2904 // If inbound and the entity is not the caller (i.e. internal to FS), then the direction is reversed
2905 // because it is not going through the B2BUA
2906 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 2906, ((void*)0)
, SWITCH_LOG_DEBUG, "sofia_presence_sub_callback: endpt is internal\n");
2907 direction = !strcasecmp(direction, "outbound") ? "inbound" : "outbound";
2908 }
2909
2910 }
2911
2912 if (!strcasecmp(direction, "outbound")) {
2913 direction = "recipient";
2914 dft_state = "early";
2915 } else {
2916 direction = "initiator";
2917 dft_state = "confirmed";
2918 }
2919
2920 if (is_dialog) {
2921 if (zstr(version)_zstr(version)) {
2922 version = "0";
2923 }
2924
2925 stream.write_function(&stream,
2926 "<?xml version=\"1.0\"?>\n"
2927 "<dialog-info xmlns=\"urn:ietf:params:xml:ns:dialog-info\" "
2928 "version=\"%s\" state=\"%s\" entity=\"%s\">\n", version, default_dialog, clean_id);
2929
2930 }
2931
2932 if (!zstr(uuid)_zstr(uuid)) {
2933 if (!zstr(answer_state)_zstr(answer_state)) {
2934 astate = answer_state;
2935 }
2936
2937 if (zstr(astate)_zstr(astate)) {
2938 if (is_dialog) {
2939 astate = dft_state;
2940 } else {
2941 astate = "terminated";
2942 }
2943 }
2944
2945 if (!strcasecmp(astate, "answered")) {
2946 astate = "confirmed";
2947 }
2948
2949
2950 if (is_dialog) {
2951
2952 if (!strcasecmp(astate, "ringing")) {
2953 if (!strcasecmp(direction, "recipient")) {
2954 astate = "early";
2955 } else {
2956 astate = "confirmed";
2957 }
2958 }
2959
2960 if (holding) {
2961 if (profile->pres_held_type == PRES_HELD_CONFIRMED) {
2962 astate = "confirmed";
2963 } else if (profile->pres_held_type == PRES_HELD_TERMINATED) {
2964 astate = "terminated";
2965 } else {
2966 astate = "early";
2967 }
2968 }
2969
2970
2971 if (!strcasecmp(astate, "hangup")) {
2972 astate = "terminated";
2973 }
2974
2975 stream.write_function(&stream, "<dialog id=\"%s\" direction=\"%s\">\n", uuid, direction);
2976 stream.write_function(&stream, "<state>%s</state>\n", astate);
2977 } else {
2978 if (!strcasecmp(astate, "ringing")) {
2979 astate = "early";
2980 }
2981 }
2982
2983
2984 if ((sofia_test_pflag(profile, PFLAG_PRESENCE_DISABLE_EARLY)((profile)->pflags[PFLAG_PRESENCE_DISABLE_EARLY] ? 1 : 0) || switch_true(disable_early)) &&
2985 ((!zstr(astate)_zstr(astate) && (!strcasecmp(astate, "early") || !strcasecmp(astate, "ringing") || (!strcasecmp(astate, "terminated") && !answered))))) {
2986 switch_safe_free(stream.data)if (stream.data) {free(stream.data);stream.data=((void*)0);};
2987 goto end;
2988 }
2989
2990 if (!strcasecmp(astate, "early") || !strcasecmp(astate, "confirmed")) {
2991
2992 clean_to_user = switch_mprintf("%s", sub_to_user ? sub_to_user : to_user);
2993 clean_from_user = switch_mprintf("%s", from_id ? from_id : from_user);
2994
2995 if (is_dialog) {
2996 if (!zstr(clean_to_user)_zstr(clean_to_user) && !zstr(clean_from_user)_zstr(clean_from_user)) {
2997 stream.write_function(&stream, "<local>\n<identity display=\"%s\">sip:%s@%s</identity>\n", clean_to_user, clean_to_user, host);
2998 stream.write_function(&stream, "<target uri=\"sip:%s@%s\">\n", clean_to_user, host);
2999 stream.write_function(&stream, "<param pname=\"+sip.rendering\" pvalue=\"%s\"/>\n", holding ? "no" : "yes");
3000
3001 stream.write_function(&stream, "</target>\n</local>\n");
3002 if (switch_true(switch_event_get_header(helper->event, "Presence-Privacy")switch_event_get_header_idx(helper->event, "Presence-Privacy"
, -1)
)) {
3003 stream.write_function(&stream, "<remote>\n<identity display=\"Anonymous\">sip:anonymous@anonymous.invalid</identity>\n");
3004 } else {
3005 stream.write_function(&stream, "<remote>\n<identity display=\"%s\">sip:%s@%s</identity>\n",
3006 from_name ? from_name : clean_from_user, clean_from_user,
3007 host);
3008 }
3009 stream.write_function(&stream, "<target uri=\"sip:**%s@%s\"/>\n", clean_to_user, host);
3010 stream.write_function(&stream, "</remote>\n");
3011
3012 } else if (!strcasecmp(proto, "queue")) {
3013 stream.write_function(&stream, "<local>\n<identity display=\"queue\">sip:%s@%s;proto=queue</identity>\n",
3014 !zstr(clean_to_user)_zstr(clean_to_user) ? clean_to_user : "unknown", host);
3015 stream.write_function(&stream, "<target uri=\"sip:%s@%s;proto=fifo\">\n", !zstr(clean_to_user)_zstr(clean_to_user) ? clean_to_user : "unknown", host);
3016 stream.write_function(&stream, "<param pname=\"+sip.rendering\" pvalue=\"no\"/>\n</target>\n</local>\n");
3017 stream.write_function(&stream, "<remote>\n<identity display=\"queue\">sip:%s</identity>\n", uuid);
3018 if (skip_proto) {
3019 stream.write_function(&stream, "<target uri=\"sip:%s\"/>\n", uuid);
3020 } else {
3021 stream.write_function(&stream, "<target uri=\"sip:queue+%s\"/>\n", uuid);
3022 }
3023
3024 stream.write_function(&stream, "</remote>\n");
3025 } else if (!strcasecmp(proto, "park")) {
3026 stream.write_function(&stream, "<local>\n<identity display=\"park\">sip:%s@%s;proto=park</identity>\n",
3027 !zstr(clean_to_user)_zstr(clean_to_user) ? clean_to_user : "unknown", host);
3028 stream.write_function(&stream, "<target uri=\"sip:%s@%s;proto=park\">\n", !zstr(clean_to_user)_zstr(clean_to_user) ? clean_to_user : "unknown", host);
3029 stream.write_function(&stream, "<param pname=\"+sip.rendering\" pvalue=\"no\"/>\n</target>\n</local>\n");
3030 stream.write_function(&stream, "<remote>\n<identity display=\"park\">sip:%s</identity>\n", uuid);
3031 if (skip_proto) {
3032 stream.write_function(&stream, "<target uri=\"sip:%s\"/>\n", uuid);
3033 } else {
3034 stream.write_function(&stream, "<target uri=\"sip:park+%s\"/>\n", uuid);
3035 }
3036 stream.write_function(&stream, "</remote>\n");
3037 } else if (!strcasecmp(proto, "pickup")) {
3038 stream.write_function(&stream, "<local>\n<identity display=\"pickup\">sip:%s@%s;proto=pickup</identity>\n",
3039 !zstr(clean_to_user)_zstr(clean_to_user) ? clean_to_user : "unknown", host);
3040 stream.write_function(&stream, "<target uri=\"sip:%s@%s;proto=pickup\">\n", !zstr(clean_to_user)_zstr(clean_to_user) ? clean_to_user : "unknown", host);
3041 stream.write_function(&stream, "<param pname=\"+sip.rendering\" pvalue=\"no\"/>\n</target>\n</local>\n");
3042 stream.write_function(&stream, "<remote>\n<identity display=\"pickup\">sip:%s</identity>\n", uuid);
3043 if (skip_proto) {
3044 stream.write_function(&stream, "<target uri=\"sip:%s\"/>\n", uuid);
3045 } else {
3046 stream.write_function(&stream, "<target uri=\"sip:pickup+%s\"/>\n", uuid);
3047 }
3048 stream.write_function(&stream, "</remote>\n");
3049 } else if (!strcasecmp(proto, "conf")) {
3050 stream.write_function(&stream, "<local>\n<identity display=\"conference\">sip:%s@%s;proto=conference</identity>\n",
3051 !zstr(clean_to_user)_zstr(clean_to_user) ? clean_to_user : "unknown", host);
3052 stream.write_function(&stream, "<target uri=\"sip:%s@%s;proto=conference\">\n",
3053 !zstr(clean_to_user)_zstr(clean_to_user) ? clean_to_user : "unknown", host);
3054 stream.write_function(&stream, "<param pname=\"+sip.rendering\" pvalue=\"yes\"/>\n</target>\n</local>\n");
3055 stream.write_function(&stream, "<remote>\n<identity display=\"conference\">sip:%s@%s</identity>\n", uuid, host);
3056 if (skip_proto) {
3057 stream.write_function(&stream, "<target uri=\"sip:%s@%s\"/>\n", uuid, host);
3058 } else {
3059 stream.write_function(&stream, "<target uri=\"sip:conf+%s@%s\"/>\n", uuid, host);
3060 }
3061 stream.write_function(&stream, "</remote>\n");
3062 }
3063 }
3064
3065 switch_safe_free(clean_to_user)if (clean_to_user) {free(clean_to_user);clean_to_user=((void*
)0);}
;
3066 switch_safe_free(clean_from_user)if (clean_from_user) {free(clean_from_user);clean_from_user=(
(void*)0);}
;
3067 }
3068 if (is_dialog) {
3069 stream.write_function(&stream, "</dialog>\n");
3070 }
3071 }
3072
3073 if (is_dialog) {
3074 stream.write_function(&stream, "</dialog-info>\n");
3075 pl = stream.data;
3076 ct = "application/dialog-info+xml";
3077 }
3078
3079 if (!zstr(astate)_zstr(astate) && !zstr(uuid)_zstr(uuid) &&
3080 helper && helper->stream.data && strcmp(helper->last_uuid, uuid)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(helper->last_uuid) && __builtin_constant_p (uuid
) && (__s1_len = __builtin_strlen (helper->last_uuid
), __s2_len = __builtin_strlen (uuid), (!((size_t)(const void
*)((helper->last_uuid) + 1) - (size_t)(const void *)(helper
->last_uuid) == 1) || __s1_len >= 4) && (!((size_t
)(const void *)((uuid) + 1) - (size_t)(const void *)(uuid) ==
1) || __s2_len >= 4)) ? __builtin_strcmp (helper->last_uuid
, uuid) : (__builtin_constant_p (helper->last_uuid) &&
((size_t)(const void *)((helper->last_uuid) + 1) - (size_t
)(const void *)(helper->last_uuid) == 1) && (__s1_len
= __builtin_strlen (helper->last_uuid), __s1_len < 4) ?
(__builtin_constant_p (uuid) && ((size_t)(const void
*)((uuid) + 1) - (size_t)(const void *)(uuid) == 1) ? __builtin_strcmp
(helper->last_uuid, uuid) : (__extension__ ({ const unsigned
char *__s2 = (const unsigned char *) (const char *) (uuid); int
__result = (((const unsigned char *) (const char *) (helper->
last_uuid))[0] - __s2[0]); if (__s1_len > 0 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
helper->last_uuid))[1] - __s2[1]); if (__s1_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (helper->last_uuid))[2] - __s2[2]); if (__s1_len >
2 && __result == 0) __result = (((const unsigned char
*) (const char *) (helper->last_uuid))[3] - __s2[3]); } }
__result; }))) : (__builtin_constant_p (uuid) && ((size_t
)(const void *)((uuid) + 1) - (size_t)(const void *)(uuid) ==
1) && (__s2_len = __builtin_strlen (uuid), __s2_len <
4) ? (__builtin_constant_p (helper->last_uuid) &&
((size_t)(const void *)((helper->last_uuid) + 1) - (size_t
)(const void *)(helper->last_uuid) == 1) ? __builtin_strcmp
(helper->last_uuid, uuid) : (- (__extension__ ({ const unsigned
char *__s2 = (const unsigned char *) (const char *) (helper->
last_uuid); int __result = (((const unsigned char *) (const char
*) (uuid))[0] - __s2[0]); if (__s2_len > 0 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
uuid))[1] - __s2[1]); if (__s2_len > 1 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
uuid))[2] - __s2[2]); if (__s2_len > 2 && __result
== 0) __result = (((const unsigned char *) (const char *) (uuid
))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (helper
->last_uuid, uuid)))); })
&& strcasecmp(astate, "terminated") && strchr(uuid, '-')(__extension__ (__builtin_constant_p ('-') && !__builtin_constant_p
(uuid) && ('-') == '\0' ? (char *) __rawmemchr (uuid
, '-') : __builtin_strchr (uuid, '-')))
) {
3081 helper->stream.write_function(&helper->stream, "update sip_dialogs set state='%s' where hostname='%q' and profile_name='%q' and uuid='%s';",
3082 astate, mod_sofia_globals.hostname, profile->name, uuid);
3083 switch_copy_string(helper->last_uuid, uuid, sizeof(helper->last_uuid));
3084 }
3085
3086 if (zstr(astate)_zstr(astate)) astate = "";
3087
3088 if (!is_dialog) {
3089 switch_set_string(status_line, status)switch_copy_string(status_line, status, sizeof(status_line));
3090
3091 if (in) {
3092 open = "open";
3093
3094 if (switch_false(resub)) {
3095 const char *direction = switch_event_get_header(helper->event, "Caller-Direction")switch_event_get_header_idx(helper->event, "Caller-Direction"
, -1)
;
3096 const char *op, *what = "Ring";
3097
3098 if (direction && !strcasecmp(direction, "outbound")) {
3099 op = switch_event_get_header(helper->event, "Other-Leg-Caller-ID-Number")switch_event_get_header_idx(helper->event, "Other-Leg-Caller-ID-Number"
, -1)
;
3100 } else {
3101 op = switch_event_get_header(helper->event, "Caller-Callee-ID-Number")switch_event_get_header_idx(helper->event, "Caller-Callee-ID-Number"
, -1)
;
3102 }
3103
3104 if (zstr(op)_zstr(op)) {
3105 op = switch_event_get_header(helper->event, "Caller-Destination-Number")switch_event_get_header_idx(helper->event, "Caller-Destination-Number"
, -1)
;
3106 }
3107
3108 if (direction) {
3109 what = strcasecmp(direction, "outbound") ? "Call" : "Ring";
3110 }
3111
3112 if (!strcmp(astate, "early")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(astate) && __builtin_constant_p ("early") &&
(__s1_len = __builtin_strlen (astate), __s2_len = __builtin_strlen
("early"), (!((size_t)(const void *)((astate) + 1) - (size_t
)(const void *)(astate) == 1) || __s1_len >= 4) &&
(!((size_t)(const void *)(("early") + 1) - (size_t)(const void
*)("early") == 1) || __s2_len >= 4)) ? __builtin_strcmp (
astate, "early") : (__builtin_constant_p (astate) && (
(size_t)(const void *)((astate) + 1) - (size_t)(const void *)
(astate) == 1) && (__s1_len = __builtin_strlen (astate
), __s1_len < 4) ? (__builtin_constant_p ("early") &&
((size_t)(const void *)(("early") + 1) - (size_t)(const void
*)("early") == 1) ? __builtin_strcmp (astate, "early") : (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) ("early"); int __result = (((const unsigned char *) (
const char *) (astate))[0] - __s2[0]); if (__s1_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (astate))[1] - __s2[1]); if (__s1_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (astate))[2] - __s2[2]); if (__s1_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (astate))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
("early") && ((size_t)(const void *)(("early") + 1) -
(size_t)(const void *)("early") == 1) && (__s2_len =
__builtin_strlen ("early"), __s2_len < 4) ? (__builtin_constant_p
(astate) && ((size_t)(const void *)((astate) + 1) - (
size_t)(const void *)(astate) == 1) ? __builtin_strcmp (astate
, "early") : (- (__extension__ ({ const unsigned char *__s2 =
(const unsigned char *) (const char *) (astate); int __result
= (((const unsigned char *) (const char *) ("early"))[0] - __s2
[0]); if (__s2_len > 0 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("early"))[1] - __s2
[1]); if (__s2_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("early"))[2] - __s2
[2]); if (__s2_len > 2 && __result == 0) __result =
(((const unsigned char *) (const char *) ("early"))[3] - __s2
[3]); } } __result; })))) : __builtin_strcmp (astate, "early"
)))); })
) {
3113 if (!zstr(op)_zstr(op)) {
3114 //switch_snprintf(status_line, sizeof(status_line), "%sing", what);
3115 //} else {
3116 if (sofia_test_pflag(profile, PFLAG_PRESENCE_PRIVACY)((profile)->pflags[PFLAG_PRESENCE_PRIVACY] ? 1 : 0)) {
3117 switch_snprintf(status_line, sizeof(status_line), "%s", what);
3118 } else {
3119 switch_snprintf(status_line, sizeof(status_line), "%s %s", what, op);
3120 }
3121 }
3122
3123 rpid = "on-the-phone";
3124 force_status = 1;
3125
3126 } else if (!strcmp(astate, "confirmed")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(astate) && __builtin_constant_p ("confirmed") &&
(__s1_len = __builtin_strlen (astate), __s2_len = __builtin_strlen
("confirmed"), (!((size_t)(const void *)((astate) + 1) - (size_t
)(const void *)(astate) == 1) || __s1_len >= 4) &&
(!((size_t)(const void *)(("confirmed") + 1) - (size_t)(const
void *)("confirmed") == 1) || __s2_len >= 4)) ? __builtin_strcmp
(astate, "confirmed") : (__builtin_constant_p (astate) &&
((size_t)(const void *)((astate) + 1) - (size_t)(const void *
)(astate) == 1) && (__s1_len = __builtin_strlen (astate
), __s1_len < 4) ? (__builtin_constant_p ("confirmed") &&
((size_t)(const void *)(("confirmed") + 1) - (size_t)(const void
*)("confirmed") == 1) ? __builtin_strcmp (astate, "confirmed"
) : (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) ("confirmed"); int __result = (((const
unsigned char *) (const char *) (astate))[0] - __s2[0]); if (
__s1_len > 0 && __result == 0) { __result = (((const
unsigned char *) (const char *) (astate))[1] - __s2[1]); if (
__s1_len > 1 && __result == 0) { __result = (((const
unsigned char *) (const char *) (astate))[2] - __s2[2]); if (
__s1_len > 2 && __result == 0) __result = (((const
unsigned char *) (const char *) (astate))[3] - __s2[3]); } }
__result; }))) : (__builtin_constant_p ("confirmed") &&
((size_t)(const void *)(("confirmed") + 1) - (size_t)(const void
*)("confirmed") == 1) && (__s2_len = __builtin_strlen
("confirmed"), __s2_len < 4) ? (__builtin_constant_p (astate
) && ((size_t)(const void *)((astate) + 1) - (size_t)
(const void *)(astate) == 1) ? __builtin_strcmp (astate, "confirmed"
) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (astate); int __result = (((const unsigned
char *) (const char *) ("confirmed"))[0] - __s2[0]); if (__s2_len
> 0 && __result == 0) { __result = (((const unsigned
char *) (const char *) ("confirmed"))[1] - __s2[1]); if (__s2_len
> 1 && __result == 0) { __result = (((const unsigned
char *) (const char *) ("confirmed"))[2] - __s2[2]); if (__s2_len
> 2 && __result == 0) __result = (((const unsigned
char *) (const char *) ("confirmed"))[3] - __s2[3]); } } __result
; })))) : __builtin_strcmp (astate, "confirmed")))); })
) {
3127 if (!zstr(op)_zstr(op)) {
3128 if (sofia_test_pflag(profile, PFLAG_PRESENCE_PRIVACY)((profile)->pflags[PFLAG_PRESENCE_PRIVACY] ? 1 : 0)) {
3129 switch_snprintf(status_line, sizeof(status_line), "On The Phone");
3130 } else {
3131 switch_snprintf(status_line, sizeof(status_line), "Talk %s", op);
3132 }
3133 } else {
3134 switch_snprintf(status_line, sizeof(status_line), "On The Phone");
3135 }
3136
3137 rpid = "on-the-phone";
3138 force_status = 1;
3139 } else if (!strcmp(astate, "terminated")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(astate) && __builtin_constant_p ("terminated") &&
(__s1_len = __builtin_strlen (astate), __s2_len = __builtin_strlen
("terminated"), (!((size_t)(const void *)((astate) + 1) - (size_t
)(const void *)(astate) == 1) || __s1_len >= 4) &&
(!((size_t)(const void *)(("terminated") + 1) - (size_t)(const
void *)("terminated") == 1) || __s2_len >= 4)) ? __builtin_strcmp
(astate, "terminated") : (__builtin_constant_p (astate) &&
((size_t)(const void *)((astate) + 1) - (size_t)(const void *
)(astate) == 1) && (__s1_len = __builtin_strlen (astate
), __s1_len < 4) ? (__builtin_constant_p ("terminated") &&
((size_t)(const void *)(("terminated") + 1) - (size_t)(const
void *)("terminated") == 1) ? __builtin_strcmp (astate, "terminated"
) : (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) ("terminated"); int __result = (((const
unsigned char *) (const char *) (astate))[0] - __s2[0]); if (
__s1_len > 0 && __result == 0) { __result = (((const
unsigned char *) (const char *) (astate))[1] - __s2[1]); if (
__s1_len > 1 && __result == 0) { __result = (((const
unsigned char *) (const char *) (astate))[2] - __s2[2]); if (
__s1_len > 2 && __result == 0) __result = (((const
unsigned char *) (const char *) (astate))[3] - __s2[3]); } }
__result; }))) : (__builtin_constant_p ("terminated") &&
((size_t)(const void *)(("terminated") + 1) - (size_t)(const
void *)("terminated") == 1) && (__s2_len = __builtin_strlen
("terminated"), __s2_len < 4) ? (__builtin_constant_p (astate
) && ((size_t)(const void *)((astate) + 1) - (size_t)
(const void *)(astate) == 1) ? __builtin_strcmp (astate, "terminated"
) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (astate); int __result = (((const unsigned
char *) (const char *) ("terminated"))[0] - __s2[0]); if (__s2_len
> 0 && __result == 0) { __result = (((const unsigned
char *) (const char *) ("terminated"))[1] - __s2[1]); if (__s2_len
> 1 && __result == 0) { __result = (((const unsigned
char *) (const char *) ("terminated"))[2] - __s2[2]); if (__s2_len
> 2 && __result == 0) __result = (((const unsigned
char *) (const char *) ("terminated"))[3] - __s2[3]); } } __result
; })))) : __builtin_strcmp (astate, "terminated")))); })
|| !strcmp(astate, "hangup")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(astate) && __builtin_constant_p ("hangup") &&
(__s1_len = __builtin_strlen (astate), __s2_len = __builtin_strlen
("hangup"), (!((size_t)(const void *)((astate) + 1) - (size_t
)(const void *)(astate) == 1) || __s1_len >= 4) &&
(!((size_t)(const void *)(("hangup") + 1) - (size_t)(const void
*)("hangup") == 1) || __s2_len >= 4)) ? __builtin_strcmp (
astate, "hangup") : (__builtin_constant_p (astate) &&
((size_t)(const void *)((astate) + 1) - (size_t)(const void *
)(astate) == 1) && (__s1_len = __builtin_strlen (astate
), __s1_len < 4) ? (__builtin_constant_p ("hangup") &&
((size_t)(const void *)(("hangup") + 1) - (size_t)(const void
*)("hangup") == 1) ? __builtin_strcmp (astate, "hangup") : (
__extension__ ({ const unsigned char *__s2 = (const unsigned char
*) (const char *) ("hangup"); int __result = (((const unsigned
char *) (const char *) (astate))[0] - __s2[0]); if (__s1_len
> 0 && __result == 0) { __result = (((const unsigned
char *) (const char *) (astate))[1] - __s2[1]); if (__s1_len
> 1 && __result == 0) { __result = (((const unsigned
char *) (const char *) (astate))[2] - __s2[2]); if (__s1_len
> 2 && __result == 0) __result = (((const unsigned
char *) (const char *) (astate))[3] - __s2[3]); } } __result
; }))) : (__builtin_constant_p ("hangup") && ((size_t
)(const void *)(("hangup") + 1) - (size_t)(const void *)("hangup"
) == 1) && (__s2_len = __builtin_strlen ("hangup"), __s2_len
< 4) ? (__builtin_constant_p (astate) && ((size_t
)(const void *)((astate) + 1) - (size_t)(const void *)(astate
) == 1) ? __builtin_strcmp (astate, "hangup") : (- (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) (astate); int __result = (((const unsigned char *) (
const char *) ("hangup"))[0] - __s2[0]); if (__s2_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) ("hangup"))[1] - __s2[1]); if (__s2_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) ("hangup"))[2] - __s2[2]); if (__s2_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) ("hangup"))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp
(astate, "hangup")))); })
) {
3140 //rpid = "online";
3141 //dialog_rpid = "";
3142 //force_event_status = "Available";
3143 term = 1;
3144 }
3145
3146 if (!term && !strcmp(status, "hold")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(status) && __builtin_constant_p ("hold") &&
(__s1_len = __builtin_strlen (status), __s2_len = __builtin_strlen
("hold"), (!((size_t)(const void *)((status) + 1) - (size_t)
(const void *)(status) == 1) || __s1_len >= 4) && (
!((size_t)(const void *)(("hold") + 1) - (size_t)(const void *
)("hold") == 1) || __s2_len >= 4)) ? __builtin_strcmp (status
, "hold") : (__builtin_constant_p (status) && ((size_t
)(const void *)((status) + 1) - (size_t)(const void *)(status
) == 1) && (__s1_len = __builtin_strlen (status), __s1_len
< 4) ? (__builtin_constant_p ("hold") && ((size_t
)(const void *)(("hold") + 1) - (size_t)(const void *)("hold"
) == 1) ? __builtin_strcmp (status, "hold") : (__extension__ (
{ const unsigned char *__s2 = (const unsigned char *) (const char
*) ("hold"); int __result = (((const unsigned char *) (const
char *) (status))[0] - __s2[0]); if (__s1_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (status))[1] - __s2[1]); if (__s1_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (status))[2] - __s2[2]); if (__s1_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (status))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
("hold") && ((size_t)(const void *)(("hold") + 1) - (
size_t)(const void *)("hold") == 1) && (__s2_len = __builtin_strlen
("hold"), __s2_len < 4) ? (__builtin_constant_p (status) &&
((size_t)(const void *)((status) + 1) - (size_t)(const void *
)(status) == 1) ? __builtin_strcmp (status, "hold") : (- (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) (status); int __result = (((const unsigned char *) (
const char *) ("hold"))[0] - __s2[0]); if (__s2_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) ("hold"))[1] - __s2[1]); if (__s2_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) ("hold"))[2] - __s2[2]); if (__s2_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) ("hold"))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp
(status, "hold")))); })
) {
3147 rpid = "on-the-phone";
3148 if (!zstr(op)_zstr(op)) {
3149 if (sofia_test_pflag(profile, PFLAG_PRESENCE_PRIVACY)((profile)->pflags[PFLAG_PRESENCE_PRIVACY] ? 1 : 0)) {
3150 switch_snprintf(status_line, sizeof(status_line), "Hold");
3151 } else {
3152 switch_snprintf(status_line, sizeof(status_line), "Hold %s", op);
3153 }
3154 force_status = 1;
3155 }
3156 }
3157 }
3158 } else {
3159 open = "closed";
3160 }
3161
3162 if (!zstr(open_closed)_zstr(open_closed)) {
3163 open = open_closed;
3164 }
3165
3166 prpid = translate_rpid(rpid);
3167
3168 if (!zstr(dialog_status)_zstr(dialog_status) && !force_status) {
3169 status = dialog_status;
3170 switch_set_string(status_line, status)switch_copy_string(status_line, status, sizeof(status_line));
3171 }
3172
3173 if (!zstr(force_event_status)_zstr(force_event_status)) {
3174 switch_set_string(status_line, force_event_status)switch_copy_string(status_line, force_event_status, sizeof(status_line
))
;
3175 }
3176
3177 if (!zstr(dialog_rpid)_zstr(dialog_rpid)) {
3178 prpid = rpid = dialog_rpid;
3179 }
3180
3181 contact_stripped = sofia_glue_strip_uri(contact_str);
3182 pl = gen_pidf(user_agent, clean_id, contact_stripped, open, rpid, prpid, status_line, &ct);
3183 free(contact_stripped);
3184 }
3185
3186 } else {
3187 if (in) {
3188 open = "open";
3189 } else {
3190 open = "closed";
3191 }
3192
3193 if (!zstr(open_closed)_zstr(open_closed)) {
3194 open = open_closed;
3195 }
3196
3197 prpid = translate_rpid(rpid);
3198
3199 if (!zstr(dialog_status)_zstr(dialog_status)) {
3200 status = dialog_status;
3201 }
3202
3203 if (!zstr(dialog_rpid)_zstr(dialog_rpid)) {
3204 prpid = rpid = dialog_rpid;
3205 }
3206
3207 contact_stripped = sofia_glue_strip_uri(contact_str);
3208 pl = gen_pidf(user_agent, clean_id, contact_stripped, open, rpid, prpid, status, &ct);
3209 free(contact_stripped);
3210 }
3211
3212
3213 if (!is_dialog && helper->event && !switch_stristr("registered", status_line)){
3214 const char *uuid = switch_event_get_header_nil(helper->event, "unique-id")(switch_event_get_header_idx(helper->event, "unique-id", -
1) ? switch_event_get_header_idx(helper->event, "unique-id"
, -1) : "")
;
3215 const char *register_source = switch_event_get_header_nil(helper->event, "register-source")(switch_event_get_header_idx(helper->event, "register-source"
, -1) ? switch_event_get_header_idx(helper->event, "register-source"
, -1) : "")
;
3216
3217 if (!zstr(uuid)_zstr(uuid) && strchr(uuid, '-')(__extension__ (__builtin_constant_p ('-') && !__builtin_constant_p
(uuid) && ('-') == '\0' ? (char *) __rawmemchr (uuid
, '-') : __builtin_strchr (uuid, '-')))
&& !zstr(status_line)_zstr(status_line) && !zstr(rpid)_zstr(rpid) && (zstr(register_source)_zstr(register_source) || strcasecmp(register_source, "register"))) {
3218 char *sql = switch_mprintf("update sip_dialogs set rpid='%q',status='%q' where hostname='%q' and profile_name='%q' and uuid='%q'",
3219 rpid, status_line,
3220 mod_sofia_globals.hostname, profile->name, uuid);
3221 sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
3222 }
3223 }
3224
3225 send_presence_notify(profile, full_to, full_from, contact, expires, call_id, event, ip, port, ct, pl, NULL)_send_presence_notify(profile,full_to,full_from,contact,expires
,call_id,event,ip,port,ct,pl,((void*)0),"sofia_presence.c", (
const char *)__func__, 3225)
;
3226
3227
3228 end:
3229
3230 switch_safe_free(free_me)if (free_me) {free(free_me);free_me=((void*)0);};
3231
3232 if (ext_profile) {
3233 sofia_glue_release_profile(ext_profile)sofia_glue_release_profile__("sofia_presence.c", (const char *
)__func__, 3233, ext_profile)
;
3234 }
3235
3236 switch_safe_free(id)if (id) {free(id);id=((void*)0);};
3237 switch_safe_free(clean_id)if (clean_id) {free(clean_id);clean_id=((void*)0);};
3238 switch_safe_free(pl)if (pl) {free(pl);pl=((void*)0);};
3239 switch_safe_free(to)if (to) {free(to);to=((void*)0);};
3240
3241 return 0;
3242}
3243
3244static int sofia_presence_mwi_callback(void *pArg, int argc, char **argv, char **columnNames)
3245{
3246 //char *sub_to_user = argv[3];
3247 //char *sub_to_host = argv[4];
3248 char *event = argv[5];
3249 char *contact = argv[6];
3250 char *call_id = argv[7];
3251 char *full_from = argv[8];
3252 char *expires = argv[10];
3253 char *profile_name = argv[13];
3254 char *body = argv[15];
3255 char *full_to = argv[16];
3256 char *remote_ip = argv[17];
3257 char *remote_port = argv[18];
3258
3259 struct mwi_helper *h = (struct mwi_helper *) pArg;
3260 sofia_profile_t *ext_profile = NULL((void*)0), *profile = h->profile;
3261
3262
3263 if (mod_sofia_globals.debug_presence > 0) {
3264 int i;
3265 for(i = 0; i < argc; i++) {
3266 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 3266, ((void*)0)
, SWITCH_LOG_CRIT, "arg %d[%s] = [%s]\n", i, columnNames[i], argv[i]);
3267 }
3268 }
3269
3270 if (profile_name && strcasecmp(profile_name, h->profile->name)) {
3271 if ((ext_profile = sofia_glue_find_profile(profile_name)sofia_glue_find_profile__("sofia_presence.c", (const char *)__func__
, 3271, profile_name)
)) {
3272 profile = ext_profile;
3273 }
3274 }
3275
3276 send_presence_notify(profile,_send_presence_notify(profile,full_to,full_from,contact,expires
,call_id,event,remote_ip,remote_port,"application/simple-message-summary"
,body,((void*)0),"sofia_presence.c", (const char *)__func__, 3288
)
3277 full_to,_send_presence_notify(profile,full_to,full_from,contact,expires
,call_id,event,remote_ip,remote_port,"application/simple-message-summary"
,body,((void*)0),"sofia_presence.c", (const char *)__func__, 3288
)
3278 full_from,_send_presence_notify(profile,full_to,full_from,contact,expires
,call_id,event,remote_ip,remote_port,"application/simple-message-summary"
,body,((void*)0),"sofia_presence.c", (const char *)__func__, 3288
)
3279 contact,_send_presence_notify(profile,full_to,full_from,contact,expires
,call_id,event,remote_ip,remote_port,"application/simple-message-summary"
,body,((void*)0),"sofia_presence.c", (const char *)__func__, 3288
)
3280 expires,_send_presence_notify(profile,full_to,full_from,contact,expires
,call_id,event,remote_ip,remote_port,"application/simple-message-summary"
,body,((void*)0),"sofia_presence.c", (const char *)__func__, 3288
)
3281 call_id,_send_presence_notify(profile,full_to,full_from,contact,expires
,call_id,event,remote_ip,remote_port,"application/simple-message-summary"
,body,((void*)0),"sofia_presence.c", (const char *)__func__, 3288
)
3282 event,_send_presence_notify(profile,full_to,full_from,contact,expires
,call_id,event,remote_ip,remote_port,"application/simple-message-summary"
,body,((void*)0),"sofia_presence.c", (const char *)__func__, 3288
)
3283 remote_ip,_send_presence_notify(profile,full_to,full_from,contact,expires
,call_id,event,remote_ip,remote_port,"application/simple-message-summary"
,body,((void*)0),"sofia_presence.c", (const char *)__func__, 3288
)
3284 remote_port,_send_presence_notify(profile,full_to,full_from,contact,expires
,call_id,event,remote_ip,remote_port,"application/simple-message-summary"
,body,((void*)0),"sofia_presence.c", (const char *)__func__, 3288
)
3285 "application/simple-message-summary",_send_presence_notify(profile,full_to,full_from,contact,expires
,call_id,event,remote_ip,remote_port,"application/simple-message-summary"
,body,((void*)0),"sofia_presence.c", (const char *)__func__, 3288
)
3286 body,_send_presence_notify(profile,full_to,full_from,contact,expires
,call_id,event,remote_ip,remote_port,"application/simple-message-summary"
,body,((void*)0),"sofia_presence.c", (const char *)__func__, 3288
)
3287 NULL_send_presence_notify(profile,full_to,full_from,contact,expires
,call_id,event,remote_ip,remote_port,"application/simple-message-summary"
,body,((void*)0),"sofia_presence.c", (const char *)__func__, 3288
)
3288 )_send_presence_notify(profile,full_to,full_from,contact,expires
,call_id,event,remote_ip,remote_port,"application/simple-message-summary"
,body,((void*)0),"sofia_presence.c", (const char *)__func__, 3288
)
;
3289
3290
3291 h->total++;
3292
3293 if (ext_profile) {
3294 sofia_glue_release_profile(ext_profile)sofia_glue_release_profile__("sofia_presence.c", (const char *
)__func__, 3294, ext_profile)
;
3295 }
3296
3297 return 0;
3298}
3299
3300static int sofia_presence_mwi_callback2(void *pArg, int argc, char **argv, char **columnNames)
3301{
3302 const char *user = argv[0];
3303 const char *host = argv[1];
3304 const char *event = "message-summary";
3305 const char *contenttype = "application/simple-message-summary";
3306 const char *body = argv[5];
3307 const char *o_contact = argv[2];
3308 const char *network_ip = argv[4];
3309 const char *call_id = argv[6];
3310
3311 char *profile_name = argv[3];
3312 struct mwi_helper *h = (struct mwi_helper *) pArg;
3313 sofia_profile_t *ext_profile = NULL((void*)0), *profile = h->profile;
3314
3315 if (profile_name && strcasecmp(profile_name, h->profile->name)) {
3316 if ((ext_profile = sofia_glue_find_profile(profile_name)sofia_glue_find_profile__("sofia_presence.c", (const char *)__func__
, 3316, profile_name)
)) {
3317 profile = ext_profile;
3318 }
3319 }
3320
3321 if (!sofia_test_pflag(profile, PFLAG_MWI_USE_REG_CALLID)((profile)->pflags[PFLAG_MWI_USE_REG_CALLID] ? 1 : 0)) {
3322 call_id = NULL((void*)0);
3323 }
3324
3325 sofia_glue_send_notify(profile, user, host, event, contenttype, body, o_contact, network_ip, call_id);
3326
3327 if (ext_profile) {
3328 sofia_glue_release_profile(ext_profile)sofia_glue_release_profile__("sofia_presence.c", (const char *
)__func__, 3328, ext_profile)
;
3329 }
3330
3331 return 0;
3332}
3333
3334static int broadsoft_sla_notify_callback(void *pArg, int argc, char **argv, char **columnNames)
3335{
3336 struct state_helper *sh = (struct state_helper *) pArg;
3337 char key[256] = "";
3338 char *data = NULL((void*)0), *tmp;
3339 char *call_id = argv[0];
3340 //char *expires = argv[1];
3341 char *user = argv[2];
3342 char *host = argv[3];
3343 char *event = argv[4];
3344 int i;
3345
3346
3347 if (mod_sofia_globals.debug_sla > 1) {
3348 for (i = 0; i < argc; i++) {
3349 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 3349, ((void*)0)
, SWITCH_LOG_ERROR, "SLA3: %d [%s]=[%s]\n", i, columnNames[i], argv[i]);
3350 }
3351 }
3352
3353 switch_snprintf(key, sizeof(key), "%s%s", user, host);
3354 data = switch_core_hash_find(sh->hash, key);
3355
3356 if (data) {
3357 tmp = switch_core_sprintf(sh->pool, "%s,<sip:%s>;appearance-index=*;appearance-state=idle", data, host);
3358 } else {
3359 tmp = switch_core_sprintf(sh->pool, "<sip:%s>;appearance-index=*;appearance-state=idle", host);
3360 }
3361
3362
3363 if (!strcasecmp(event, "line-seize")) {
3364 char *hack;
3365
3366 if ((hack = (char *) switch_stristr("=seized", tmp))) {
3367 switch_snprintf(hack, 7, "=idle ");
3368 }
3369 }
3370
3371 if (mod_sofia_globals.debug_sla > 1) {
3372 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 3372, ((void*)0)
, SWITCH_LOG_ERROR, "DB PRES NOTIFY: [%s]\n[%s]\n[%s]\n[%s]\n[%s]\n[%s]\n[%s]\n[%s]\n[%s]\n",
3373 argv[5], argv[6], argv[7], argv[8], call_id, event, argv[9], argv[10], tmp);
3374
3375 }
3376
3377 send_presence_notify(sh->profile, argv[5], argv[6], argv[7], argv[8], call_id, event, argv[9], argv[10], NULL, NULL, tmp)_send_presence_notify(sh->profile,argv[5],argv[6],argv[7],
argv[8],call_id,event,argv[9],argv[10],((void*)0),((void*)0),
tmp,"sofia_presence.c", (const char *)__func__, 3377)
;
3378
3379 sh->total++;
3380
3381 return 0;
3382}
3383
3384static int broadsoft_sla_gather_state_callback(void *pArg, int argc, char **argv, char **columnNames)
3385{
3386 struct state_helper *sh = (struct state_helper *) pArg;
3387 char key[256] = "";
3388 switch_core_session_t *session;
3389 const char *callee_name = NULL((void*)0), *callee_number = NULL((void*)0);
3390 char *data = NULL((void*)0), *tmp;
3391 char *user = argv[0];
3392 char *host = argv[1];
3393 char *info = argv[2];
3394 char *state = argv[3];
3395 char *uuid = argv[4];
3396 int i;
3397
3398 if (mod_sofia_globals.debug_sla > 1) {
3399 for (i = 0; i < argc; i++) {
3400 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 3400, ((void*)0)
, SWITCH_LOG_ERROR, "SLA2: %d [%s]=[%s]\n", i, columnNames[i], argv[i]);
3401 }
3402 }
3403
3404 if (zstr(info)_zstr(info)) {
3405 return 0;
3406 }
3407
3408 if (zstr(state)_zstr(state)) {
3409 state = "idle";
3410 }
3411
3412 switch_snprintf(key, sizeof(key), "%s%s", user, host);
3413
3414 data = switch_core_hash_find(sh->hash, key);
3415
3416 if (strcasecmp(state, "idle") && uuid && (session = switch_core_session_locate(uuid)switch_core_session_perform_locate(uuid, "sofia_presence.c", (
const char *)__func__, 3416)
)) {
3417 switch_channel_t *channel = switch_core_session_get_channel(session);
3418
3419 if (switch_channel_test_flag(channel, CF_ORIGINATOR) || switch_channel_test_flag(channel, CF_BRIDGE_ORIGINATOR) ||
3420 switch_channel_inbound_display(channel)((switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND
&& !switch_channel_test_flag(channel, CF_BLEG)) || (
switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND
&& switch_channel_test_flag(channel, CF_DIALPLAN)))
|| switch_channel_test_flag(channel, CF_SLA_BARGING)) {
3421 callee_name = switch_channel_get_variable(channel, "callee_id_name")switch_channel_get_variable_dup(channel, "callee_id_name", SWITCH_TRUE
, -1)
;
3422 callee_number = switch_channel_get_variable(channel, "callee_id_number")switch_channel_get_variable_dup(channel, "callee_id_number", SWITCH_TRUE
, -1)
;
3423
3424 if (zstr(callee_number)_zstr(callee_number)) {
3425 callee_number = switch_channel_get_variable(channel, "destination_number")switch_channel_get_variable_dup(channel, "destination_number"
, SWITCH_TRUE, -1)
;
3426 }
3427
3428 } else {
3429 callee_name = switch_channel_get_variable(channel, "caller_id_name")switch_channel_get_variable_dup(channel, "caller_id_name", SWITCH_TRUE
, -1)
;
3430 callee_number = switch_channel_get_variable(channel, "caller_id_number")switch_channel_get_variable_dup(channel, "caller_id_number", SWITCH_TRUE
, -1)
;
3431 }
3432
3433 if (zstr(callee_name)_zstr(callee_name) && !zstr(callee_number)_zstr(callee_number)) {
3434 callee_name = callee_number;
3435 }
3436
3437 if (!zstr(callee_number)_zstr(callee_number)) {
3438 callee_number = switch_sanitize_number(switch_core_session_strdup(session, callee_number)switch_core_perform_session_strdup(session, callee_number, "sofia_presence.c"
, (const char *)__func__, 3438)
);
3439 }
3440
3441 if (!zstr(callee_name)_zstr(callee_name)) {
3442 char *tmp = switch_core_session_strdup(session, callee_name)switch_core_perform_session_strdup(session, callee_name, "sofia_presence.c"
, (const char *)__func__, 3442)
;
3443 switch_url_decode(tmp);
3444 callee_name = switch_sanitize_number(tmp);
3445 }
3446
3447
3448 //if (switch_channel_get_state(channel) != CS_EXECUTE) {
3449 //callee_number = NULL;
3450 //}
3451
3452 switch_core_session_rwunlock(session);
3453 }
3454
3455 if (data && strstr(data, info)) {
3456 return 0;
3457 }
3458
3459
3460 if (!zstr(callee_number)_zstr(callee_number)) {
3461 if (zstr(callee_name)_zstr(callee_name)) {
3462 callee_name = "unknown";
3463 }
3464
3465 if (data) {
3466 tmp = switch_core_sprintf(sh->pool,
3467 "%s,<sip:%s>;%s;appearance-state=%s;appearance-uri=\"\\\"%s\\\" <sip:%s@%s>\"",
3468 data, host, info, state, callee_name, callee_number, host);
3469 } else {
3470 tmp = switch_core_sprintf(sh->pool,
3471 "<sip:%s>;%s;appearance-state=%s;appearance-uri=\"\\\"%s\\\" <sip:%s@%s>\"",
3472 host, info, state, callee_name, callee_number, host);
3473 }
3474 } else {
3475 if (data) {
3476 tmp = switch_core_sprintf(sh->pool, "%s,<sip:%s>;%s;appearance-state=%s", data, host, info, state);
3477 } else {
3478 tmp = switch_core_sprintf(sh->pool, "<sip:%s>;%s;appearance-state=%s", host, info, state);
3479 }
3480 }
3481
3482 switch_core_hash_insert(sh->hash, key, tmp)switch_core_hash_insert_destructor(sh->hash, key, tmp, ((void
*)0))
;
3483
3484 return 0;
3485}
3486
3487static int sync_sla(sofia_profile_t *profile, const char *to_user, const char *to_host, switch_bool_t clear, switch_bool_t unseize, const char *call_id)
3488{
3489 struct state_helper *sh;
3490 switch_memory_pool_t *pool;
3491 char *sql;
3492 int total = 0;
3493
3494
3495 if (clear) {
3496 struct pres_sql_cb cb = {profile, 0};
3497
3498
3499 if (call_id) {
3500
3501 sql = switch_mprintf("update sip_subscriptions set version=version+1,expires=%ld where "
3502 "call_id='%q' "
3503 "and event='line-seize'", (long) switch_epoch_time_now(NULL((void*)0)),
3504 call_id);
3505
3506 sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
3507
3508 if (mod_sofia_globals.debug_sla > 1) {
3509 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 3509, ((void*)0)
, SWITCH_LOG_ERROR, "CLEAR SQL %s\n", sql);
3510 }
3511 switch_safe_free(sql)if (sql) {free(sql);sql=((void*)0);};
3512
3513 sql = switch_mprintf("select full_to, full_from, contact, -1, call_id, event, network_ip, network_port, "
3514 "NULL as ct, NULL as pt "
3515 " from sip_subscriptions where call_id='%q' "
3516
3517 "and event='line-seize'", call_id);
3518
3519 sofia_glue_execute_sql_callback(profile, profile->dbh_mutex, sql, sofia_presence_send_sql, &cb);
3520 if (mod_sofia_globals.debug_sla > 1) {
3521 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 3521, ((void*)0)
, SWITCH_LOG_ERROR, "CLEAR SQL %s\n", sql);
3522 }
3523 switch_safe_free(sql)if (sql) {free(sql);sql=((void*)0);};
3524 } else {
3525
3526 sql = switch_mprintf("update sip_subscriptions set version=version+1,expires=%ld where "
3527 "hostname='%q' and profile_name='%q' "
3528 "and sub_to_user='%q' and sub_to_host='%q' "
3529
3530 "and event='line-seize'", (long) switch_epoch_time_now(NULL((void*)0)),
3531 mod_sofia_globals.hostname, profile->name, to_user, to_host
3532 );
3533
3534 if (mod_sofia_globals.debug_sla > 1) {
3535 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 3535, ((void*)0)
, SWITCH_LOG_ERROR, "CLEAR SQL %s\n", sql);
3536 }
3537
3538 sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
3539
3540
3541 sql = switch_mprintf("select full_to, full_from, contact, -1, call_id, event, network_ip, network_port, "
3542 "NULL as ct, NULL as pt "
3543 " from sip_subscriptions where "
3544 "hostname='%q' and profile_name='%q' "
3545 "and sub_to_user='%q' and sub_to_host='%q' "
3546 "and event='line-seized'",
3547 mod_sofia_globals.hostname, profile->name, to_user, to_host
3548 );
3549
3550 sofia_glue_execute_sql_callback(profile, profile->dbh_mutex, sql, sofia_presence_send_sql, &cb);
3551
3552 if (mod_sofia_globals.debug_sla > 1) {
3553 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 3553, ((void*)0)
, SWITCH_LOG_ERROR, "CLEAR SQL %s\n", sql);
3554 }
3555
3556 switch_safe_free(sql)if (sql) {free(sql);sql=((void*)0);};
3557 }
3558
3559
3560 sql = switch_mprintf("delete from sip_dialogs where hostname='%q' and profile_name='%q' and "
3561 "((sip_from_user='%q' and sip_from_host='%q') or presence_id='%q@%q') "
3562 "and call_info_state='seized'", mod_sofia_globals.hostname, profile->name, to_user, to_host, to_user, to_host);
3563
3564
3565 if (mod_sofia_globals.debug_sla > 1) {
3566 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 3566, ((void*)0)
, SWITCH_LOG_ERROR, "CLEAR SQL %s\n", sql);
3567 }
3568 sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
3569 switch_safe_free(sql)if (sql) {free(sql);sql=((void*)0);};
3570 }
3571
3572
3573 switch_core_new_memory_pool(&pool)switch_core_perform_new_memory_pool(&pool, "sofia_presence.c"
, (const char *)__func__, 3573)
;
3574 sh = switch_core_alloc(pool, sizeof(*sh))switch_core_perform_alloc(pool, sizeof(*sh), "sofia_presence.c"
, (const char *)__func__, 3574)
;
3575 sh->pool = pool;
3576 switch_core_hash_init(&sh->hash)switch_core_hash_init_case(&sh->hash, SWITCH_TRUE);
3577
3578 sql = switch_mprintf("select sip_from_user,sip_from_host,call_info,call_info_state,uuid from sip_dialogs "
3579 "where call_info_state is not null and call_info_state != '' and call_info_state != 'idle' and hostname='%q' and profile_name='%q' "
3580 "and ((sip_from_user='%q' and sip_from_host='%q') or presence_id='%q@%q') "
3581 "and profile_name='%q'",
3582 mod_sofia_globals.hostname, profile->name, to_user, to_host, to_user, to_host, profile->name);
3583
3584
3585 if (mod_sofia_globals.debug_sla > 1) {
3586 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 3586, ((void*)0)
, SWITCH_LOG_ERROR, "PRES SQL %s\n", sql);
3587 }
3588 sofia_glue_execute_sql_callback(profile, profile->dbh_mutex, sql, broadsoft_sla_gather_state_callback, sh);
3589 switch_safe_free(sql)if (sql) {free(sql);sql=((void*)0);};
3590
3591
3592 if (!zstr(call_id)_zstr(call_id)) {
3593
3594 if (unseize) {
3595 sql = switch_mprintf("select call_id,expires,sub_to_user,sub_to_host,event,full_to,full_from,contact,expires,network_ip,network_port "
3596 "from sip_subscriptions where call_id='%q' and hostname='%q' and profile_name='%q' "
3597 "and (event='call-info' or event='line-seize')",
3598 call_id, mod_sofia_globals.hostname, profile->name);
3599
3600 } else {
3601 sql = switch_mprintf("select call_id,expires,sub_to_user,sub_to_host,event,full_to,full_from,contact,expires,network_ip,network_port "
3602 "from sip_subscriptions where call_id='%q' and hostname='%q' and profile_name='%q' and event='call-info'",
3603 call_id, mod_sofia_globals.hostname, profile->name);
3604 }
3605
3606 } else {
3607
3608 if (unseize) {
3609 sql = switch_mprintf("select call_id,expires,sub_to_user,sub_to_host,event,full_to,full_from,contact,expires,network_ip,network_port "
3610 "from sip_subscriptions "
3611 "where hostname='%q' and profile_name='%q' "
3612 "and sub_to_user='%q' and sub_to_host='%q' "
3613 "and (event='call-info' or event='line-seize') and (profile_name='%q' or presence_hosts like '%%%q%%')",
3614 mod_sofia_globals.hostname, profile->name, to_user, to_host, profile->name, to_host);
3615 } else {
3616 sql = switch_mprintf("select call_id,expires,sub_to_user,sub_to_host,event,full_to,full_from,contact,expires,network_ip,network_port "
3617 "from sip_subscriptions "
3618 "where hostname='%q' and profile_name='%q' "
3619 "and sub_to_user='%q' and sub_to_host='%q' " "and (event='call-info') and "
3620 "(profile_name='%q' or presence_hosts like '%%%q%%')",
3621 mod_sofia_globals.hostname, profile->name, to_user, to_host, profile->name, to_host);
3622 }
3623 }
3624
3625 if (mod_sofia_globals.debug_sla > 1) {
3626 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 3626, ((void*)0)
, SWITCH_LOG_ERROR, "PRES SQL %s\n", sql);
3627 }
3628
3629 sh->profile = profile;
3630 sofia_glue_execute_sql_callback(profile, profile->dbh_mutex, sql, broadsoft_sla_notify_callback, sh);
3631 switch_safe_free(sql)if (sql) {free(sql);sql=((void*)0);};
3632 total = sh->total;
3633 sh = NULL((void*)0);
3634 switch_core_destroy_memory_pool(&pool)switch_core_perform_destroy_memory_pool(&pool, "sofia_presence.c"
, (const char *)__func__, 3634)
;
3635
3636
3637
3638
3639
3640 return total;
3641
3642}
3643
3644void sofia_presence_handle_sip_i_subscribe(int status,
3645 char const *phrase,
3646 nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
3647 sofia_dispatch_event_t *de,
3648 tagi_t tags[])
3649{
3650
3651 long exp_delta = 0;
3652 char exp_delta_str[30] = "";
3653 uint32_t sub_max_deviation_var = 0;
3654 sip_to_t const *to;
3655 const char *from_user = NULL((void*)0), *from_host = NULL((void*)0);
3656 const char *to_user = NULL((void*)0), *to_host = NULL((void*)0);
3657 char *my_to_user = NULL((void*)0);
3658 char *sql, *event = NULL((void*)0);
3659 char *proto = "sip";
3660 char *orig_proto = "";
3661 char *alt_proto = NULL((void*)0);
3662 char *d_user = NULL((void*)0);
3663 char *contact_str = "";
3664 const char *call_id = NULL((void*)0);
3665 char *to_str = NULL((void*)0);
3666 char *full_from = NULL((void*)0);
3667 char *full_to = NULL((void*)0);
3668 char *full_via = NULL((void*)0);
3669 char *full_agent = NULL((void*)0);
3670 char *sstr;
3671 switch_event_t *sevent;
3672 int sub_state = nua_substate_pending;
3673 int sent_reply = 0;
3674 sip_contact_t const *contact;
3675 const char *ipv6;
3676 const char *contact_user = NULL((void*)0);
3677 const char *contact_host = NULL((void*)0);
3678 const char *contact_port = NULL((void*)0);
3679 sofia_nat_parse_t np = { { 0 } };
3680 int found_proto = 0;
3681 const char *use_to_tag;
3682 char to_tag[13] = "";
3683 char buf[1025] = "";
3684 char *orig_to_user = NULL((void*)0);
3685 char *p;
3686
3687 if (!sip) {
3688 return;
3689 }
3690
3691 to = sip->sip_to;
3692 contact = sip->sip_contact;
3693
3694 np.fs_path = 1;
3695 if (!(contact_str = sofia_glue_gen_contact_str(profile, sip, nh, de, &np))) {
3696 nua_respond(nh, 481, "INVALID SUBSCRIPTION", TAG_END()(tag_type_t)0, (tag_value_t)0);
3697 return;
3698 }
3699
3700 if (sip->sip_to && sip->sip_to->a_tag) {
3701 use_to_tag = sip->sip_to->a_tag;
3702 } else {
3703 switch_stun_random_string(to_tag, 12, NULL((void*)0));
3704 use_to_tag = to_tag;
3705 }
3706
3707 if ( sip->sip_contact && sip->sip_contact->m_url ) {
3708 contact_host = sip->sip_contact->m_url->url_host;
3709 contact_port = sip->sip_contact->m_url->url_port;
3710 contact_user = sip->sip_contact->m_url->url_user;
3711 }
3712
3713 full_agent = sip_header_as_string(nh->nh_home, (void *) sip->sip_user_agent);
3714
3715 //tl_gets(tags, NUTAG_SUBSTATE_REF(sub_state), TAG_END());
3716
3717 //sip->sip_subscription_state->ss_substate
3718
3719 if (sip->sip_subscription_state && sip->sip_subscription_state->ss_substate) {
3720 if (switch_stristr("terminated", sip->sip_subscription_state->ss_substate)) {
3721 sub_state = nua_substate_terminated;
3722 } else if (switch_stristr("active", sip->sip_subscription_state->ss_substate)) {
3723 sub_state = nua_substate_active;
3724 }
3725 }
3726
3727 event = sip_header_as_string(nh->nh_home, (void *) sip->sip_event);
3728
3729 if (to) {
3730 to_str = switch_mprintf("sip:%s@%s", to->a_url->url_user, to->a_url->url_host);
3731 }
3732
3733 if (to) {
3734 to_user = to->a_url->url_user;
3735 to_host = to->a_url->url_host;
3736 }
3737
3738 if (profile->sub_domain) {
3739 to_host = profile->sub_domain;
3740 }
3741
3742 if (sip->sip_from) {
3743 from_user = sip->sip_from->a_url->url_user;
3744 from_host = sip->sip_from->a_url->url_host;
3745 } else {
3746 from_user = "n/a";
3747 from_host = "n/a";
3748 }
3749
3750 if ((exp_delta = sip->sip_expires ? sip->sip_expires->ex_delta : 3600)) {
3751 if ((profile->force_subscription_expires > 0) && (profile->force_subscription_expires < (uint32_t)exp_delta)) {
3752 exp_delta = profile->force_subscription_expires;
3753 }
3754 }
3755
3756 if ((sub_max_deviation_var = profile->sip_subscription_max_deviation)) {
3757 if (sub_max_deviation_var > 0) {
3758 int sub_deviation;
3759 srand( (unsigned) ( (unsigned)(intptr_t)switch_thread_self() + switch_micro_time_now() ) );
3760 /* random negative number between 0 and negative sub_max_deviation_var: */
3761 sub_deviation = ( rand() % sub_max_deviation_var ) - sub_max_deviation_var;
3762 if ( (exp_delta + sub_deviation) > 45 ) {
3763 exp_delta += sub_deviation;
3764 }
3765 }
3766 }
3767
3768 if (mod_sofia_globals.debug_presence > 0 || mod_sofia_globals.debug_sla > 0) {
3769 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 3769, ((void*)0)
, SWITCH_LOG_ERROR, "DELTA %ld\n", exp_delta);
3770 }
3771
3772 if (!exp_delta) {
3773 sub_state = nua_substate_terminated;
3774 }
3775
3776 switch_snprintf(exp_delta_str, sizeof(exp_delta_str), "%ld", exp_delta);
3777
3778 if (!strcmp("as-feature-event", event)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
("as-feature-event") && __builtin_constant_p (event)
&& (__s1_len = __builtin_strlen ("as-feature-event")
, __s2_len = __builtin_strlen (event), (!((size_t)(const void
*)(("as-feature-event") + 1) - (size_t)(const void *)("as-feature-event"
) == 1) || __s1_len >= 4) && (!((size_t)(const void
*)((event) + 1) - (size_t)(const void *)(event) == 1) || __s2_len
>= 4)) ? __builtin_strcmp ("as-feature-event", event) : (
__builtin_constant_p ("as-feature-event") && ((size_t
)(const void *)(("as-feature-event") + 1) - (size_t)(const void
*)("as-feature-event") == 1) && (__s1_len = __builtin_strlen
("as-feature-event"), __s1_len < 4) ? (__builtin_constant_p
(event) && ((size_t)(const void *)((event) + 1) - (size_t
)(const void *)(event) == 1) ? __builtin_strcmp ("as-feature-event"
, event) : (__extension__ ({ const unsigned char *__s2 = (const
unsigned char *) (const char *) (event); int __result = (((const
unsigned char *) (const char *) ("as-feature-event"))[0] - __s2
[0]); if (__s1_len > 0 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("as-feature-event"
))[1] - __s2[1]); if (__s1_len > 1 && __result == 0
) { __result = (((const unsigned char *) (const char *) ("as-feature-event"
))[2] - __s2[2]); if (__s1_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) ("as-feature-event"
))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p (
event) && ((size_t)(const void *)((event) + 1) - (size_t
)(const void *)(event) == 1) && (__s2_len = __builtin_strlen
(event), __s2_len < 4) ? (__builtin_constant_p ("as-feature-event"
) && ((size_t)(const void *)(("as-feature-event") + 1
) - (size_t)(const void *)("as-feature-event") == 1) ? __builtin_strcmp
("as-feature-event", event) : (- (__extension__ ({ const unsigned
char *__s2 = (const unsigned char *) (const char *) ("as-feature-event"
); int __result = (((const unsigned char *) (const char *) (event
))[0] - __s2[0]); if (__s2_len > 0 && __result == 0
) { __result = (((const unsigned char *) (const char *) (event
))[1] - __s2[1]); if (__s2_len > 1 && __result == 0
) { __result = (((const unsigned char *) (const char *) (event
))[2] - __s2[2]); if (__s2_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) (event)
)[3] - __s2[3]); } } __result; })))) : __builtin_strcmp ("as-feature-event"
, event)))); })
) {
3779 sip_authorization_t const *authorization = NULL((void*)0);
3780 auth_res_t auth_res = AUTH_FORBIDDEN;
3781 char key[128] = "";
3782 switch_event_t *v_event = NULL((void*)0);
3783
3784
3785 if (sip->sip_authorization) {
3786 authorization = sip->sip_authorization;
3787 } else if (sip->sip_proxy_authorization) {
3788 authorization = sip->sip_proxy_authorization;
3789 }
3790
3791 if (authorization) {
3792 char network_ip[80];
3793 int network_port;
3794 sofia_glue_get_addr(de->data->e_msg, network_ip, sizeof(network_ip), &network_port);
3795 auth_res = sofia_reg_parse_auth(profile, authorization, sip, de,
3796 (char *) sip->sip_request->rq_method_name, key, sizeof(key), network_ip, network_port, &v_event, 0,
3797 REG_REGISTER, to_user, NULL((void*)0), NULL((void*)0), NULL((void*)0));
3798 if (v_event) switch_event_destroy(&v_event);
3799 } else if (sofia_reg_handle_register(nua, profile, nh, sip, de, REG_REGISTER, key, sizeof(key), &v_event, NULL, NULL, NULL)sofia_reg_handle_register_token(nua, profile, nh, sip, de, REG_REGISTER
, key, sizeof(key), &v_event, ((void*)0), ((void*)0), ((void
*)0), ((void*)0))
) {
3800 if (v_event) switch_event_destroy(&v_event);
3801 goto end;
3802 }
3803
3804 if ((auth_res != AUTH_OK && auth_res != AUTH_RENEWED)) {
3805 nua_respond(nh, SIP_401_UNAUTHORIZED401, sip_401_Unauthorized, NUTAG_WITH_THIS_MSG(de->data->e_msg)nutag_with, tag_ptr_v(de->data->e_msg), TAG_END()(tag_type_t)0, (tag_value_t)0);
3806 goto end;
3807 }
3808 } else if (sofia_test_pflag(profile, PFLAG_AUTH_SUBSCRIPTIONS)((profile)->pflags[PFLAG_AUTH_SUBSCRIPTIONS] ? 1 : 0)) {
3809 sip_authorization_t const *authorization = NULL((void*)0);
3810 auth_res_t auth_res = AUTH_FORBIDDEN;
3811 char keybuf[128] = "";
3812 char *key;
3813 size_t keylen;
3814 switch_event_t *v_event = NULL((void*)0);
3815
3816 key = keybuf;
3817 keylen = sizeof(keybuf);
3818
3819 if (sip->sip_authorization) {
3820 authorization = sip->sip_authorization;
3821 } else if (sip->sip_proxy_authorization) {
3822 authorization = sip->sip_proxy_authorization;
3823 }
3824
3825 if (authorization) {
3826 char network_ip[80];
3827 int network_port;
3828 sofia_glue_get_addr(de->data->e_msg, network_ip, sizeof(network_ip), &network_port);
3829 auth_res = sofia_reg_parse_auth(profile, authorization, sip, de,
3830 (char *) sip->sip_request->rq_method_name, key, keylen, network_ip, network_port, NULL((void*)0), 0,
3831 REG_INVITE, NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0));
3832 } else if ( sofia_reg_handle_register(nua, profile, nh, sip, de, REG_INVITE, key, (uint32_t)keylen, &v_event, NULL, NULL, NULL)sofia_reg_handle_register_token(nua, profile, nh, sip, de, REG_INVITE
, key, (uint32_t)keylen, &v_event, ((void*)0), ((void*)0)
, ((void*)0), ((void*)0))
) {
3833 if (v_event) {
3834 switch_event_destroy(&v_event);
3835 }
3836
3837 goto end;
3838 }
3839
3840 if ((auth_res != AUTH_OK && auth_res != AUTH_RENEWED)) {
3841 nua_respond(nh, SIP_401_UNAUTHORIZED401, sip_401_Unauthorized, NUTAG_WITH_THIS_MSG(de->data->e_msg)nutag_with, tag_ptr_v(de->data->e_msg), TAG_END()(tag_type_t)0, (tag_value_t)0);
3842 goto end;
3843 }
3844 }
3845
3846 orig_to_user = su_strdup(nua_handle_home(nh)((su_home_t *)(nh)), to_user);
3847
3848 if (to_user && (p = strchr(to_user, '+')(__extension__ (__builtin_constant_p ('+') && !__builtin_constant_p
(to_user) && ('+') == '\0' ? (char *) __rawmemchr (to_user
, '+') : __builtin_strchr (to_user, '+')))
) && p != to_user) {
3849 char *h;
3850 if ((proto = (d_user = strdup(to_user)(__extension__ (__builtin_constant_p (to_user) && ((size_t
)(const void *)((to_user) + 1) - (size_t)(const void *)(to_user
) == 1) ? (((const char *) (to_user))[0] == '\0' ? (char *) calloc
((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (to_user
) + 1; char *__retval = (char *) malloc (__len); if (__retval
!= ((void*)0)) __retval = (char *) memcpy (__retval, to_user
, __len); __retval; })) : __strdup (to_user)))
))) {
3851 if ((my_to_user = strchr(d_user, '+')(__extension__ (__builtin_constant_p ('+') && !__builtin_constant_p
(d_user) && ('+') == '\0' ? (char *) __rawmemchr (d_user
, '+') : __builtin_strchr (d_user, '+')))
)) {
3852 *my_to_user++ = '\0';
3853 to_user = my_to_user;
3854 if ((h = strchr(to_user, '+')(__extension__ (__builtin_constant_p ('+') && !__builtin_constant_p
(to_user) && ('+') == '\0' ? (char *) __rawmemchr (to_user
, '+') : __builtin_strchr (to_user, '+')))
) || (h = strchr(to_user, '@')(__extension__ (__builtin_constant_p ('@') && !__builtin_constant_p
(to_user) && ('@') == '\0' ? (char *) __rawmemchr (to_user
, '@') : __builtin_strchr (to_user, '@')))
)) {
3855 *h++ = '\0';
3856 to_host = h;
3857 }
3858 }
3859 }
3860
3861 if (!(proto && to_user && to_host)) {
3862 nua_respond(nh, SIP_404_NOT_FOUND404, sip_404_Not_found, NUTAG_WITH_THIS_MSG(de->data->e_msg)nutag_with, tag_ptr_v(de->data->e_msg), TAG_END()(tag_type_t)0, (tag_value_t)0);
3863 goto end;
3864 }
3865
3866 found_proto++;
3867 }
3868
3869 call_id = sip->sip_call_id->i_id;
3870 full_from = sip_header_as_string(nh->nh_home, (void *) sip->sip_from);
3871 full_to = sip_header_as_string(nh->nh_home, (void *) sip->sip_to);
3872 full_via = sip_header_as_string(nh->nh_home, (void *) sip->sip_via);
3873
3874
3875 if (sip->sip_expires && sip->sip_expires->ex_delta > 31536000) {
3876 sip->sip_expires->ex_delta = 31536000;
3877 }
3878
3879 if (sofia_test_pflag(profile, PFLAG_PRESENCE_MAP)((profile)->pflags[PFLAG_PRESENCE_MAP] ? 1 : 0) && !found_proto && (alt_proto = switch_ivr_check_presence_mapping(to_user, to_host))) {
3880 orig_proto = proto;
3881 proto = alt_proto;
3882 }
3883
3884 if ((sub_state != nua_substate_terminated)) {
3885 sql = switch_mprintf("select contact from sip_subscriptions where call_id='%q' and profile_name='%q' and hostname='%q'",
3886 call_id, profile->name, mod_sofia_globals.hostname);
3887 sofia_glue_execute_sql2str(profile, profile->dbh_mutex, sql, buf, sizeof(buf));
3888
3889
3890 if (mod_sofia_globals.debug_presence > 0 || mod_sofia_globals.debug_sla > 0) {
3891 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 3891, ((void*)0)
, SWITCH_LOG_ERROR,
3892 "check subs sql: %s [%s]\n", sql, buf);
3893 }
3894
3895 switch_safe_free(sql)if (sql) {free(sql);sql=((void*)0);};
3896
3897 if (!zstr(buf)_zstr(buf)) {
3898 sub_state = nua_substate_active;
3899 }
3900 }
3901
3902 if (sub_state == nua_substate_active) {
3903 char *contact = contact_str;
3904
3905 sstr = switch_mprintf("active;expires=%ld", exp_delta);
3906
3907 if (strstr(buf, "fs_path=") && !strstr(contact_str, "fs_path=")) {
3908 char *e = strchr(buf,';')(__extension__ (__builtin_constant_p (';') && !__builtin_constant_p
(buf) && (';') == '\0' ? (char *) __rawmemchr (buf, ';'
) : __builtin_strchr (buf, ';')))
;
3909 size_t l = e ? buf-e : strlen(buf);
3910 if (strncmp(contact_str,buf,l)(__extension__ (__builtin_constant_p (l) && ((__builtin_constant_p
(contact_str) && strlen (contact_str) < ((size_t)
(l))) || (__builtin_constant_p (buf) && strlen (buf)
< ((size_t) (l)))) ? __extension__ ({ size_t __s1_len, __s2_len
; (__builtin_constant_p (contact_str) && __builtin_constant_p
(buf) && (__s1_len = __builtin_strlen (contact_str),
__s2_len = __builtin_strlen (buf), (!((size_t)(const void *)
((contact_str) + 1) - (size_t)(const void *)(contact_str) == 1
) || __s1_len >= 4) && (!((size_t)(const void *)((
buf) + 1) - (size_t)(const void *)(buf) == 1) || __s2_len >=
4)) ? __builtin_strcmp (contact_str, buf) : (__builtin_constant_p
(contact_str) && ((size_t)(const void *)((contact_str
) + 1) - (size_t)(const void *)(contact_str) == 1) &&
(__s1_len = __builtin_strlen (contact_str), __s1_len < 4)
? (__builtin_constant_p (buf) && ((size_t)(const void
*)((buf) + 1) - (size_t)(const void *)(buf) == 1) ? __builtin_strcmp
(contact_str, buf) : (__extension__ ({ const unsigned char *
__s2 = (const unsigned char *) (const char *) (buf); int __result
= (((const unsigned char *) (const char *) (contact_str))[0]
- __s2[0]); if (__s1_len > 0 && __result == 0) { __result
= (((const unsigned char *) (const char *) (contact_str))[1]
- __s2[1]); if (__s1_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) (contact_str))[2]
- __s2[2]); if (__s1_len > 2 && __result == 0) __result
= (((const unsigned char *) (const char *) (contact_str))[3]
- __s2[3]); } } __result; }))) : (__builtin_constant_p (buf)
&& ((size_t)(const void *)((buf) + 1) - (size_t)(const
void *)(buf) == 1) && (__s2_len = __builtin_strlen (
buf), __s2_len < 4) ? (__builtin_constant_p (contact_str) &&
((size_t)(const void *)((contact_str) + 1) - (size_t)(const void
*)(contact_str) == 1) ? __builtin_strcmp (contact_str, buf) :
(- (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (contact_str); int __result = (((const
unsigned char *) (const char *) (buf))[0] - __s2[0]); if (__s2_len
> 0 && __result == 0) { __result = (((const unsigned
char *) (const char *) (buf))[1] - __s2[1]); if (__s2_len >
1 && __result == 0) { __result = (((const unsigned char
*) (const char *) (buf))[2] - __s2[2]); if (__s2_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (buf))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp
(contact_str, buf)))); }) : strncmp (contact_str, buf, l)))
) {
3911 contact = buf;
3912 }
3913 }
3914
3915 sql = switch_mprintf("update sip_subscriptions "
3916 "set expires=%ld, "
3917 "network_ip='%q',network_port='%d',sip_user='%q',sip_host='%q',full_via='%q',full_to='%q',full_from='%q',contact='%q' "
3918 "where call_id='%q' and profile_name='%q' and hostname='%q'",
3919 (long) switch_epoch_time_now(NULL((void*)0)) + exp_delta,
3920 np.network_ip, np.network_port, from_user, from_host, full_via, full_to, full_from, contact,
3921
3922 call_id, profile->name, mod_sofia_globals.hostname);
3923
3924 if (mod_sofia_globals.debug_presence > 0 || mod_sofia_globals.debug_sla > 0) {
3925 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 3925, ((void*)0)
, SWITCH_LOG_ERROR,
3926 "re-subscribe event %s, sql: %s\n", event, sql);
3927 }
3928
3929 sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
3930 } else {
3931
3932 if (sub_state == nua_substate_terminated) {
3933 sql = switch_mprintf("delete from sip_subscriptions where call_id='%q' and profile_name='%q' and hostname='%q'",
3934 call_id, profile->name, mod_sofia_globals.hostname);
3935
3936 if (mod_sofia_globals.debug_presence > 0 || mod_sofia_globals.debug_sla > 0) {
3937 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 3937, ((void*)0)
, SWITCH_LOG_ERROR,
3938 "sub del sql: %s\n", sql);
3939 }
3940
3941 switch_assert(sql != NULL)((sql != ((void*)0)) ? (void) (0) : __assert_fail ("sql != ((void*)0)"
, "sofia_presence.c", 3941, __PRETTY_FUNCTION__))
;
3942 sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
3943 sstr = switch_mprintf("terminated;reason=noresource");
3944
3945 } else {
3946 sip_accept_t *ap = sip->sip_accept;
3947 char accept_header[256] = "";
3948
3949 sub_state = nua_substate_active;
3950
3951 while (ap) {
3952 switch_snprintf(accept_header + strlen(accept_header), sizeof(accept_header) - strlen(accept_header),
3953 "%s%s ", ap->ac_type, ap->ac_next ? "," : "");
3954 ap = ap->ac_next;
3955 }
3956
3957 sql = switch_mprintf("insert into sip_subscriptions "
3958 "(proto,sip_user,sip_host,sub_to_user,sub_to_host,presence_hosts,event,contact,call_id,full_from,"
3959 "full_via,expires,user_agent,accept,profile_name,hostname,network_port,network_ip,version,orig_proto, full_to) "
3960 "values ('%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q',%ld,'%q','%q','%q','%q','%d','%q',-1,'%q','%q;tag=%q')",
3961 proto, from_user, from_host, to_user, to_host, profile->presence_hosts ? profile->presence_hosts : "",
3962 event, contact_str, call_id, full_from, full_via,
3963 (long) switch_epoch_time_now(NULL((void*)0)) + exp_delta,
3964 full_agent, accept_header, profile->name, mod_sofia_globals.hostname,
3965 np.network_port, np.network_ip, orig_proto, full_to, use_to_tag);
3966
3967 switch_assert(sql != NULL)((sql != ((void*)0)) ? (void) (0) : __assert_fail ("sql != ((void*)0)"
, "sofia_presence.c", 3967, __PRETTY_FUNCTION__))
;
3968
3969
3970 if (mod_sofia_globals.debug_presence > 0 || mod_sofia_globals.debug_sla > 0) {
3971 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 3971, ((void*)0)
, SWITCH_LOG_NOTICE, "%s SUBSCRIBE %s@%s %s@%s\n%s\n",
3972 profile->name, from_user, from_host, to_user, to_host, sql);
3973 }
3974
3975
3976 sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
3977 sstr = switch_mprintf("active;expires=%ld", exp_delta);
3978 }
3979
3980 }
3981
3982 if ( sip->sip_event && sip->sip_event->o_type && !strcasecmp(sip->sip_event->o_type, "ua-profile") && contact_host ) {
3983 char *uri = NULL((void*)0);
3984 char *ct = "application/url";
3985 char *extra_headers = NULL((void*)0);
3986
3987 if ( contact_port ) {
3988 uri = switch_mprintf("sip:%s:%s", contact_host, contact_port);
3989 } else {
3990 uri = switch_mprintf("sip:%s", contact_host);
3991 }
3992
3993 if ( uri ) {
3994 switch_event_t *params = NULL((void*)0);
3995 /* Grandstream REALLY uses a header called Message Body */
3996 extra_headers = switch_mprintf("MessageBody: %s\r\n", profile->pnp_prov_url);
3997 if (sofia_test_pflag(profile, PFLAG_SUBSCRIBE_RESPOND_200_OK)((profile)->pflags[PFLAG_SUBSCRIBE_RESPOND_200_OK] ? 1 : 0
)
) {
3998 nua_respond(nh, SIP_200_OK200, sip_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg)nutag_with, tag_ptr_v(de->data->e_msg), TAG_END()(tag_type_t)0, (tag_value_t)0);
3999 } else {
4000 nua_respond(nh, SIP_202_ACCEPTED202, sip_202_Accepted, NUTAG_WITH_THIS_MSG(de->data->e_msg)nutag_with, tag_ptr_v(de->data->e_msg), TAG_END()(tag_type_t)0, (tag_value_t)0);
4001 }
4002
4003 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 4003, ((void*)0)
, SWITCH_LOG_DEBUG, "sending pnp NOTIFY for %s to provision to %s\n", uri, profile->pnp_prov_url);
4004
4005 switch_event_create(&params, SWITCH_EVENT_NOTIFY)switch_event_create_subclass_detailed("sofia_presence.c", (const
char * )(const char *)__func__, 4005, &params, SWITCH_EVENT_NOTIFY
, ((void*)0))
;
4006 switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "profile", profile->name);
4007 switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "event-string", sip->sip_event->o_type);
4008 switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "to-uri", uri);
4009 switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "from-uri", uri);
4010 switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "extra-headers", extra_headers);
4011 switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "content-type", ct);
4012 switch_event_add_body(params, "%s", profile->pnp_prov_url);
4013 switch_event_fire(&params)switch_event_fire_detailed("sofia_presence.c", (const char * )
(const char *)__func__, 4013, &params, ((void*)0))
;
4014
4015 switch_safe_free(uri)if (uri) {free(uri);uri=((void*)0);};
4016 switch_safe_free(extra_headers)if (extra_headers) {free(extra_headers);extra_headers=((void*
)0);}
;
4017
4018 goto end;
4019 }
4020 }
4021
4022 if (status < 200) {
4023 char *sticky = NULL((void*)0);
4024 char *contactstr = profile->url, *cs = NULL((void*)0);
Value stored to 'contactstr' during its initialization is never read
4025 char *p = NULL((void*)0), *new_contactstr = NULL((void*)0);
4026
4027
4028 if (np.is_nat) {
4029 char params[128] = "";
4030 if (contact->m_url->url_params) {
4031 switch_snprintf(params, sizeof(params), ";%s", contact->m_url->url_params);
4032 }
4033 ipv6 = strchr(np.network_ip, ':')(__extension__ (__builtin_constant_p (':') && !__builtin_constant_p
(np.network_ip) && (':') == '\0' ? (char *) __rawmemchr
(np.network_ip, ':') : __builtin_strchr (np.network_ip, ':')
))
;
4034 sticky = switch_mprintf("sip:%s@%s%s%s:%d%s", contact_user, ipv6 ? "[" : "", np.network_ip, ipv6 ? "]" : "", np.network_port, params);
4035 }
4036
4037 if (np.is_auto_nat) {
4038 contactstr = profile->public_url;
4039 } else {
4040 contactstr = profile->url;
4041 }
4042
4043
4044 if (switch_stristr("port=tcp", contact->m_url->url_params)) {
4045 if (np.is_auto_nat) {
4046 cs = profile->tcp_public_contact;
4047 } else {
4048 cs = profile->tcp_contact;
4049 }
4050 } else if (switch_stristr("port=tls", contact->m_url->url_params)) {
4051 if (np.is_auto_nat) {
4052 cs = sofia_test_pflag(profile, PFLAG_TLS)((profile)->pflags[PFLAG_TLS] ? 1 : 0) ?
4053 profile->tls_public_contact : profile->tcp_public_contact;
4054 } else {
4055 cs = sofia_test_pflag(profile, PFLAG_TLS)((profile)->pflags[PFLAG_TLS] ? 1 : 0) ?
4056 profile->tls_contact : profile->tcp_contact;
4057 }
4058 }
4059
4060 if (cs) {
4061 contactstr = cs;
4062 }
4063
4064
4065 if (nh && nh->nh_ds && nh->nh_ds->ds_usage) {
4066 /* nua_dialog_usage_set_refresh_range(nh->nh_ds->ds_usage, exp_delta + SUB_OVERLAP, exp_delta + SUB_OVERLAP); */
4067 nua_dialog_usage_set_refresh_range(nh->nh_ds->ds_usage, exp_delta, exp_delta);
4068 }
4069
4070 if (contactstr && (p = strchr(contactstr, '@')(__extension__ (__builtin_constant_p ('@') && !__builtin_constant_p
(contactstr) && ('@') == '\0' ? (char *) __rawmemchr
(contactstr, '@') : __builtin_strchr (contactstr, '@')))
)) {
4071 if (strrchr(p, '>')) {
4072 new_contactstr = switch_mprintf("<sip:%s%s", orig_to_user, p);
4073 } else {
4074 new_contactstr = switch_mprintf("<sip:%s%s>", orig_to_user, p);
4075 }
4076 }
4077
4078 sip_to_tag(nh->nh_home, sip->sip_to, use_to_tag);
4079
4080 if (mod_sofia_globals.debug_presence > 0) {
4081 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 4081, ((void*)0)
, SWITCH_LOG_DEBUG, "Responding to SUBSCRIBE with 202 Accepted\n");
4082 }
4083 if (sofia_test_pflag(profile, PFLAG_SUBSCRIBE_RESPOND_200_OK)((profile)->pflags[PFLAG_SUBSCRIBE_RESPOND_200_OK] ? 1 : 0
)
) {
4084 nua_respond(nh, SIP_200_OK200, sip_200_OK,
4085 SIPTAG_TO(sip->sip_to)siptag_to, siptag_to_v(sip->sip_to),
4086 TAG_IF(new_contactstr, SIPTAG_CONTACT_STR(new_contactstr))!(new_contactstr) ? tag_skip : siptag_contact_str, tag_str_v(
new_contactstr)
,
4087 NUTAG_WITH_THIS_MSG(de->data->e_msg)nutag_with, tag_ptr_v(de->data->e_msg),
4088 SIPTAG_SUBSCRIPTION_STATE_STR(sstr)siptag_subscription_state_str, tag_str_v(sstr), SIPTAG_EXPIRES_STR(exp_delta_str)siptag_expires_str, tag_str_v(exp_delta_str), TAG_IF(sticky, NUTAG_PROXY(sticky))!(sticky) ? tag_skip : ntatag_default_proxy, urltag_url_v((sticky
))
, TAG_END()(tag_type_t)0, (tag_value_t)0);
4089 } else {
4090 nua_respond(nh, SIP_202_ACCEPTED202, sip_202_Accepted,
4091 SIPTAG_TO(sip->sip_to)siptag_to, siptag_to_v(sip->sip_to),
4092 TAG_IF(new_contactstr, SIPTAG_CONTACT_STR(new_contactstr))!(new_contactstr) ? tag_skip : siptag_contact_str, tag_str_v(
new_contactstr)
,
4093 NUTAG_WITH_THIS_MSG(de->data->e_msg)nutag_with, tag_ptr_v(de->data->e_msg),
4094 SIPTAG_SUBSCRIPTION_STATE_STR(sstr)siptag_subscription_state_str, tag_str_v(sstr), SIPTAG_EXPIRES_STR(exp_delta_str)siptag_expires_str, tag_str_v(exp_delta_str), TAG_IF(sticky, NUTAG_PROXY(sticky))!(sticky) ? tag_skip : ntatag_default_proxy, urltag_url_v((sticky
))
, TAG_END()(tag_type_t)0, (tag_value_t)0);
4095 }
4096
4097 switch_safe_free(new_contactstr)if (new_contactstr) {free(new_contactstr);new_contactstr=((void
*)0);}
;
4098 switch_safe_free(sticky)if (sticky) {free(sticky);sticky=((void*)0);};
4099
4100 if (sub_state == nua_substate_terminated) {
4101 if (mod_sofia_globals.debug_presence > 0) {
4102 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 4102, ((void*)0)
, SWITCH_LOG_DEBUG, "Sending NOTIFY with Expires [0] and State [%s]\n", sstr);
4103 }
4104
4105 if (zstr(full_agent)_zstr(full_agent) || (*full_agent != 'z' && *full_agent != 'Z')) {
4106 /* supress endless loop bug with zoiper */
4107 nua_notify(nh,
4108 SIPTAG_EXPIRES_STR("0")siptag_expires_str, tag_str_v("0"),
4109 SIPTAG_SUBSCRIPTION_STATE_STR(sstr)siptag_subscription_state_str, tag_str_v(sstr),
4110 TAG_END()(tag_type_t)0, (tag_value_t)0);
4111 }
4112
4113
4114 }
4115 }
4116
4117 if (sub_state == nua_substate_terminated) {
4118 char *full_call_info = NULL((void*)0);
4119 char *p = NULL((void*)0);
4120
4121 if (sip->sip_call_info) {
4122 full_call_info = sip_header_as_string(nh->nh_home, (void *) sip->sip_call_info);
4123 if ((p = strchr(full_call_info, ';')(__extension__ (__builtin_constant_p (';') && !__builtin_constant_p
(full_call_info) && (';') == '\0' ? (char *) __rawmemchr
(full_call_info, ';') : __builtin_strchr (full_call_info, ';'
)))
)) {
4124 p++;
4125 }
4126
4127#if 0
4128 nua_notify(nh,
4129 SIPTAG_EXPIRES_STR("0")siptag_expires_str, tag_str_v("0"),
4130 SIPTAG_SUBSCRIPTION_STATE_STR(sstr)siptag_subscription_state_str, tag_str_v(sstr), TAG_IF(full_call_info, SIPTAG_CALL_INFO_STR(full_call_info))!(full_call_info) ? tag_skip : siptag_call_info_str, tag_str_v
(full_call_info)
, TAG_END()(tag_type_t)0, (tag_value_t)0);
4131#endif
4132
4133 if (!strcasecmp(event, "line-seize")) {
4134 if (mod_sofia_globals.debug_sla > 1) {
4135 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 4135, ((void*)0)
, SWITCH_LOG_ERROR, "CANCEL LINE SEIZE\n");
4136 }
4137
4138 sql = switch_mprintf("delete from sip_dialogs where hostname='%q' and profile_name='%q' and "
4139 "((sip_from_user='%q' and sip_from_host='%q') or presence_id='%q@%q') "
4140 "and call_info_state='seized'",
4141 mod_sofia_globals.hostname, profile->name, to_user, to_host, to_user, to_host);
4142
4143
4144 if (mod_sofia_globals.debug_sla > 1) {
4145 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 4145, ((void*)0)
, SWITCH_LOG_ERROR, "CLEAR SQL %s\n", sql);
4146 }
4147 sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
4148
4149 sync_sla(profile, to_user, to_host, SWITCH_FALSE, SWITCH_FALSE, NULL((void*)0));
4150 }
4151
4152 su_free(nh->nh_home, full_call_info);
4153
4154 }
4155
4156 } else {
4157 if (!strcasecmp(event, "line-seize")) {
4158 char *full_call_info = NULL((void*)0);
4159 char *p;
4160 switch_time_t now;
4161
4162 if (sip->sip_call_info) {
4163 full_call_info = sip_header_as_string(nh->nh_home, (void *) sip->sip_call_info);
4164 if ((p = strchr(full_call_info, ';')(__extension__ (__builtin_constant_p (';') && !__builtin_constant_p
(full_call_info) && (';') == '\0' ? (char *) __rawmemchr
(full_call_info, ';') : __builtin_strchr (full_call_info, ';'
)))
)) {
4165 p++;
4166 }
4167
4168 nua_notify(nh,
4169 SIPTAG_FROM(sip->sip_to)siptag_from, siptag_from_v(sip->sip_to),
4170 SIPTAG_TO(sip->sip_from)siptag_to, siptag_to_v(sip->sip_from),
4171 SIPTAG_EXPIRES_STR(exp_delta_str)siptag_expires_str, tag_str_v(exp_delta_str),
4172 SIPTAG_SUBSCRIPTION_STATE_STR(sstr)siptag_subscription_state_str, tag_str_v(sstr),
4173 SIPTAG_EVENT_STR("line-seize")siptag_event_str, tag_str_v("line-seize"), TAG_IF(full_call_info, SIPTAG_CALL_INFO_STR(full_call_info))!(full_call_info) ? tag_skip : siptag_call_info_str, tag_str_v
(full_call_info)
, TAG_END()(tag_type_t)0, (tag_value_t)0);
4174
4175
4176
4177
4178 sql = switch_mprintf("delete from sip_dialogs where hostname='%q' and profile_name='%q' and "
4179 "((sip_from_user='%q' and sip_from_host='%q') or presence_id='%q@%q') "
4180 "and call_info_state='seized' and profile_name='%q'",
4181 mod_sofia_globals.hostname, profile->name, to_user, to_host, to_user, to_host, profile->name);
4182
4183
4184 if (mod_sofia_globals.debug_sla > 1) {
4185 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 4185, ((void*)0)
, SWITCH_LOG_ERROR, "CLEAR SQL %s\n", sql);
4186 }
4187 sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
4188
4189 now = switch_epoch_time_now(NULL((void*)0));
4190 sql = switch_mprintf("insert into sip_dialogs (sip_from_user,sip_from_host,call_info,call_info_state,hostname,expires,rcd,profile_name) "
4191 "values ('%q','%q','%q','seized','%q',%"TIME_T_FMT"ld"",%ld,'%q')",
4192 to_user, to_host, switch_str_nil(p)(p ? p : ""), mod_sofia_globals.hostname,
4193 switch_epoch_time_now(NULL((void*)0)) + exp_delta, (long)now, profile->name);
4194
4195 if (mod_sofia_globals.debug_sla > 1) {
4196 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 4196, ((void*)0)
, SWITCH_LOG_ERROR, "SEIZE SQL %s\n", sql);
4197 }
4198 sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
4199 sync_sla(profile, to_user, to_host, SWITCH_FALSE, SWITCH_FALSE, NULL((void*)0));
4200
4201 su_free(nh->nh_home, full_call_info);
4202 }
4203 } else if (!strcasecmp(event, "call-info")) {
4204 sync_sla(profile, to_user, to_host, SWITCH_FALSE, SWITCH_FALSE, call_id);
4205 }
4206 }
4207
4208 sent_reply++;
4209
4210 switch_safe_free(sstr)if (sstr) {free(sstr);sstr=((void*)0);};
4211
4212 if (!strcasecmp(event, "as-feature-event")) {
4213 switch_event_t *event;
4214 char sip_cseq[40] = "";
4215
4216 switch_snprintf(sip_cseq, sizeof(sip_cseq), "%d", sip->sip_cseq->cs_seq);
4217 switch_event_create(&event, SWITCH_EVENT_PHONE_FEATURE_SUBSCRIBE)switch_event_create_subclass_detailed("sofia_presence.c", (const
char * )(const char *)__func__, 4217, &event, SWITCH_EVENT_PHONE_FEATURE_SUBSCRIBE
, ((void*)0))
;
4218 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "user", from_user);
4219 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "host", from_host);
4220 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "contact", contact_str);
4221 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call-id", call_id);
4222 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "expires", exp_delta_str);
4223 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "cseq", sip_cseq);
4224 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "profile_name", profile->name);
4225 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "hostname", mod_sofia_globals.hostname);
4226
4227 if (sip->sip_payload) {
4228 switch_xml_t xml = NULL((void*)0);
4229 char *pd_dup = NULL((void*)0);
4230
4231 pd_dup = strdup(sip->sip_payload->pl_data)(__extension__ (__builtin_constant_p (sip->sip_payload->
pl_data) && ((size_t)(const void *)((sip->sip_payload
->pl_data) + 1) - (size_t)(const void *)(sip->sip_payload
->pl_data) == 1) ? (((const char *) (sip->sip_payload->
pl_data))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1
) : ({ size_t __len = strlen (sip->sip_payload->pl_data
) + 1; char *__retval = (char *) malloc (__len); if (__retval
!= ((void*)0)) __retval = (char *) memcpy (__retval, sip->
sip_payload->pl_data, __len); __retval; })) : __strdup (sip
->sip_payload->pl_data)))
;
4232
4233 if ((xml = switch_xml_parse_str(pd_dup, strlen(pd_dup)))) {
4234 switch_xml_t device = NULL((void*)0);
4235
4236 if ((device = switch_xml_child(xml, "device"))) {
4237 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "device", device->txt);
4238 }
4239
4240 if (!strcmp(xml->name, "SetDoNotDisturb")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(xml->name) && __builtin_constant_p ("SetDoNotDisturb"
) && (__s1_len = __builtin_strlen (xml->name), __s2_len
= __builtin_strlen ("SetDoNotDisturb"), (!((size_t)(const void
*)((xml->name) + 1) - (size_t)(const void *)(xml->name
) == 1) || __s1_len >= 4) && (!((size_t)(const void
*)(("SetDoNotDisturb") + 1) - (size_t)(const void *)("SetDoNotDisturb"
) == 1) || __s2_len >= 4)) ? __builtin_strcmp (xml->name
, "SetDoNotDisturb") : (__builtin_constant_p (xml->name) &&
((size_t)(const void *)((xml->name) + 1) - (size_t)(const
void *)(xml->name) == 1) && (__s1_len = __builtin_strlen
(xml->name), __s1_len < 4) ? (__builtin_constant_p ("SetDoNotDisturb"
) && ((size_t)(const void *)(("SetDoNotDisturb") + 1)
- (size_t)(const void *)("SetDoNotDisturb") == 1) ? __builtin_strcmp
(xml->name, "SetDoNotDisturb") : (__extension__ ({ const unsigned
char *__s2 = (const unsigned char *) (const char *) ("SetDoNotDisturb"
); int __result = (((const unsigned char *) (const char *) (xml
->name))[0] - __s2[0]); if (__s1_len > 0 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
xml->name))[1] - __s2[1]); if (__s1_len > 1 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
xml->name))[2] - __s2[2]); if (__s1_len > 2 && __result
== 0) __result = (((const unsigned char *) (const char *) (xml
->name))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
("SetDoNotDisturb") && ((size_t)(const void *)(("SetDoNotDisturb"
) + 1) - (size_t)(const void *)("SetDoNotDisturb") == 1) &&
(__s2_len = __builtin_strlen ("SetDoNotDisturb"), __s2_len <
4) ? (__builtin_constant_p (xml->name) && ((size_t
)(const void *)((xml->name) + 1) - (size_t)(const void *)(
xml->name) == 1) ? __builtin_strcmp (xml->name, "SetDoNotDisturb"
) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (xml->name); int __result = (((const
unsigned char *) (const char *) ("SetDoNotDisturb"))[0] - __s2
[0]); if (__s2_len > 0 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("SetDoNotDisturb"
))[1] - __s2[1]); if (__s2_len > 1 && __result == 0
) { __result = (((const unsigned char *) (const char *) ("SetDoNotDisturb"
))[2] - __s2[2]); if (__s2_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) ("SetDoNotDisturb"
))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (xml
->name, "SetDoNotDisturb")))); })
) {
4241 switch_xml_t action = NULL((void*)0);
4242
4243 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Feature-Action", "SetDoNotDisturb");
4244 if ((action = switch_xml_child(xml, "doNotDisturbOn"))) {
4245 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Feature-Enabled", action->txt);
4246 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action-Name", action->name);
4247 }
4248 }
4249
4250 if (!strcmp(xml->name, "SetForwarding")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(xml->name) && __builtin_constant_p ("SetForwarding"
) && (__s1_len = __builtin_strlen (xml->name), __s2_len
= __builtin_strlen ("SetForwarding"), (!((size_t)(const void
*)((xml->name) + 1) - (size_t)(const void *)(xml->name
) == 1) || __s1_len >= 4) && (!((size_t)(const void
*)(("SetForwarding") + 1) - (size_t)(const void *)("SetForwarding"
) == 1) || __s2_len >= 4)) ? __builtin_strcmp (xml->name
, "SetForwarding") : (__builtin_constant_p (xml->name) &&
((size_t)(const void *)((xml->name) + 1) - (size_t)(const
void *)(xml->name) == 1) && (__s1_len = __builtin_strlen
(xml->name), __s1_len < 4) ? (__builtin_constant_p ("SetForwarding"
) && ((size_t)(const void *)(("SetForwarding") + 1) -
(size_t)(const void *)("SetForwarding") == 1) ? __builtin_strcmp
(xml->name, "SetForwarding") : (__extension__ ({ const unsigned
char *__s2 = (const unsigned char *) (const char *) ("SetForwarding"
); int __result = (((const unsigned char *) (const char *) (xml
->name))[0] - __s2[0]); if (__s1_len > 0 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
xml->name))[1] - __s2[1]); if (__s1_len > 1 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
xml->name))[2] - __s2[2]); if (__s1_len > 2 && __result
== 0) __result = (((const unsigned char *) (const char *) (xml
->name))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
("SetForwarding") && ((size_t)(const void *)(("SetForwarding"
) + 1) - (size_t)(const void *)("SetForwarding") == 1) &&
(__s2_len = __builtin_strlen ("SetForwarding"), __s2_len <
4) ? (__builtin_constant_p (xml->name) && ((size_t
)(const void *)((xml->name) + 1) - (size_t)(const void *)(
xml->name) == 1) ? __builtin_strcmp (xml->name, "SetForwarding"
) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (xml->name); int __result = (((const
unsigned char *) (const char *) ("SetForwarding"))[0] - __s2
[0]); if (__s2_len > 0 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("SetForwarding")
)[1] - __s2[1]); if (__s2_len > 1 && __result == 0
) { __result = (((const unsigned char *) (const char *) ("SetForwarding"
))[2] - __s2[2]); if (__s2_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) ("SetForwarding"
))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (xml
->name, "SetForwarding")))); })
) {
4251 switch_xml_t cfwd_type, cfwd_enable, cfwd_target;
4252
4253 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Feature-Action", "SetCallForward");
4254 if ((cfwd_type = switch_xml_child(xml, "forwardingType"))
4255 && (cfwd_enable = switch_xml_child(xml, "activateForward"))
4256 && (cfwd_target = switch_xml_child(xml, "forwardDN"))) {
4257
4258 if (!strcmp(cfwd_type->txt, "forwardImmediate")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(cfwd_type->txt) && __builtin_constant_p ("forwardImmediate"
) && (__s1_len = __builtin_strlen (cfwd_type->txt)
, __s2_len = __builtin_strlen ("forwardImmediate"), (!((size_t
)(const void *)((cfwd_type->txt) + 1) - (size_t)(const void
*)(cfwd_type->txt) == 1) || __s1_len >= 4) && (
!((size_t)(const void *)(("forwardImmediate") + 1) - (size_t)
(const void *)("forwardImmediate") == 1) || __s2_len >= 4)
) ? __builtin_strcmp (cfwd_type->txt, "forwardImmediate") :
(__builtin_constant_p (cfwd_type->txt) && ((size_t
)(const void *)((cfwd_type->txt) + 1) - (size_t)(const void
*)(cfwd_type->txt) == 1) && (__s1_len = __builtin_strlen
(cfwd_type->txt), __s1_len < 4) ? (__builtin_constant_p
("forwardImmediate") && ((size_t)(const void *)(("forwardImmediate"
) + 1) - (size_t)(const void *)("forwardImmediate") == 1) ? __builtin_strcmp
(cfwd_type->txt, "forwardImmediate") : (__extension__ ({ const
unsigned char *__s2 = (const unsigned char *) (const char *)
("forwardImmediate"); int __result = (((const unsigned char *
) (const char *) (cfwd_type->txt))[0] - __s2[0]); if (__s1_len
> 0 && __result == 0) { __result = (((const unsigned
char *) (const char *) (cfwd_type->txt))[1] - __s2[1]); if
(__s1_len > 1 && __result == 0) { __result = (((const
unsigned char *) (const char *) (cfwd_type->txt))[2] - __s2
[2]); if (__s1_len > 2 && __result == 0) __result =
(((const unsigned char *) (const char *) (cfwd_type->txt)
)[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p (
"forwardImmediate") && ((size_t)(const void *)(("forwardImmediate"
) + 1) - (size_t)(const void *)("forwardImmediate") == 1) &&
(__s2_len = __builtin_strlen ("forwardImmediate"), __s2_len <
4) ? (__builtin_constant_p (cfwd_type->txt) && ((
size_t)(const void *)((cfwd_type->txt) + 1) - (size_t)(const
void *)(cfwd_type->txt) == 1) ? __builtin_strcmp (cfwd_type
->txt, "forwardImmediate") : (- (__extension__ ({ const unsigned
char *__s2 = (const unsigned char *) (const char *) (cfwd_type
->txt); int __result = (((const unsigned char *) (const char
*) ("forwardImmediate"))[0] - __s2[0]); if (__s2_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) ("forwardImmediate"))[1] - __s2[1]); if (__s2_len >
1 && __result == 0) { __result = (((const unsigned char
*) (const char *) ("forwardImmediate"))[2] - __s2[2]); if (__s2_len
> 2 && __result == 0) __result = (((const unsigned
char *) (const char *) ("forwardImmediate"))[3] - __s2[3]); }
} __result; })))) : __builtin_strcmp (cfwd_type->txt, "forwardImmediate"
)))); })
) {
4259 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Feature-Enabled", cfwd_enable->txt);
4260 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action-Name", "forward_immediate");
4261 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action-Value", cfwd_target->txt);
4262 } else if (!strcmp(cfwd_type->txt, "forwardBusy")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(cfwd_type->txt) && __builtin_constant_p ("forwardBusy"
) && (__s1_len = __builtin_strlen (cfwd_type->txt)
, __s2_len = __builtin_strlen ("forwardBusy"), (!((size_t)(const
void *)((cfwd_type->txt) + 1) - (size_t)(const void *)(cfwd_type
->txt) == 1) || __s1_len >= 4) && (!((size_t)(const
void *)(("forwardBusy") + 1) - (size_t)(const void *)("forwardBusy"
) == 1) || __s2_len >= 4)) ? __builtin_strcmp (cfwd_type->
txt, "forwardBusy") : (__builtin_constant_p (cfwd_type->txt
) && ((size_t)(const void *)((cfwd_type->txt) + 1)
- (size_t)(const void *)(cfwd_type->txt) == 1) &&
(__s1_len = __builtin_strlen (cfwd_type->txt), __s1_len <
4) ? (__builtin_constant_p ("forwardBusy") && ((size_t
)(const void *)(("forwardBusy") + 1) - (size_t)(const void *)
("forwardBusy") == 1) ? __builtin_strcmp (cfwd_type->txt, "forwardBusy"
) : (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) ("forwardBusy"); int __result = (((const
unsigned char *) (const char *) (cfwd_type->txt))[0] - __s2
[0]); if (__s1_len > 0 && __result == 0) { __result
= (((const unsigned char *) (const char *) (cfwd_type->txt
))[1] - __s2[1]); if (__s1_len > 1 && __result == 0
) { __result = (((const unsigned char *) (const char *) (cfwd_type
->txt))[2] - __s2[2]); if (__s1_len > 2 && __result
== 0) __result = (((const unsigned char *) (const char *) (cfwd_type
->txt))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
("forwardBusy") && ((size_t)(const void *)(("forwardBusy"
) + 1) - (size_t)(const void *)("forwardBusy") == 1) &&
(__s2_len = __builtin_strlen ("forwardBusy"), __s2_len < 4
) ? (__builtin_constant_p (cfwd_type->txt) && ((size_t
)(const void *)((cfwd_type->txt) + 1) - (size_t)(const void
*)(cfwd_type->txt) == 1) ? __builtin_strcmp (cfwd_type->
txt, "forwardBusy") : (- (__extension__ ({ const unsigned char
*__s2 = (const unsigned char *) (const char *) (cfwd_type->
txt); int __result = (((const unsigned char *) (const char *)
("forwardBusy"))[0] - __s2[0]); if (__s2_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) ("forwardBusy"))[1] - __s2[1]); if (__s2_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) ("forwardBusy"))[2] - __s2[2]); if (__s2_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) ("forwardBusy"))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp
(cfwd_type->txt, "forwardBusy")))); })
) {
4263 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Feature-Enabled", cfwd_enable->txt);
4264 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action-Name", "forward_busy");
4265 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action-Value", cfwd_target->txt);
4266 } else if (!strcmp(cfwd_type->txt, "forwardNoAns")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(cfwd_type->txt) && __builtin_constant_p ("forwardNoAns"
) && (__s1_len = __builtin_strlen (cfwd_type->txt)
, __s2_len = __builtin_strlen ("forwardNoAns"), (!((size_t)(const
void *)((cfwd_type->txt) + 1) - (size_t)(const void *)(cfwd_type
->txt) == 1) || __s1_len >= 4) && (!((size_t)(const
void *)(("forwardNoAns") + 1) - (size_t)(const void *)("forwardNoAns"
) == 1) || __s2_len >= 4)) ? __builtin_strcmp (cfwd_type->
txt, "forwardNoAns") : (__builtin_constant_p (cfwd_type->txt
) && ((size_t)(const void *)((cfwd_type->txt) + 1)
- (size_t)(const void *)(cfwd_type->txt) == 1) &&
(__s1_len = __builtin_strlen (cfwd_type->txt), __s1_len <
4) ? (__builtin_constant_p ("forwardNoAns") && ((size_t
)(const void *)(("forwardNoAns") + 1) - (size_t)(const void *
)("forwardNoAns") == 1) ? __builtin_strcmp (cfwd_type->txt
, "forwardNoAns") : (__extension__ ({ const unsigned char *__s2
= (const unsigned char *) (const char *) ("forwardNoAns"); int
__result = (((const unsigned char *) (const char *) (cfwd_type
->txt))[0] - __s2[0]); if (__s1_len > 0 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
cfwd_type->txt))[1] - __s2[1]); if (__s1_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (cfwd_type->txt))[2] - __s2[2]); if (__s1_len >
2 && __result == 0) __result = (((const unsigned char
*) (const char *) (cfwd_type->txt))[3] - __s2[3]); } } __result
; }))) : (__builtin_constant_p ("forwardNoAns") && ((
size_t)(const void *)(("forwardNoAns") + 1) - (size_t)(const void
*)("forwardNoAns") == 1) && (__s2_len = __builtin_strlen
("forwardNoAns"), __s2_len < 4) ? (__builtin_constant_p (
cfwd_type->txt) && ((size_t)(const void *)((cfwd_type
->txt) + 1) - (size_t)(const void *)(cfwd_type->txt) ==
1) ? __builtin_strcmp (cfwd_type->txt, "forwardNoAns") : (
- (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (cfwd_type->txt); int __result = (
((const unsigned char *) (const char *) ("forwardNoAns"))[0] -
__s2[0]); if (__s2_len > 0 && __result == 0) { __result
= (((const unsigned char *) (const char *) ("forwardNoAns"))
[1] - __s2[1]); if (__s2_len > 1 && __result == 0)
{ __result = (((const unsigned char *) (const char *) ("forwardNoAns"
))[2] - __s2[2]); if (__s2_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) ("forwardNoAns"
))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (cfwd_type
->txt, "forwardNoAns")))); })
) {
4267 switch_xml_t rc;
4268
4269 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Feature-Enabled", cfwd_enable->txt);
4270 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action-Name", "forward_no_answer");
4271 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action-Value", cfwd_target->txt);
4272 if ((rc = switch_xml_child(xml, "ringCount"))) {
4273 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "ringCount", rc->txt);
4274 }
4275 }
4276 }
4277 }
4278 }
4279 }
4280 switch_event_fire(&event)switch_event_fire_detailed("sofia_presence.c", (const char * )
(const char *)__func__, 4280, &event, ((void*)0))
;
4281 } else if (!strcasecmp(event, "message-summary")) {
4282 if ((sql = switch_mprintf("select proto,sip_user,'%q',sub_to_user,sub_to_host,event,contact,call_id,full_from,"
4283 "full_via,expires,user_agent,accept,profile_name,network_ip"
4284 " from sip_subscriptions where hostname='%q' and profile_name='%q' and "
4285 "event='message-summary' and sub_to_user='%q' "
4286 "and (sip_host='%q' or presence_hosts like '%%%q%%')",
4287 to_host, mod_sofia_globals.hostname, profile->name,
4288 to_user, to_host, to_host))) {
4289
4290 if (mod_sofia_globals.debug_presence > 0) {
4291 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 4291, ((void*)0)
, SWITCH_LOG_ERROR,
4292 "SUBSCRIBE MWI SQL: %s\n", sql);
4293 }
4294
4295
4296 sofia_glue_execute_sql_callback(profile, profile->dbh_mutex, sql, sofia_presence_sub_reg_callback, profile);
4297
4298 switch_safe_free(sql)if (sql) {free(sql);sql=((void*)0);};
4299 }
4300 } else if (!strcasecmp(event, "conference")) {
4301 switch_event_t *event;
4302 switch_event_create(&event, SWITCH_EVENT_CONFERENCE_DATA_QUERY)switch_event_create_subclass_detailed("sofia_presence.c", (const
char * )(const char *)__func__, 4302, &event, SWITCH_EVENT_CONFERENCE_DATA_QUERY
, ((void*)0))
;
4303 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Conference-Name", to_user);
4304 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Conference-Domain", to_host);
4305 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Query-From", from_user);
4306 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Query-From-Domain", from_host);
4307 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Call-Id", call_id);
4308 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Sofia-Profile", profile->name);
4309 switch_event_fire(&event)switch_event_fire_detailed("sofia_presence.c", (const char * )
(const char *)__func__, 4309, &event, ((void*)0))
;
4310 }
4311
4312 end:
4313
4314 if (strcasecmp(event, "call-info") && strcasecmp(event, "line-seize")) {
4315
4316 if (to_user && (strstr(to_user, "ext+") || strstr(to_user, "user+"))) {
4317 char protocol[80];
4318 char *p;
4319
4320 switch_copy_string(protocol, to_user, sizeof(protocol));
4321 if ((p = strchr(protocol, '+')(__extension__ (__builtin_constant_p ('+') && !__builtin_constant_p
(protocol) && ('+') == '\0' ? (char *) __rawmemchr (
protocol, '+') : __builtin_strchr (protocol, '+')))
)) {
4322 *p = '\0';
4323 }
4324
4325 if (switch_event_create(&sevent, SWITCH_EVENT_PRESENCE_IN)switch_event_create_subclass_detailed("sofia_presence.c", (const
char * )(const char *)__func__, 4325, &sevent, SWITCH_EVENT_PRESENCE_IN
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
4326 switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "proto", protocol);
4327 if (!zstr(orig_proto)_zstr(orig_proto)) {
4328 switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "orig_proto", orig_proto);
4329 }
4330 switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "login", profile->name);
4331 switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "sip_profile", profile->name);
4332 switch_event_add_header(sevent, SWITCH_STACK_BOTTOM, "from", "%s@%s", to_user, to_host);
4333 switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "rpid", "active");
4334 switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "status", "Click To Call");
4335 switch_event_fire(&sevent)switch_event_fire_detailed("sofia_presence.c", (const char * )
(const char *)__func__, 4335, &sevent, ((void*)0))
;
4336 }
4337
4338 } else if (to_user && (strcasecmp(proto, SOFIA_CHAT_PROTO"sip") != 0)) {
4339 if (switch_event_create(&sevent, SWITCH_EVENT_PRESENCE_PROBE)switch_event_create_subclass_detailed("sofia_presence.c", (const
char * )(const char *)__func__, 4339, &sevent, SWITCH_EVENT_PRESENCE_PROBE
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
4340 switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "proto", proto);
4341 if (!zstr(orig_proto)_zstr(orig_proto)) {
4342 switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "orig_proto", orig_proto);
4343 }
4344 switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "login", profile->name);
4345 switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "sip_profile", profile->name);
4346 switch_event_add_header(sevent, SWITCH_STACK_BOTTOM, "from", "%s@%s", from_user, from_host);
4347 switch_event_add_header(sevent, SWITCH_STACK_BOTTOM, "to", "%s%s%s@%s", proto, "+", to_user, to_host);
4348 switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "proto-specific-event-name", event);
4349 switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "expires", exp_delta_str);
4350 switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "event_type", "presence");
4351 switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "alt_event_type", "dialog");
4352 switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "expires", exp_delta_str);
4353 switch_event_fire(&sevent)switch_event_fire_detailed("sofia_presence.c", (const char * )
(const char *)__func__, 4353, &sevent, ((void*)0))
;
4354
4355 }
4356 } else {
4357
4358 if (!strcasecmp(event, "dialog")) {
4359 if (switch_event_create(&sevent, SWITCH_EVENT_PRESENCE_PROBE)switch_event_create_subclass_detailed("sofia_presence.c", (const
char * )(const char *)__func__, 4359, &sevent, SWITCH_EVENT_PRESENCE_PROBE
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
4360 switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "probe-type", "dialog");
4361 switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "proto", SOFIA_CHAT_PROTO"sip");
4362 switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "login", profile->name);
4363 switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "sip_profile", profile->name);
4364 switch_event_add_header(sevent, SWITCH_STACK_BOTTOM, "from", "%s@%s", from_user, from_host);
4365 switch_event_add_header(sevent, SWITCH_STACK_BOTTOM, "to", "%s@%s", to_user, to_host);
4366 switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "proto-specific-event-name", event);
4367 switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "expires", exp_delta_str);
4368 switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "event_type", "presence");
4369 switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "alt_event_type", "dialog");
4370 switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "expires", exp_delta_str);
4371 switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "sub-call-id", call_id);
4372 switch_event_fire(&sevent)switch_event_fire_detailed("sofia_presence.c", (const char * )
(const char *)__func__, 4372, &sevent, ((void*)0))
;
4373 }
4374 } else if (!strcasecmp(event, "presence")) {
4375 if (switch_event_create(&sevent, SWITCH_EVENT_PRESENCE_PROBE)switch_event_create_subclass_detailed("sofia_presence.c", (const
char * )(const char *)__func__, 4375, &sevent, SWITCH_EVENT_PRESENCE_PROBE
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
4376 switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "proto", SOFIA_CHAT_PROTO"sip");
4377 switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "login", profile->name);
4378 switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "sip_profile", profile->name);
4379 switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "presence-source", "subscribe");
4380 switch_event_add_header(sevent, SWITCH_STACK_BOTTOM, "from", "%s@%s", from_user, from_host);
4381 switch_event_add_header(sevent, SWITCH_STACK_BOTTOM, "to", "%s@%s", to_user, to_host);
4382 switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "expires", exp_delta_str);
4383 switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "alt_event_type", "dialog");
4384 switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "rpid", "unknown");
4385 switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "status", "Registered");
4386 switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "sub-call-id", call_id);
4387 switch_event_fire(&sevent)switch_event_fire_detailed("sofia_presence.c", (const char * )
(const char *)__func__, 4387, &sevent, ((void*)0))
;
4388 }
4389 }
4390 }
4391 }
4392
4393 if (event) {
4394 su_free(nh->nh_home, event);
4395 }
4396
4397 if (full_from) {
4398 su_free(nh->nh_home, full_from);
4399 }
4400 if (full_to) {
4401 su_free(nh->nh_home, full_to);
4402 }
4403
4404 if (full_via) {
4405 su_free(nh->nh_home, full_via);
4406 }
4407 if (full_agent) {
4408 su_free(nh->nh_home, full_agent);
4409 }
4410
4411 switch_safe_free(d_user)if (d_user) {free(d_user);d_user=((void*)0);};
4412 switch_safe_free(to_str)if (to_str) {free(to_str);to_str=((void*)0);};
4413 switch_safe_free(contact_str)if (contact_str) {free(contact_str);contact_str=((void*)0);};
4414 switch_safe_free(alt_proto)if (alt_proto) {free(alt_proto);alt_proto=((void*)0);};
4415
4416 if (!sent_reply) {
4417 nua_respond(nh, 481, "INVALID SUBSCRIPTION", TAG_END()(tag_type_t)0, (tag_value_t)0);
4418 }
4419
4420 if (!sofia_private || !sofia_private->is_call) {
4421 nua_handle_destroy(nh);
4422 }
4423
4424}
4425
4426
4427sofia_gateway_subscription_t *sofia_find_gateway_subscription(sofia_gateway_t *gateway_ptr, const char *event)
4428{
4429 sofia_gateway_subscription_t *gw_sub_ptr;
4430 for (gw_sub_ptr = gateway_ptr->subscriptions; gw_sub_ptr; gw_sub_ptr = gw_sub_ptr->next) {
4431 if (!strcasecmp(gw_sub_ptr->event, event)) {
4432 /* this is the gateway subscription we are interested in */
4433 return gw_sub_ptr;
4434 }
4435 }
4436 return NULL((void*)0);
4437}
4438
4439void sofia_presence_handle_sip_r_subscribe(int status,
4440 char const *phrase,
4441 nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
4442 sofia_dispatch_event_t *de,
4443 tagi_t tags[])
4444{
4445 sip_event_t const *o = NULL((void*)0);
4446 sofia_gateway_subscription_t *gw_sub_ptr;
4447 sofia_gateway_t *gateway = NULL((void*)0);
4448
4449 if (!sip) {
4450 return;
4451 }
4452
4453 tl_gets(tags, SIPTAG_EVENT_REF(o)siptag_event_ref, siptag_event_vr(&(o)), TAG_END()(tag_type_t)0, (tag_value_t)0);
4454 /* o->o_type: message-summary (for example) */
4455 if (!o) {
4456 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 4456, ((void*)0)
, SWITCH_LOG_ERROR, "Event information not given\n");
4457 return;
4458 }
4459
4460 if (!sofia_private || zstr(sofia_private->gateway_name)_zstr(sofia_private->gateway_name)) {
4461 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 4461, ((void*)0)
, SWITCH_LOG_ERROR, "Gateway information missing\n");
4462 return;
4463 }
4464
4465
4466 if (!(gateway = sofia_reg_find_gateway(sofia_private->gateway_name)sofia_reg_find_gateway__("sofia_presence.c", (const char *)__func__
, 4466, sofia_private->gateway_name)
)) {
4467 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 4467, ((void*)0)
, SWITCH_LOG_ERROR, "Gateway information missing\n");
4468 return;
4469 }
4470
4471
4472 /* Find the subscription if one exists */
4473 if (!(gw_sub_ptr = sofia_find_gateway_subscription(gateway, o->o_type))) {
4474 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 4474, ((void*)0)
, SWITCH_LOG_WARNING, "Could not find gateway subscription. Gateway: %s. Subscription Event: %s\n",
4475 gateway->name, o->o_type);
4476 goto end;
4477 }
4478
4479 /* Update the subscription status for the subscription */
4480 switch (status) {
4481 case 200:
4482 case 202:
4483 /* TODO: in the spec it is possible for the other side to change the original expiry time,
4484 * this needs to be researched (eg, what sip header this information will be in) and implemented.
4485 * Although, since it seems the sofia stack is pretty much handling the subscription expiration
4486 * anyway, then maybe its not even worth bothering.
4487 */
4488 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 4488, ((void*)0)
, SWITCH_LOG_DEBUG, "got 200 OK response, updated state to SUB_STATE_SUBSCRIBE.\n");
4489 gw_sub_ptr->state = SUB_STATE_SUBSCRIBE;
4490 break;
4491 case 100:
4492 break;
4493 default:
4494 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 4494, ((void*)0)
, SWITCH_LOG_WARNING, "status (%d) != 200, updated state to SUB_STATE_FAILED.\n", status);
4495 gw_sub_ptr->state = SUB_STATE_FAILED;
4496
4497 if (!sofia_private) {
4498 nua_handle_destroy(nh);
4499 }
4500
4501 break;
4502 }
4503
4504 end:
4505
4506 if (gateway) {
4507 sofia_reg_release_gateway(gateway)sofia_reg_release_gateway__("sofia_presence.c", (const char *
)__func__, 4507, gateway);
;
4508 }
4509
4510}
4511
4512
4513static int sofia_presence_send_sql(void *pArg, int argc, char **argv, char **columnNames)
4514{
4515 struct pres_sql_cb *cb = (struct pres_sql_cb *) pArg;
4516
4517
4518 if (mod_sofia_globals.debug_presence > 0) {
4519 int i;
4520 for(i = 0; i < argc; i++) {
4521 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 4521, ((void*)0)
, SWITCH_LOG_CRIT, "arg %d[%s] = [%s]\n", i, columnNames[i], argv[i]);
4522 }
4523 }
4524
4525 send_presence_notify(cb->profile, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], NULL)_send_presence_notify(cb->profile,argv[0],argv[1],argv[2],
argv[3],argv[4],argv[5],argv[6],argv[7],argv[8],argv[9],((void
*)0),"sofia_presence.c", (const char *)__func__, 4525)
;
4526 cb->ttl++;
4527
4528 return 0;
4529}
4530
4531
4532uint32_t sofia_presence_contact_count(sofia_profile_t *profile, const char *contact_str)
4533{
4534 char buf[32] = "";
4535 char *sql;
4536
4537 sql = switch_mprintf("select count(*) from sip_subscriptions where hostname='%q' and profile_name='%q' and contact='%q'",
4538 mod_sofia_globals.hostname, profile->name, contact_str);
4539
4540 sofia_glue_execute_sql2str(profile, profile->dbh_mutex, sql, buf, sizeof(buf));
4541 switch_safe_free(sql)if (sql) {free(sql);sql=((void*)0);};
4542 return atoi(buf);
4543}
4544
4545void sofia_presence_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
4546 sofia_dispatch_event_t *de,
4547 tagi_t tags[])
4548{
4549
4550 sip_from_t const *from;
4551 char *from_user = NULL((void*)0);
4552 char *from_host = NULL((void*)0);
4553 char *rpid = "";
4554 sip_payload_t *payload;
4555 char *event_type = NULL((void*)0);
4556 char etag[9] = "";
4557 char expstr[30] = "";
4558 long exp = 0, exp_delta = 3600;
4559 char *pd_dup = NULL((void*)0);
4560 int count = 1, sub_count = 1;
4561 char *contact_str;
4562 sofia_nat_parse_t np = { { 0 } };
4563
4564 if (!sip) {
4565 return;
4566 }
4567
4568 from = sip->sip_from;
4569 payload = sip->sip_payload;
4570
4571 np.fs_path = 1;
4572 contact_str = sofia_glue_gen_contact_str(profile, sip, nh, de, &np);
4573
4574 if (from) {
4575 from_user = (char *) from->a_url->url_user;
4576 from_host = (char *) from->a_url->url_host;
4577 }
4578
4579 exp_delta = (sip->sip_expires ? sip->sip_expires->ex_delta : 3600);
4580 if ((profile->force_publish_expires > 0) && (profile->force_publish_expires < (uint32_t)exp_delta)) {
4581 exp_delta = profile->force_publish_expires;
4582 }
4583
4584 if (exp_delta < 0) {
4585 exp = exp_delta;
4586 } else {
4587 exp = (long) switch_epoch_time_now(NULL((void*)0)) + exp_delta;
4588 }
4589
4590 if (payload) {
4591 switch_xml_t xml, note, person, tuple, status, basic, act;
4592 switch_event_t *event;
4593 char *sql;
4594 char *full_agent = NULL((void*)0);
4595 char network_ip[80];
4596 int network_port = 0;
4597
4598 sofia_glue_get_addr(de->data->e_msg, network_ip, sizeof(network_ip), &network_port);
4599
4600 pd_dup = strdup(payload->pl_data)(__extension__ (__builtin_constant_p (payload->pl_data) &&
((size_t)(const void *)((payload->pl_data) + 1) - (size_t
)(const void *)(payload->pl_data) == 1) ? (((const char *)
(payload->pl_data))[0] == '\0' ? (char *) calloc ((size_t
) 1, (size_t) 1) : ({ size_t __len = strlen (payload->pl_data
) + 1; char *__retval = (char *) malloc (__len); if (__retval
!= ((void*)0)) __retval = (char *) memcpy (__retval, payload
->pl_data, __len); __retval; })) : __strdup (payload->pl_data
)))
;
4601
4602 if ((xml = switch_xml_parse_str(pd_dup, strlen(pd_dup)))) {
4603 char *open_closed = "", *note_txt = "";
4604
4605 if (sip->sip_user_agent) {
4606 full_agent = sip_header_as_string(nh->nh_home, (void *) sip->sip_user_agent);
4607 }
4608
4609 if ((tuple = switch_xml_child(xml, "tuple")) && (status = switch_xml_child(tuple, "status"))
4610 && (basic = switch_xml_child(status, "basic"))) {
4611 open_closed = basic->txt;
4612
4613 if ((note = switch_xml_child(tuple, "note"))) {
4614 rpid = note_txt = note->txt;
4615 } else if ((note = switch_xml_child(tuple, "dm:note"))) {
4616 rpid = note_txt = note->txt;
4617 }
4618 }
4619
4620 if ((person = switch_xml_child(xml, "dm:person"))) {
4621 if ((note = switch_xml_child(person, "dm:note"))) {
4622 note_txt = note->txt;
4623 } else if ((note = switch_xml_child(person, "rpid:note"))) {
4624 note_txt = note->txt;
4625 }
4626 if ((act = switch_xml_child(person, "rpid:activities")) && act->child && act->child->name) {
4627 if ((rpid = strchr(act->child->name, ':')(__extension__ (__builtin_constant_p (':') && !__builtin_constant_p
(act->child->name) && (':') == '\0' ? (char *)
__rawmemchr (act->child->name, ':') : __builtin_strchr
(act->child->name, ':')))
)) {
4628 rpid++;
4629 } else {
4630 rpid = act->child->name;
4631 }
4632 }
4633 if (zstr(note_txt)_zstr(note_txt)) note_txt = "Available";
4634 }
4635
4636 if (!strcasecmp(open_closed, "closed")) {
4637 rpid = note_txt = "Unregistered";
4638 if (sofia_test_pflag(profile, PFLAG_MULTIREG)((profile)->pflags[PFLAG_MULTIREG] ? 1 : 0)) {
4639 count = sofia_reg_reg_count(profile, from_user, from_host);
4640
4641 if (count != 1) {
4642 /* Don't broadcast offline when there is more than one client or one signing off makes them all appear to sign off on some clients */
4643 count = 0;
4644 } else {
4645 sub_count = sofia_presence_contact_count(profile, contact_str);
4646 }
4647 }
4648 }
4649
4650 event_type = sip_header_as_string(nh->nh_home, (void *) sip->sip_event);
4651
4652 if (count) {
4653 if ((sql = switch_mprintf("delete from sip_presence where sip_user='%q' and sip_host='%q' "
4654 " and profile_name='%q' and hostname='%q'",
4655 from_user, from_host, profile->name, mod_sofia_globals.hostname))) {
4656 sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
4657 }
4658
4659 if (sub_count > 0 && (sql = switch_mprintf("insert into sip_presence (sip_user, sip_host, status, rpid, expires, user_agent,"
4660 " profile_name, hostname, open_closed, network_ip, network_port) "
4661 "values ('%q','%q','%q','%q',%ld,'%q','%q','%q','%q','%q','%d')",
4662 from_user, from_host, note_txt, rpid, exp, full_agent, profile->name,
4663 mod_sofia_globals.hostname, open_closed, network_ip, network_port))) {
4664
4665 sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
4666 }
4667
4668 } else if (contact_str) {
4669 struct pres_sql_cb cb = {profile, 0};
4670
4671 sql = switch_mprintf("select full_to, full_from, contact, expires, call_id, event, network_ip, network_port, "
4672 "'application/pidf+xml' as ct,'%q' as pt "
4673 " from sip_subscriptions where "
4674 "hostname='%q' and profile_name='%q' and sub_to_user='%q' and sub_to_host='%q' and event='%q'"
4675 "and contact = '%q' ",
4676
4677 switch_str_nil(payload->pl_data)(payload->pl_data ? payload->pl_data : ""),
4678 mod_sofia_globals.hostname, profile->name,
4679 from_user, from_host, event_type, contact_str);
4680
4681 sofia_glue_execute_sql_callback(profile, profile->dbh_mutex, sql, sofia_presence_send_sql, &cb);
4682 switch_safe_free(sql)if (sql) {free(sql);sql=((void*)0);};
4683 }
4684
4685 if (sub_count > 0) {
4686 if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_IN)switch_event_create_subclass_detailed("sofia_presence.c", (const
char * )(const char *)__func__, 4686, &event, SWITCH_EVENT_PRESENCE_IN
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
4687 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", SOFIA_CHAT_PROTO"sip");
4688 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "rpid", rpid);
4689 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "login", profile->url);
4690 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "sip_profile", profile->name);
4691 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "user-agent", full_agent);
4692 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s@%s", from_user, from_host);
4693 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "status", note_txt);
4694 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "event_type", event_type);
4695 switch_event_fire(&event)switch_event_fire_detailed("sofia_presence.c", (const char * )
(const char *)__func__, 4695, &event, ((void*)0))
;
4696 }
4697 }
4698
4699 if (event_type) {
4700 su_free(nh->nh_home, event_type);
4701 }
4702
4703 if (full_agent) {
4704 su_free(nh->nh_home, full_agent);
4705 }
4706
4707 switch_xml_free(xml);
4708 }
4709 } else {
4710 char *sql = switch_mprintf("update sip_presence set expires=%ld where sip_user='%q' and sip_host='%q' and profile_name='%q' and hostname='%q'",
4711 exp, from_user, from_host, profile->name, mod_sofia_globals.hostname);
4712 sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
4713 }
4714
4715 switch_safe_free(pd_dup)if (pd_dup) {free(pd_dup);pd_dup=((void*)0);};
4716
4717 switch_snprintf(expstr, sizeof(expstr), "%d", exp_delta);
4718 switch_stun_random_string(etag, 8, NULL((void*)0));
4719
4720 if (sub_count > 0) {
4721 nua_respond(nh, SIP_200_OK200, sip_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg)nutag_with, tag_ptr_v(de->data->e_msg), SIPTAG_ETAG_STR(etag)siptag_etag_str, tag_str_v(etag), SIPTAG_EXPIRES_STR(expstr)siptag_expires_str, tag_str_v(expstr), TAG_END()(tag_type_t)0, (tag_value_t)0);
4722 } else {
4723 nua_respond(nh, SIP_404_NOT_FOUND404, sip_404_Not_found, NUTAG_WITH_THIS_MSG(de->data->e_msg)nutag_with, tag_ptr_v(de->data->e_msg), TAG_END()(tag_type_t)0, (tag_value_t)0);
4724 }
4725
4726 switch_safe_free(contact_str)if (contact_str) {free(contact_str);contact_str=((void*)0);};
4727}
4728
4729void sofia_presence_set_hash_key(char *hash_key, int32_t len, sip_t const *sip)
4730{
4731 url_t *to = sip->sip_to->a_url;
4732 url_t *from = sip->sip_from->a_url;
4733 switch_snprintf(hash_key, len, "%s%s%s", from->url_user, from->url_host, to->url_user);
4734}
4735
4736void sofia_presence_handle_sip_i_message(int status,
4737 char const *phrase,
4738 nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh,
4739 switch_core_session_t *session,
4740 sofia_private_t *sofia_private, sip_t const *sip,
4741 sofia_dispatch_event_t *de,
4742 tagi_t tags[])
4743{
4744
4745 if (sip) {
4746 sip_from_t const *from = sip->sip_from;
4747 const char *from_user = NULL((void*)0);
4748 const char *from_host = NULL((void*)0);
4749 sip_to_t const *to = sip->sip_to;
4750 const char *to_user = NULL((void*)0);
4751 const char *to_host = NULL((void*)0);
4752 sip_payload_t *payload = sip->sip_payload;
4753 char *msg = NULL((void*)0);
4754 const char *us;
4755 char network_ip[80];
4756 int network_port = 0;
4757 switch_channel_t *channel = NULL((void*)0);
4758
4759
4760 if (!sofia_test_pflag(profile, PFLAG_ENABLE_CHAT)((profile)->pflags[PFLAG_ENABLE_CHAT] ? 1 : 0)) {
4761 goto end;
4762 }
4763
4764
4765 if (session) {
4766 channel = switch_core_session_get_channel(session);
4767 }
4768
4769 if (sofia_test_pflag(profile, PFLAG_AUTH_MESSAGES)((profile)->pflags[PFLAG_AUTH_MESSAGES] ? 1 : 0) && sip){
4770 sip_authorization_t const *authorization = NULL((void*)0);
4771 auth_res_t auth_res = AUTH_FORBIDDEN;
4772 char keybuf[128] = "";
4773 char *key;
4774 size_t keylen;
4775 switch_event_t *v_event = NULL((void*)0);
4776
4777 key = keybuf;
4778 keylen = sizeof(keybuf);
4779
4780 if (sip->sip_authorization) {
4781 authorization = sip->sip_authorization;
4782 } else if (sip->sip_proxy_authorization) {
4783 authorization = sip->sip_proxy_authorization;
4784 }
4785
4786 if (authorization) {
4787 char network_ip[80];
4788 int network_port;
4789 sofia_glue_get_addr(de->data->e_msg, network_ip, sizeof(network_ip), &network_port);
4790 auth_res = sofia_reg_parse_auth(profile, authorization, sip, de,
4791 (char *) sip->sip_request->rq_method_name, key, keylen, network_ip, network_port, NULL((void*)0), 0,
4792 REG_INVITE, NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0));
4793 } else if ( sofia_reg_handle_register(nua, profile, nh, sip, de, REG_INVITE, key, (uint32_t)keylen, &v_event, NULL, NULL, NULL)sofia_reg_handle_register_token(nua, profile, nh, sip, de, REG_INVITE
, key, (uint32_t)keylen, &v_event, ((void*)0), ((void*)0)
, ((void*)0), ((void*)0))
) {
4794 if (v_event) {
4795 switch_event_destroy(&v_event);
4796 }
4797
4798 goto end;
4799 }
4800
4801 if ((auth_res != AUTH_OK && auth_res != AUTH_RENEWED)) {
4802 nua_respond(nh, SIP_401_UNAUTHORIZED401, sip_401_Unauthorized, NUTAG_WITH_THIS_MSG(de->data->e_msg)nutag_with, tag_ptr_v(de->data->e_msg), TAG_END()(tag_type_t)0, (tag_value_t)0);
4803 goto end;
4804 }
4805
4806 if (channel) {
4807 switch_channel_set_variable(channel, "sip_authorized", "true")switch_channel_set_variable_var_check(channel, "sip_authorized"
, "true", SWITCH_TRUE)
;
4808 }
4809 }
4810
4811 if ((us = sofia_glue_get_unknown_header(sip, "X-FS-Sending-Message")) && !strcmp(us, switch_core_get_uuid())__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(us) && __builtin_constant_p (switch_core_get_uuid()
) && (__s1_len = __builtin_strlen (us), __s2_len = __builtin_strlen
(switch_core_get_uuid()), (!((size_t)(const void *)((us) + 1
) - (size_t)(const void *)(us) == 1) || __s1_len >= 4) &&
(!((size_t)(const void *)((switch_core_get_uuid()) + 1) - (size_t
)(const void *)(switch_core_get_uuid()) == 1) || __s2_len >=
4)) ? __builtin_strcmp (us, switch_core_get_uuid()) : (__builtin_constant_p
(us) && ((size_t)(const void *)((us) + 1) - (size_t)
(const void *)(us) == 1) && (__s1_len = __builtin_strlen
(us), __s1_len < 4) ? (__builtin_constant_p (switch_core_get_uuid
()) && ((size_t)(const void *)((switch_core_get_uuid(
)) + 1) - (size_t)(const void *)(switch_core_get_uuid()) == 1
) ? __builtin_strcmp (us, switch_core_get_uuid()) : (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) (switch_core_get_uuid()); int __result = (((const unsigned
char *) (const char *) (us))[0] - __s2[0]); if (__s1_len >
0 && __result == 0) { __result = (((const unsigned char
*) (const char *) (us))[1] - __s2[1]); if (__s1_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (us))[2] - __s2[2]); if (__s1_len > 2 && __result
== 0) __result = (((const unsigned char *) (const char *) (us
))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p (
switch_core_get_uuid()) && ((size_t)(const void *)((switch_core_get_uuid
()) + 1) - (size_t)(const void *)(switch_core_get_uuid()) == 1
) && (__s2_len = __builtin_strlen (switch_core_get_uuid
()), __s2_len < 4) ? (__builtin_constant_p (us) &&
((size_t)(const void *)((us) + 1) - (size_t)(const void *)(us
) == 1) ? __builtin_strcmp (us, switch_core_get_uuid()) : (- (
__extension__ ({ const unsigned char *__s2 = (const unsigned char
*) (const char *) (us); int __result = (((const unsigned char
*) (const char *) (switch_core_get_uuid()))[0] - __s2[0]); if
(__s2_len > 0 && __result == 0) { __result = (((const
unsigned char *) (const char *) (switch_core_get_uuid()))[1]
- __s2[1]); if (__s2_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) (switch_core_get_uuid
()))[2] - __s2[2]); if (__s2_len > 2 && __result ==
0) __result = (((const unsigned char *) (const char *) (switch_core_get_uuid
()))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (us
, switch_core_get_uuid())))); })
) {
4812 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 4812, ((void*)0)
, SWITCH_LOG_WARNING, "Not sending message to ourselves!\n");
4813 nua_respond(nh, SIP_503_SERVICE_UNAVAILABLE503, sip_503_Service_unavailable, NUTAG_WITH_THIS_MSG(de->data->e_msg)nutag_with, tag_ptr_v(de->data->e_msg), TAG_END()(tag_type_t)0, (tag_value_t)0);
4814 return;
4815 }
4816
4817 if (sip->sip_content_type && sip->sip_content_type->c_subtype) {
4818 if (strstr(sip->sip_content_type->c_subtype, "composing")) {
4819 goto end;
4820 }
4821 }
4822
4823
4824 sofia_glue_get_addr(de->data->e_msg, network_ip, sizeof(network_ip), &network_port);
4825
4826
4827 if (from) {
4828 from_user = from->a_url->url_user;
4829 from_host = from->a_url->url_host;
4830 }
4831
4832 if (to) {
4833 to_user = to->a_url->url_user;
4834 to_host = to->a_url->url_host;
4835 }
4836
4837 if (!to_user) {
4838 goto end;
4839 }
4840
4841 if (payload) {
4842 msg = payload->pl_data;
4843 }
4844
4845 if (nh) {
4846 char hash_key[512];
4847 private_object_t *tech_pvt;
4848 switch_event_t *event, *event_dup;
4849 char *to_addr;
4850 char *from_addr;
4851 char *p;
4852 char *full_from;
4853 char proto[512] = SOFIA_CHAT_PROTO"sip";
4854 sip_unknown_t *un;
4855 int first_history_info = 1;
4856
4857 full_from = sip_header_as_string(nh->nh_home, (void *) sip->sip_from);
4858
4859 if ((p = strchr(to_user, '+')(__extension__ (__builtin_constant_p ('+') && !__builtin_constant_p
(to_user) && ('+') == '\0' ? (char *) __rawmemchr (to_user
, '+') : __builtin_strchr (to_user, '+')))
) && p != to_user) {
4860 switch_copy_string(proto, to_user, sizeof(proto));
4861 p = strchr(proto, '+')(__extension__ (__builtin_constant_p ('+') && !__builtin_constant_p
(proto) && ('+') == '\0' ? (char *) __rawmemchr (proto
, '+') : __builtin_strchr (proto, '+')))
;
4862 *p++ = '\0';
4863
4864 if ((to_addr = strdup(p)(__extension__ (__builtin_constant_p (p) && ((size_t)
(const void *)((p) + 1) - (size_t)(const void *)(p) == 1) ? (
((const char *) (p))[0] == '\0' ? (char *) calloc ((size_t) 1
, (size_t) 1) : ({ size_t __len = strlen (p) + 1; char *__retval
= (char *) malloc (__len); if (__retval != ((void*)0)) __retval
= (char *) memcpy (__retval, p, __len); __retval; })) : __strdup
(p)))
)) {
4865 if ((p = strchr(to_addr, '+')(__extension__ (__builtin_constant_p ('+') && !__builtin_constant_p
(to_addr) && ('+') == '\0' ? (char *) __rawmemchr (to_addr
, '+') : __builtin_strchr (to_addr, '+')))
)) {
4866 *p = '@';
4867 }
4868 }
4869 } else {
4870 to_addr = switch_mprintf("%s@%s", to_user, to_host);
4871 }
4872
4873 from_addr = switch_mprintf("%s@%s", from_user, from_host);
4874
4875 if (sofia_test_pflag(profile, PFLAG_IN_DIALOG_CHAT)((profile)->pflags[PFLAG_IN_DIALOG_CHAT] ? 1 : 0)) {
4876 sofia_presence_set_hash_key(hash_key, sizeof(hash_key), sip);
4877 }
4878
4879 if (switch_event_create(&event, SWITCH_EVENT_MESSAGE)switch_event_create_subclass_detailed("sofia_presence.c", (const
char * )(const char *)__func__, 4879, &event, SWITCH_EVENT_MESSAGE
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
4880 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "login", profile->url);
4881 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", SOFIA_CHAT_PROTO"sip");
4882
4883 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "to_proto", proto);
4884
4885 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "from", from_addr);
4886 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "from_user", from_user);
4887 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "from_host", from_host);
4888 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "to_user", to_user);
4889 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "to_host", to_host);
4890 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "from_sip_ip", network_ip);
4891 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from_sip_port", "%d", network_port);
4892 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "to", to_addr);
4893 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "subject", "SIMPLE MESSAGE");
4894 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "context", profile->context);
4895
4896 if (sip->sip_content_type && sip->sip_content_type->c_subtype) {
4897 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", sip->sip_content_type->c_type);
4898 } else {
4899 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "text/plain");
4900 }
4901
4902 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "from_full", full_from);
4903 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "sip_profile", profile->name);
4904
4905
4906 if (sip->sip_call_info) {
4907 sip_call_info_t *call_info = sip->sip_call_info;
4908 char *ci = sip_header_as_string(nua_handle_home(nh)((su_home_t *)(nh)), (void *) call_info);
4909 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "sip_call_info", ci);
4910 }
4911
4912 /* Loop thru unknown Headers Here so we can do something with them */
4913 for (un = sip->sip_unknown; un; un = un->un_next) {
4914 if (!strncasecmp(un->un_name, "Diversion", 9)) {
4915 /* Basic Diversion Support for Diversion Indication in SIP */
4916 /* draft-levy-sip-diversion-08 */
4917 if (!zstr(un->un_value)_zstr(un->un_value)) {
4918 char *tmp_name;
4919 if ((tmp_name = switch_mprintf("%s%s", SOFIA_SIP_HEADER_PREFIX"sip_h_", un->un_name))) {
4920 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, tmp_name, un->un_value);
4921 free(tmp_name);
4922 }
4923 }
4924 } else if (!strncasecmp(un->un_name, "History-Info", 12)) {
4925 if (first_history_info) {
4926 /* If the header exists first time, make sure to remove old info and re-set the variable */
4927 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "sip_history_info", un->un_value);
4928 first_history_info = 0;
4929 } else {
4930 /* Append the History-Info into one long string */
4931 const char *history_var = switch_channel_get_variable(channel, "sip_history_info")switch_channel_get_variable_dup(channel, "sip_history_info", SWITCH_TRUE
, -1)
;
4932 if (!zstr(history_var)_zstr(history_var)) {
4933 char *tmp_str;
4934 if ((tmp_str = switch_mprintf("%s, %s", history_var, un->un_value))) {
4935 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "sip_history_info", tmp_str);
4936 free(tmp_str);
4937 } else {
4938 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "sip_history_info", un->un_value);
4939 }
4940 } else {
4941 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "sip_history_info", un->un_value);
4942 }
4943 }
4944 } else if (!strcasecmp(un->un_name, "Geolocation")) {
4945 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "sip_geolocation", un->un_value);
4946 } else if (!strcasecmp(un->un_name, "Geolocation-Error")) {
4947 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "sip_geolocation_error", un->un_value);
4948 } else if (!strncasecmp(un->un_name, "X-", 2) || !strncasecmp(un->un_name, "P-", 2) || !strcasecmp(un->un_name, "User-to-User")) {
4949 if (!zstr(un->un_value)_zstr(un->un_value)) {
4950 char new_name[512] = "";
4951 int reps = 0;
4952 for (;;) {
4953 char postfix[25] = "";
4954 if (reps > 0) {
4955 switch_snprintf(postfix, sizeof(postfix), "-%d", reps);
4956 }
4957 reps++;
4958 switch_snprintf(new_name, sizeof(new_name), "%s%s%s", SOFIA_SIP_HEADER_PREFIX"sip_h_", un->un_name, postfix);
4959
4960 if (switch_event_get_header(event, new_name)switch_event_get_header_idx(event, new_name, -1)) {
4961 continue;
4962 }
4963
4964 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, new_name, un->un_value);
4965 break;
4966 }
4967 }
4968 }
4969 }
4970
4971 if (msg) {
4972 switch_event_add_body(event, "%s", msg);
4973 }
4974
4975 if (channel) {
4976 switch_channel_event_set_data(channel, event);
4977 }
4978
4979
4980 if (sofia_test_pflag(profile, PFLAG_FIRE_MESSAGE_EVENTS)((profile)->pflags[PFLAG_FIRE_MESSAGE_EVENTS] ? 1 : 0)) {
4981 if (switch_event_dup(&event_dup, event) == SWITCH_STATUS_SUCCESS) {
4982 event_dup->event_id = SWITCH_EVENT_RECV_MESSAGE;
4983 event_dup->flags |= EF_UNIQ_HEADERS;
4984 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Event-Name", switch_event_name(event->event_id));
4985 switch_event_fire(&event_dup)switch_event_fire_detailed("sofia_presence.c", (const char * )
(const char *)__func__, 4985, &event_dup, ((void*)0))
;
4986 }
4987 }
4988
4989 if (session) {
4990 if (switch_event_dup(&event_dup, event) == SWITCH_STATUS_SUCCESS) {
4991 switch_core_session_queue_event(session, &event_dup);
4992 }
4993 }
4994
4995
4996 } else {
4997 abort();
4998 }
4999
5000 if (sofia_test_pflag(profile, PFLAG_IN_DIALOG_CHAT)((profile)->pflags[PFLAG_IN_DIALOG_CHAT] ? 1 : 0) && (tech_pvt = (private_object_t *) switch_core_hash_find(profile->chat_hash, hash_key))) {
5001 switch_core_session_queue_event(tech_pvt->session, &event);
5002 } else {
5003 switch_core_chat_send(proto, event);
5004 switch_event_destroy(&event);
5005 }
5006
5007 switch_safe_free(to_addr)if (to_addr) {free(to_addr);to_addr=((void*)0);};
5008 switch_safe_free(from_addr)if (from_addr) {free(from_addr);from_addr=((void*)0);};
5009
5010 if (full_from) {
5011 su_free(nh->nh_home, full_from);
5012 }
5013 }
5014 }
5015
5016 end:
5017
5018 if (sofia_test_pflag(profile, PFLAG_MESSAGES_RESPOND_200_OK)((profile)->pflags[PFLAG_MESSAGES_RESPOND_200_OK] ? 1 : 0)) {
5019 nua_respond(nh, SIP_200_OK200, sip_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg)nutag_with, tag_ptr_v(de->data->e_msg), TAG_END()(tag_type_t)0, (tag_value_t)0);
5020 } else {
5021 nua_respond(nh, SIP_202_ACCEPTED202, sip_202_Accepted, NUTAG_WITH_THIS_MSG(de->data->e_msg)nutag_with, tag_ptr_v(de->data->e_msg), TAG_END()(tag_type_t)0, (tag_value_t)0);
5022 }
5023
5024}
5025
5026void sofia_presence_set_chat_hash(private_object_t *tech_pvt, sip_t const *sip)
5027{
5028 char hash_key[256] = "";
5029 char buf[512];
5030 su_home_t *home = NULL((void*)0);
5031
5032 if (!tech_pvt || tech_pvt->hash_key || !sip || !sip->sip_from || !sip->sip_from->a_url ||
5033 !sip->sip_from->a_url->url_user || !sip->sip_from->a_url->url_host) {
5034 return;
5035 }
5036
5037 if (sofia_reg_find_reg_url(tech_pvt->profile, sip->sip_from->a_url->url_user, sip->sip_from->a_url->url_host, buf, sizeof(buf))) {
5038 home = su_home_new(sizeof(*home));
5039 switch_assert(home != NULL)((home != ((void*)0)) ? (void) (0) : __assert_fail ("home != ((void*)0)"
, "sofia_presence.c", 5039, __PRETTY_FUNCTION__))
;
5040 tech_pvt->chat_from = sip_header_as_string(home, (const sip_header_t *) sip->sip_to);
5041 tech_pvt->chat_to = switch_core_session_strdup(tech_pvt->session, buf)switch_core_perform_session_strdup(tech_pvt->session, buf,
"sofia_presence.c", (const char *)__func__, 5041)
;
5042 sofia_presence_set_hash_key(hash_key, sizeof(hash_key), sip);
5043 su_home_unref(home);
5044 home = NULL((void*)0);
5045 } else {
5046 return;
5047 }
5048
5049 switch_mutex_lock(tech_pvt->profile->flag_mutex);
5050 tech_pvt->hash_key = switch_core_session_strdup(tech_pvt->session, hash_key)switch_core_perform_session_strdup(tech_pvt->session, hash_key
, "sofia_presence.c", (const char *)__func__, 5050)
;
5051 switch_core_hash_insert(tech_pvt->profile->chat_hash, tech_pvt->hash_key, tech_pvt)switch_core_hash_insert_destructor(tech_pvt->profile->chat_hash
, tech_pvt->hash_key, tech_pvt, ((void*)0))
;
5052 switch_mutex_unlock(tech_pvt->profile->flag_mutex);
5053}
5054
5055
5056void sofia_presence_check_subscriptions(sofia_profile_t *profile, time_t now)
5057{
5058 char *sql;
5059
5060 if (now) {
5061 struct pres_sql_cb cb = {profile, 0};
5062
5063 if (profile->pres_type != PRES_TYPE_FULL) {
5064 if (mod_sofia_globals.debug_presence > 0) {
5065 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 5065, ((void*)0)
, SWITCH_LOG_WARNING, "check_subs: %s is passive, skipping\n", (char *) profile->name);
5066 }
5067 return;
5068 }
5069
5070 sql = switch_mprintf("update sip_subscriptions set version=version+1 where "
5071 "((expires > 0 and expires <= %ld)) and profile_name='%q' and hostname='%q'",
5072 (long) now, profile->name, mod_sofia_globals.hostname);
5073
5074 sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
5075 switch_safe_free(sql)if (sql) {free(sql);sql=((void*)0);};
5076
5077 sql = switch_mprintf("select full_to, full_from, contact, -1, call_id, event, network_ip, network_port, "
5078 "NULL as ct, NULL as pt "
5079 " from sip_subscriptions where ((expires > 0 and expires <= %ld)) and profile_name='%q' and hostname='%q'",
5080 (long) now, profile->name, mod_sofia_globals.hostname);
5081
5082 sofia_glue_execute_sql_callback(profile, profile->dbh_mutex, sql, sofia_presence_send_sql, &cb);
5083 switch_safe_free(sql)if (sql) {free(sql);sql=((void*)0);};
5084
5085 if (cb.ttl) {
5086 sql = switch_mprintf("delete from sip_subscriptions where ((expires > 0 and expires <= %ld)) "
5087 "and profile_name='%q' and hostname='%q'",
5088 (long) now, profile->name, mod_sofia_globals.hostname);
5089
5090 if (mod_sofia_globals.debug_presence > 0 || mod_sofia_globals.debug_sla > 0) {
5091 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "sofia_presence.c", (const char *)__func__
, 5091, ((void*)0)
, SWITCH_LOG_ERROR,
5092 "sub del sql: %s\n", sql);
5093 }
5094
5095 sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
5096 }
5097 }
5098
5099
5100
5101}
5102
5103
5104/* For Emacs:
5105 * Local Variables:
5106 * mode:c
5107 * indent-tabs-mode:t
5108 * tab-width:4
5109 * c-basic-offset:4
5110 * End:
5111 * For VIM:
5112 * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
5113 */