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    }
  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_eprofile * ast_geoloc_eprofile_create_from_profile(struct ast_geoloc_profile *profile)
Allocate a new effective profile from an existing profile.
struct ast_geoloc_profile *AST_OPTIONAL_API_NAME() ast_geoloc_get_profile(const char *id)
Retrieve a geolocation profile by id.
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.
struct ast_endpoint * endpoint
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.