136{
144 char *geoloc_hdr_value =
NULL;
145 char *geoloc_routing_hdr_value =
NULL;
146 char *geoloc_uri =
NULL;
147 int rc = 0;
149 pjsip_generic_string_hdr *geoloc_hdr =
NULL;
150 pjsip_generic_string_hdr *geoloc_routing_hdr =
NULL;
152
155 session_name);
156 }
157 if (!endpoint) {
159 session_name);
160 }
161
162 if (!channel) {
164 session_name);
165 }
166
167 if (!rdata) {
169 session_name);
170 }
171
172
173
174
175
177 geoloc_routing_hdr = pjsip_msg_find_hdr_by_name(rdata->msg_info.msg,
179
180 if (!geoloc_hdr) {
181 ast_trace(4,
"%s: Message has no Geolocation header\n", session_name);
182 } else {
185 }
186
188 if (geoloc_hdr) {
191 "Done.\n", session_name,
193 } else {
195 "Done.\n", session_name);
196 }
197 }
198
200 if (!config_profile) {
201 if (geoloc_hdr) {
203 PJSTR_PRINTF_SPEC "' but endpoint's geoloc_incoming_call_profile doesn't exist. "
204 "Done.\n", session_name,
206 } else {
208 " an invalid geoloc_incoming_call_profile. Done.\n", session_name);
209 }
210 }
211
215 }
216
219 if (!config_eprofile) {
222 }
223
224 if (config_eprofile && config_eprofile->effective_location) {
225 ast_trace(4,
"%s: config eprofile '%s' has effective location\n",
226 session_name, config_eprofile->id);
227
230
231 ast_trace(4,
"%s: config eprofile '%s' is being used\n",
232 session_name, config_eprofile->id);
233
234
235
236
237
238
239
240
242 if (rc != 0) {
244 "%s: Couldn't add config eprofile '%s' to datastore. Fail.\n", session_name,
245 config_eprofile->id);
246 }
247
249 session_name);
250 }
251 } else {
252
253
254
255
256 ast_trace(4,
"%s: Either config_eprofile didn't exist or it had no effective location\n",
257 session_name);
258
260 config_eprofile =
NULL;
263 session_name);
264 }
265 }
266 }
267
268
269
270
271
272
273
275
276
277
278
279
280
281
282
283
284
285
286
287
288 geoloc_hdr_value =
ast_alloca(geoloc_hdr->hvalue.slen + 1);
289 ast_copy_pj_str(geoloc_hdr_value, &geoloc_hdr->hvalue, geoloc_hdr->hvalue.slen + 1);
290
291
292
293
294
295
296 while (geoloc_hdr_value && !incoming_eprofile) {
297 char *pidf_body =
NULL;
298 unsigned int pidf_len = 0;
299 struct ast_xml_doc *incoming_doc =
NULL;
300 int rc = 0;
301
302
304 if (
ast_strlen_zero(geoloc_uri) || geoloc_uri[0] !=
'<' || strchr(geoloc_uri,
'>') ==
NULL) {
305 ast_log(
LOG_WARNING,
"%s: Geolocation header has no or bad URI '%s'. Skipping\n", session_name,
306 S_OR(geoloc_uri,
"<empty>"));
307 continue;
308 }
309
310 ast_trace(4,
"Processing URI '%s'\n", geoloc_uri);
311
313 ast_trace(4,
"Processing URI '%s'\n", geoloc_uri);
314
316 if (!incoming_eprofile) {
317 ast_log(
LOG_WARNING,
"%s: Unable to create effective profile for URI '%s'. Skipping\n",
318 session_name, geoloc_uri);
319 continue;
320 }
321 } else {
322 ast_trace(4,
"Processing PIDF-LO '%s'\n", geoloc_uri);
323
324 rc =
find_pidf(session_name, rdata, geoloc_uri, &pidf_body, &pidf_len);
325 if (rc != 0 || !pidf_body || pidf_len == 0) {
326 continue;
327 }
329
331 if (!incoming_doc) {
333 session_name, geoloc_uri);
334 continue;
335 }
336
339
340 if (!incoming_eprofile) {
342 "%s: Couldn't create incoming_eprofile from pidf\n", session_name);
343 continue;
344 }
345 }
346 }
347 }
348
349 if (!incoming_eprofile) {
350
351 incoming_eprofile = config_eprofile;
352 } else {
354 config_eprofile =
NULL;
355 if (geoloc_routing_hdr) {
356 geoloc_routing_hdr_value =
ast_alloca(geoloc_routing_hdr->hvalue.slen + 1);
358 geoloc_routing_hdr->hvalue.slen + 1);
359 incoming_eprofile->allow_routing_use =
ast_true(geoloc_routing_hdr_value);
360 }
361 }
362
363 if (incoming_eprofile) {
365 if (rc != 0) {
367 "%s: Couldn't add eprofile '%s' to channel. Fail.\n", session_name,
368 incoming_eprofile->id);
369 }
370
372 session_name, incoming_eprofile->id);
373 }
374
376}
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
@ AST_GEOLOC_PRECED_DISCARD_CONFIG
@ AST_GEOLOC_PRECED_PREFER_CONFIG
@ AST_GEOLOC_PRECED_DISCARD_INCOMING
struct ast_geoloc_eprofile * ast_geoloc_eprofile_create_from_pidf(struct ast_xml_doc *pidf_xmldoc, const char *geoloc_uri, const char *reference_string)
Allocate a new effective profile from an XML PIDF-LO document.
struct ast_geoloc_eprofile * ast_geoloc_eprofile_create_from_uri(const char *uri, const char *reference_string)
Allocate a new effective profile from a URI.
struct ast_geoloc_profile * ast_geoloc_get_profile(const char *id)
Retrieve a geolocation profile by id.
struct ast_geoloc_eprofile * ast_geoloc_eprofile_create_from_profile(struct ast_geoloc_profile *profile)
Allocate a new effective profile from an existing profile.
void ast_copy_pj_str(char *dest, const pj_str_t *src, size_t size)
Copy a pj_str_t into a standard character buffer.
#define PJSTR_PRINTF_VAR(_v)
#define PJSTR_PRINTF_SPEC
static pj_str_t GEOLOCATION_ROUTING_HDR
static int add_eprofile_to_channel(struct ast_sip_session *session, struct ast_geoloc_eprofile *eprofile, struct ast_str *buf)
static pj_str_t GEOLOCATION_HDR
static int find_pidf(const char *session_name, struct pjsip_rx_data *rdata, char *geoloc_uri, char **pidf_body, unsigned int *pidf_len)
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true"....
static force_inline int attribute_pure ast_strlen_zero(const char *s)
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
static int force_inline attribute_pure ast_begins_with(const char *str, const char *prefix)
Checks whether a string begins with another.
char * ast_strsep(char **s, const char sep, uint32_t flags)
Act like strsep but ignore separators inside quotes.
Main Channel structure associated with a channel.
An entity with which Asterisk communicates.
Support for dynamic strings.
void ast_xml_close(struct ast_xml_doc *doc)
Close an already open document and free the used structure.
struct ast_xml_doc * ast_xml_read_memory(char *buffer, size_t size)
Open an XML document that resides in memory.