Asterisk - The Open Source Telephony Project GIT-master-7e7a603
Data Structures | Macros | Enumerations | Functions
res_geolocation.h File Reference
#include "asterisk/channel.h"
#include "asterisk/config.h"
#include "asterisk/sorcery.h"
#include "asterisk/xml.h"
#include "asterisk/optional_api.h"
Include dependency graph for res_geolocation.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  ast_geoloc_eprofile
 
struct  ast_geoloc_location
 
struct  ast_geoloc_profile
 

Macros

#define AST_GEOLOC_INVALID_VALUE   -1
 
#define CONFIG_STR_TO_ENUM_DECL(_stem)   int ast_geoloc_ ## _stem ## _str_to_enum(const char *str);
 
#define GEOLOC_ENUM_TO_NAME_DECL(_stem)   const char * ast_geoloc_ ## _stem ## _to_name(int ix);
 

Enumerations

enum  ast_geoloc_format {
  AST_GEOLOC_FORMAT_NONE = 0 , AST_GEOLOC_FORMAT_CIVIC_ADDRESS , AST_GEOLOC_FORMAT_GML , AST_GEOLOC_FORMAT_URI ,
  AST_GEOLOC_FORMAT_LAST
}
 
enum  ast_geoloc_pidf_element {
  AST_PIDF_ELEMENT_NONE = 0 , AST_PIDF_ELEMENT_DEVICE , AST_PIDF_ELEMENT_TUPLE , AST_PIDF_ELEMENT_PERSON ,
  AST_PIDF_ELEMENT_LAST
}
 
enum  ast_geoloc_precedence { AST_GEOLOC_PRECED_PREFER_INCOMING = 0 , AST_GEOLOC_PRECED_PREFER_CONFIG , AST_GEOLOC_PRECED_DISCARD_INCOMING , AST_GEOLOC_PRECED_DISCARD_CONFIG }
 
enum  ast_geoloc_validate_result {
  AST_GEOLOC_VALIDATE_INVALID_VALUE = -1 , AST_GEOLOC_VALIDATE_SUCCESS = 0 , AST_GEOLOC_VALIDATE_MISSING_SHAPE , AST_GEOLOC_VALIDATE_INVALID_SHAPE ,
  AST_GEOLOC_VALIDATE_INVALID_VARNAME , AST_GEOLOC_VALIDATE_NOT_ENOUGH_VARNAMES , AST_GEOLOC_VALIDATE_TOO_MANY_VARNAMES
}
 

Functions

int ast_geoloc_civicaddr_is_code_valid (const char *code)
 Given a civicAddress code, check whether it's valid. More...
 
enum ast_geoloc_validate_result ast_geoloc_civicaddr_validate_varlist (const struct ast_variable *varlist, const char **result)
 Validate that the names of the variables in the list are valid codes or synonyms. More...
 
struct ast_geoloc_locationast_geoloc_get_location (const char *id)
 Retrieve a geolocation location object by id. More...
 
struct ast_geoloc_profileast_geoloc_get_profile (const char *id)
 Retrieve a geolocation profile by id. More...
 
enum ast_geoloc_validate_result ast_geoloc_gml_validate_varlist (const struct ast_variable *varlist, const char **result)
 Validate that the variables in the list represent a valid GML shape. More...
 
int ast_geoloc_is_loaded (void)
 Check if res_geolocation is available. More...
 
const char * ast_geoloc_validate_result_to_str (enum ast_geoloc_validate_result result)
 
 CONFIG_STR_TO_ENUM_DECL (format)
 
 CONFIG_STR_TO_ENUM_DECL (precedence)
 
 GEOLOC_ENUM_TO_NAME_DECL (format)
 
 GEOLOC_ENUM_TO_NAME_DECL (precedence)
 
int ast_geoloc_datastore_add_eprofile (struct ast_datastore *ds, struct ast_geoloc_eprofile *eprofile)
 Add an eprofile to a datastore. More...
 
struct ast_datastoreast_geoloc_datastore_create (const char *id)
 Create an empty geoloc datastore. More...
 
struct ast_datastoreast_geoloc_datastore_create_from_eprofile (struct ast_geoloc_eprofile *eprofile)
 Create a geoloc datastore from an effective profile. More...
 
struct ast_datastoreast_geoloc_datastore_create_from_profile_name (const char *profile_name)
 Geolocation datastore Functions. More...
 
int ast_geoloc_datastore_delete_eprofile (struct ast_datastore *ds, int ix)
 Delete a specific eprofile from a datastore by index. More...
 
struct ast_datastoreast_geoloc_datastore_find (struct ast_channel *chan)
 Retrieves the geoloc datastore from a channel, if any. More...
 
struct ast_geoloc_eprofileast_geoloc_datastore_get_eprofile (struct ast_datastore *ds, int ix)
 Retrieve a specific eprofile from a datastore by index. More...
 
const char * ast_geoloc_datastore_get_id (struct ast_datastore *ds)
 Retrieve a geoloc datastore's id. More...
 
int ast_geoloc_datastore_insert_eprofile (struct ast_datastore *ds, struct ast_geoloc_eprofile *eprofile, int index)
 Insert an eprofile to a datastore at the specified position. More...
 
int ast_geoloc_datastore_set_inheritance (struct ast_datastore *ds, int inherit)
 Sets the inheritance flag on the datastore. More...
 
int ast_geoloc_datastore_size (struct ast_datastore *ds)
 Retrieves the number of eprofiles in the datastore. More...
 
struct ast_geoloc_eprofileast_geoloc_eprofile_alloc (const char *name)
 Geolocation Effective Profile Functions. More...
 
struct ast_geoloc_eprofileast_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. More...
 
struct ast_geoloc_eprofileast_geoloc_eprofile_create_from_profile (struct ast_geoloc_profile *profile)
 Allocate a new effective profile from an existing profile. More...
 
struct ast_geoloc_eprofileast_geoloc_eprofile_create_from_uri (const char *uri, const char *reference_string)
 Allocate a new effective profile from a URI. More...
 
struct ast_geoloc_eprofileast_geoloc_eprofile_dup (struct ast_geoloc_eprofile *src)
 Duplicate an effective profile. More...
 
int ast_geoloc_eprofile_refresh_location (struct ast_geoloc_eprofile *eprofile)
 Refresh the effective profile with any changed info. More...
 
const char * ast_geoloc_eprofile_to_pidf (struct ast_geoloc_eprofile *eprofile, struct ast_channel *chan, struct ast_str **buf, const char *ref_string)
 Convert a single eprofile to a PIDF-LO document. More...
 
const char * ast_geoloc_eprofile_to_uri (struct ast_geoloc_eprofile *eprofile, struct ast_channel *chan, struct ast_str **buf, const char *ref_string)
 Convert a URI eprofile to a URI string. More...
 
const char * ast_geoloc_eprofiles_to_pidf (struct ast_datastore *ds, struct ast_channel *chan, struct ast_str **buf, const char *ref_string)
 Convert a datastore containing eprofiles to a PIDF-LO document. More...
 

Macro Definition Documentation

◆ AST_GEOLOC_INVALID_VALUE

#define AST_GEOLOC_INVALID_VALUE   -1

Definition at line 28 of file res_geolocation.h.

◆ CONFIG_STR_TO_ENUM_DECL

#define CONFIG_STR_TO_ENUM_DECL (   _stem)    int ast_geoloc_ ## _stem ## _str_to_enum(const char *str);

Definition at line 53 of file res_geolocation.h.

◆ GEOLOC_ENUM_TO_NAME_DECL

#define GEOLOC_ENUM_TO_NAME_DECL (   _stem)    const char * ast_geoloc_ ## _stem ## _to_name(int ix);

Definition at line 57 of file res_geolocation.h.

Enumeration Type Documentation

◆ ast_geoloc_format

Enumerator
AST_GEOLOC_FORMAT_NONE 
AST_GEOLOC_FORMAT_CIVIC_ADDRESS 
AST_GEOLOC_FORMAT_GML 
AST_GEOLOC_FORMAT_URI 
AST_GEOLOC_FORMAT_LAST 

Definition at line 38 of file res_geolocation.h.

38 {
44};
@ AST_GEOLOC_FORMAT_GML
@ AST_GEOLOC_FORMAT_CIVIC_ADDRESS
@ AST_GEOLOC_FORMAT_LAST
@ AST_GEOLOC_FORMAT_URI
@ AST_GEOLOC_FORMAT_NONE

◆ ast_geoloc_pidf_element

Enumerator
AST_PIDF_ELEMENT_NONE 
AST_PIDF_ELEMENT_DEVICE 
AST_PIDF_ELEMENT_TUPLE 
AST_PIDF_ELEMENT_PERSON 
AST_PIDF_ELEMENT_LAST 

Definition at line 30 of file res_geolocation.h.

30 {
36};
@ AST_PIDF_ELEMENT_PERSON
@ AST_PIDF_ELEMENT_TUPLE
@ AST_PIDF_ELEMENT_DEVICE
@ AST_PIDF_ELEMENT_NONE
@ AST_PIDF_ELEMENT_LAST

◆ ast_geoloc_precedence

Enumerator
AST_GEOLOC_PRECED_PREFER_INCOMING 
AST_GEOLOC_PRECED_PREFER_CONFIG 
AST_GEOLOC_PRECED_DISCARD_INCOMING 
AST_GEOLOC_PRECED_DISCARD_CONFIG 

Definition at line 46 of file res_geolocation.h.

◆ ast_geoloc_validate_result

Enumerator
AST_GEOLOC_VALIDATE_INVALID_VALUE 
AST_GEOLOC_VALIDATE_SUCCESS 
AST_GEOLOC_VALIDATE_MISSING_SHAPE 
AST_GEOLOC_VALIDATE_INVALID_SHAPE 
AST_GEOLOC_VALIDATE_INVALID_VARNAME 
AST_GEOLOC_VALIDATE_NOT_ENOUGH_VARNAMES 
AST_GEOLOC_VALIDATE_TOO_MANY_VARNAMES 

Definition at line 152 of file res_geolocation.h.

Function Documentation

◆ ast_geoloc_civicaddr_is_code_valid()

int ast_geoloc_civicaddr_is_code_valid ( const char *  code)

Given a civicAddress code, check whether it's valid.

Parameters
codePointer to the code to check
Returns
1 if valid, 0 otherwise.

Definition at line 68 of file geoloc_civicaddr.c.

69{
70 const char **entry = bsearch(&code, addr_code_name_entries, ARRAY_LEN(addr_code_name_entries),
71 sizeof(const char *), compare_civicaddr_codes);
72 return (entry != NULL);
73}
static int compare_civicaddr_codes(const void *_a, const void *_b)
static const char * addr_code_name_entries[]
#define NULL
Definition: resample.c:96
Definition: search.h:40
#define ARRAY_LEN(a)
Definition: utils.h:666

References addr_code_name_entries, ARRAY_LEN, compare_civicaddr_codes(), and NULL.

Referenced by ast_geoloc_civicaddr_validate_varlist().

◆ ast_geoloc_civicaddr_validate_varlist()

enum ast_geoloc_validate_result ast_geoloc_civicaddr_validate_varlist ( const struct ast_variable varlist,
const char **  result 
)

Validate that the names of the variables in the list are valid codes or synonyms.

Parameters
varlistVariable list to check.
[out]resultPointer to char * to receive failing item.
Returns
result code.

Definition at line 75 of file geoloc_civicaddr.c.

77{
78 const struct ast_variable *var = varlist;
79 for (; var; var = var->next) {
80 int valid = ast_geoloc_civicaddr_is_code_valid(var->name);
81 if (!valid) {
82 *result = var->name;
84 }
85 }
87}
#define var
Definition: ast_expr2f.c:605
static PGresult * result
Definition: cel_pgsql.c:84
int ast_geoloc_civicaddr_is_code_valid(const char *code)
Given a civicAddress code, check whether it's valid.
Structure for variables, used for configurations and for channel variables.

References ast_geoloc_civicaddr_is_code_valid(), AST_GEOLOC_VALIDATE_INVALID_VARNAME, AST_GEOLOC_VALIDATE_SUCCESS, result, and var.

Referenced by validate_location_info().

◆ ast_geoloc_datastore_add_eprofile()

int ast_geoloc_datastore_add_eprofile ( struct ast_datastore ds,
struct ast_geoloc_eprofile eprofile 
)

Add an eprofile to a datastore.

Parameters
dsThe datastore
eprofileThe eprofile to add.
Returns
The new number of eprofiles or -1 to indicate a failure.

Definition at line 135 of file geoloc_datastore.c.

137{
138 struct eprofiles_datastore *eds = NULL;
139 int rc = 0;
140
141 if (!IS_GEOLOC_DS(ds) || !eprofile) {
142 return -1;
143 }
144
145 eds = ds->data;
146 rc = AST_VECTOR_APPEND(&eds->eprofiles, ao2_bump(eprofile));
147 if (rc != 0) {
148 ao2_ref(eprofile, -1);
149 ast_log(LOG_ERROR, "Couldn't add eprofile '%s' to geoloc datastore '%s'\n", eprofile->id, eds->id);
150 return -1;
151 }
152
153 return AST_VECTOR_SIZE(&eds->eprofiles);
154}
#define ast_log
Definition: astobj2.c:42
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
Definition: astobj2.h:480
#define IS_GEOLOC_DS(_ds)
#define LOG_ERROR
void * data
Definition: datastore.h:66
const ast_string_field id
struct eprofiles_datastore::geoloc_eprofiles eprofiles
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:609
#define AST_VECTOR_APPEND(vec, elem)
Append an element to a vector, growing the vector if needed.
Definition: vector.h:256

References ao2_bump, ao2_ref, ast_log, AST_VECTOR_APPEND, AST_VECTOR_SIZE, ast_datastore::data, eprofiles_datastore::eprofiles, ast_geoloc_eprofile::id, eprofiles_datastore::id, IS_GEOLOC_DS, LOG_ERROR, and NULL.

Referenced by add_eprofile_to_channel(), ast_geoloc_datastore_create_from_eprofile(), ast_geoloc_datastore_create_from_profile_name(), and geoloc_profile_write().

◆ ast_geoloc_datastore_create()

struct ast_datastore * ast_geoloc_datastore_create ( const char *  id)

Create an empty geoloc datastore.

Parameters
idAn id to use for the datastore.
Returns
The datastore.

Definition at line 99 of file geoloc_datastore.c.

100{
101 struct ast_datastore *ds = NULL;
102 struct eprofiles_datastore *eds = NULL;
103 int rc = 0;
104
105 if (ast_strlen_zero(id)) {
106 ast_log(LOG_ERROR, "A geoloc datastore can't be allocated with a NULL or empty id\n");
107 return NULL;
108 }
109
111 if (!ds) {
112 ast_log(LOG_ERROR, "Geoloc datastore '%s' couldn't be allocated\n", id);
113 return NULL;
114 }
115
116 eds = ast_calloc(1, sizeof(*eds));
117 if (!eds) {
119 ast_log(LOG_ERROR, "Private structure for geoloc datastore '%s' couldn't be allocated\n", id);
120 return NULL;
121 }
122 ds->data = eds;
123
124
125 rc = AST_VECTOR_INIT(&eds->eprofiles, 2);
126 if (rc != 0) {
128 ast_log(LOG_ERROR, "Vector for geoloc datastore '%s' couldn't be initialized\n", id);
129 return NULL;
130 }
131
132 return ds;
133}
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
#define ast_datastore_alloc(info, uid)
Definition: datastore.h:85
int ast_datastore_free(struct ast_datastore *datastore)
Free a data store object.
Definition: datastore.c:68
static const struct ast_datastore_info geoloc_datastore_info
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
Structure for a data store object.
Definition: datastore.h:64
#define AST_VECTOR_INIT(vec, size)
Initialize a vector.
Definition: vector.h:113

References ast_calloc, ast_datastore_alloc, ast_datastore_free(), ast_log, ast_strlen_zero(), AST_VECTOR_INIT, ast_datastore::data, eprofiles_datastore::eprofiles, geoloc_datastore_info, LOG_ERROR, and NULL.

Referenced by add_eprofile_to_channel(), ast_geoloc_datastore_create_from_eprofile(), ast_geoloc_datastore_create_from_profile_name(), and geoloc_profile_write().

◆ ast_geoloc_datastore_create_from_eprofile()

struct ast_datastore * ast_geoloc_datastore_create_from_eprofile ( struct ast_geoloc_eprofile eprofile)

Create a geoloc datastore from an effective profile.

Parameters
eprofileThe effective profile to use.
Returns
The datastore.

Definition at line 242 of file geoloc_datastore.c.

244{
245 struct ast_datastore *ds;
246 int rc = 0;
247
248 if (!eprofile) {
249 return NULL;
250 }
251
252 ds = ast_geoloc_datastore_create(eprofile->id);
253 if (!ds) {
254 return NULL;
255 }
256
257 rc = ast_geoloc_datastore_add_eprofile(ds, eprofile);
258 if (rc <= 0) {
260 ds = NULL;
261 }
262
263 return ds;
264}
struct ast_datastore * ast_geoloc_datastore_create(const char *id)
Create an empty geoloc datastore.
int ast_geoloc_datastore_add_eprofile(struct ast_datastore *ds, struct ast_geoloc_eprofile *eprofile)
Add an eprofile to a datastore.

References ast_datastore_free(), ast_geoloc_datastore_add_eprofile(), ast_geoloc_datastore_create(), ast_geoloc_eprofile::id, and NULL.

◆ ast_geoloc_datastore_create_from_profile_name()

struct ast_datastore * ast_geoloc_datastore_create_from_profile_name ( const char *  profile_name)

Geolocation datastore Functions.

Create a geoloc datastore from a profile name

Parameters
profile_nameThe name of the profile to use.
Returns
The datastore.

Definition at line 266 of file geoloc_datastore.c.

267{
268 struct ast_datastore *ds = NULL;
269 struct ast_geoloc_eprofile *eprofile = NULL;
270 struct ast_geoloc_profile *profile = NULL;
271 int rc = 0;
272
273 if (ast_strlen_zero(profile_name)) {
274 return NULL;
275 }
276
277 profile = ast_sorcery_retrieve_by_id(geoloc_sorcery, "profile", profile_name);
278 if (!profile) {
279 ast_log(LOG_ERROR, "A profile with the name '%s' was not found\n", profile_name);
280 return NULL;
281 }
282
283 ds = ast_geoloc_datastore_create(profile_name);
284 if (!ds) {
285 ast_log(LOG_ERROR, "A datastore couldn't be allocated for profile '%s'\n", profile_name);
286 ao2_ref(profile, -1);
287 return NULL;
288 }
289
290 eprofile = ast_geoloc_eprofile_create_from_profile(profile);
291 ao2_ref(profile, -1);
292 if (!eprofile) {
294 ast_log(LOG_ERROR, "An effective profile with the name '%s' couldn't be allocated\n", profile_name);
295 return NULL;
296 }
297
298 rc = ast_geoloc_datastore_add_eprofile(ds, eprofile);
299 ao2_ref(eprofile, -1);
300 if (rc <= 0) {
302 ds = NULL;
303 }
304
305 return ds;
306}
struct ast_sorcery * geoloc_sorcery
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_sorcery_retrieve_by_id(const struct ast_sorcery *sorcery, const char *type, const char *id)
Retrieve an object using its unique identifier.
Definition: sorcery.c:1853

References ao2_ref, ast_datastore_free(), ast_geoloc_datastore_add_eprofile(), ast_geoloc_datastore_create(), ast_geoloc_eprofile_create_from_profile(), ast_log, ast_sorcery_retrieve_by_id(), ast_strlen_zero(), geoloc_sorcery, LOG_ERROR, and NULL.

◆ ast_geoloc_datastore_delete_eprofile()

int ast_geoloc_datastore_delete_eprofile ( struct ast_datastore ds,
int  ix 
)

Delete a specific eprofile from a datastore by index.

Parameters
dsThe datastore
ixThe index
Returns
0 if succesful, -1 otherwise.

Definition at line 224 of file geoloc_datastore.c.

225{
226 struct eprofiles_datastore *eds = NULL;
227
228 if (!IS_GEOLOC_DS(ds)) {
229 return -1;
230 }
231
232 eds = ds->data;
233
234 if (ix >= AST_VECTOR_SIZE(&eds->eprofiles)) {
235 return -1;
236 }
237
238 ao2_ref(AST_VECTOR_REMOVE(&eds->eprofiles, ix, 1), -1);
239 return 0;
240}
#define AST_VECTOR_REMOVE(vec, idx, preserve_ordered)
Remove an element from a vector by index.
Definition: vector.h:412

References ao2_ref, AST_VECTOR_REMOVE, AST_VECTOR_SIZE, ast_datastore::data, eprofiles_datastore::eprofiles, IS_GEOLOC_DS, and NULL.

◆ ast_geoloc_datastore_find()

struct ast_datastore * ast_geoloc_datastore_find ( struct ast_channel chan)

Retrieves the geoloc datastore from a channel, if any.

Parameters
chanChannel
Returns
datastore if found, NULL otherwise.

Definition at line 219 of file geoloc_datastore.c.

220{
222}
struct ast_datastore * ast_channel_datastore_find(struct ast_channel *chan, const struct ast_datastore_info *info, const char *uid)
Find a datastore on a channel.
Definition: channel.c:2399

References ast_channel_datastore_find(), geoloc_datastore_info, and NULL.

Referenced by geoloc_profile_read(), geoloc_profile_write(), and handle_outgoing_request().

◆ ast_geoloc_datastore_get_eprofile()

struct ast_geoloc_eprofile * ast_geoloc_datastore_get_eprofile ( struct ast_datastore ds,
int  ix 
)

Retrieve a specific eprofile from a datastore by index.

Parameters
dsThe datastore
ixThe index
Returns
The effective profile ao2 object with its reference count bumped.

Definition at line 200 of file geoloc_datastore.c.

201{
202 struct eprofiles_datastore *eds = NULL;
203 struct ast_geoloc_eprofile *eprofile;
204
205 if (!IS_GEOLOC_DS(ds)) {
206 return NULL;
207 }
208
209 eds = ds->data;
210
211 if (ix >= AST_VECTOR_SIZE(&eds->eprofiles)) {
212 return NULL;
213 }
214
215 eprofile = AST_VECTOR_GET(&eds->eprofiles, ix);
216 return ao2_bump(eprofile);
217}
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:680

References ao2_bump, AST_VECTOR_GET, AST_VECTOR_SIZE, ast_datastore::data, eprofiles_datastore::eprofiles, IS_GEOLOC_DS, and NULL.

Referenced by ast_geoloc_eprofiles_to_pidf(), geoloc_profile_read(), geoloc_profile_write(), and handle_outgoing_request().

◆ ast_geoloc_datastore_get_id()

const char * ast_geoloc_datastore_get_id ( struct ast_datastore ds)

Retrieve a geoloc datastore's id.

Parameters
dsThe datastore
Returns
The datastore's id.

Definition at line 86 of file geoloc_datastore.c.

87{
88 struct eprofiles_datastore *eds = NULL;
89
90 if (!IS_GEOLOC_DS(ds)) {
91 return NULL;
92 }
93
94 eds = (struct eprofiles_datastore *)ds->data;
95
96 return eds->id;
97}

References ast_datastore::data, eprofiles_datastore::id, IS_GEOLOC_DS, and NULL.

◆ ast_geoloc_datastore_insert_eprofile()

int ast_geoloc_datastore_insert_eprofile ( struct ast_datastore ds,
struct ast_geoloc_eprofile eprofile,
int  index 
)

Insert an eprofile to a datastore at the specified position.

Parameters
dsThe datastore
eprofileThe eprofile to add.
indexThe position to insert at. Existing eprofiles will be moved up to make room.
Returns
The new number of eprofiles or -1 to indicate a failure.

Definition at line 156 of file geoloc_datastore.c.

158{
159 struct eprofiles_datastore *eds = NULL;
160 int rc = 0;
161
162 if (!IS_GEOLOC_DS(ds) || !eprofile) {
163 return -1;
164 }
165
166 eds = ds->data;
167 rc = AST_VECTOR_INSERT_AT(&eds->eprofiles, index, ao2_bump(eprofile));
168 if (rc != 0) {
169 ao2_ref(eprofile, -1);
170 ast_log(LOG_ERROR, "Couldn't add eprofile '%s' to geoloc datastore '%s' in position '%d'\n",
171 eprofile->id, eds->id, index);
172 return -1;
173 }
174
175 return AST_VECTOR_SIZE(&eds->eprofiles);
176}
#define AST_VECTOR_INSERT_AT(vec, idx, elem)
Insert an element at a specific position in a vector, growing the vector if needed.
Definition: vector.h:338

References ao2_bump, ao2_ref, ast_log, AST_VECTOR_INSERT_AT, AST_VECTOR_SIZE, ast_datastore::data, eprofiles_datastore::eprofiles, ast_geoloc_eprofile::id, eprofiles_datastore::id, IS_GEOLOC_DS, LOG_ERROR, and NULL.

◆ ast_geoloc_datastore_set_inheritance()

int ast_geoloc_datastore_set_inheritance ( struct ast_datastore ds,
int  inherit 
)

Sets the inheritance flag on the datastore.

Parameters
dsThe datastore
inherit1 to allow the datastore to be inherited by other channels 0 to prevent the datastore to be inherited by other channels
Returns
0 if successful, -1 otherwise.

Definition at line 191 of file geoloc_datastore.c.

192{
193 if (!IS_GEOLOC_DS(ds)) {
194 return -1;
195 }
196 ds->inheritance = inherit ? DATASTORE_INHERIT_FOREVER : 0;
197 return 0;
198}
#define DATASTORE_INHERIT_FOREVER
Definition: channel.h:192
unsigned int inheritance
Definition: datastore.h:69

References DATASTORE_INHERIT_FOREVER, ast_datastore::inheritance, and IS_GEOLOC_DS.

Referenced by add_eprofile_to_channel(), and geoloc_profile_write().

◆ ast_geoloc_datastore_size()

int ast_geoloc_datastore_size ( struct ast_datastore ds)

Retrieves the number of eprofiles in the datastore.

Parameters
dsThe datastore
Returns
The number of eprofiles.

Definition at line 178 of file geoloc_datastore.c.

179{
180 struct eprofiles_datastore *eds = NULL;
181
182 if (!IS_GEOLOC_DS(ds)) {
183 return -1;
184 }
185
186 eds = ds->data;
187
188 return AST_VECTOR_SIZE(&eds->eprofiles);
189}

References AST_VECTOR_SIZE, ast_datastore::data, eprofiles_datastore::eprofiles, IS_GEOLOC_DS, and NULL.

Referenced by ast_geoloc_eprofiles_to_pidf(), and handle_outgoing_request().

◆ ast_geoloc_eprofile_alloc()

struct ast_geoloc_eprofile * ast_geoloc_eprofile_alloc ( const char *  name)

Geolocation Effective Profile Functions.

Allocate a new, empty effective profile.

Parameters
nameThe profile's name
Returns
The effective profile ao2 object.

Definition at line 69 of file geoloc_eprofile.c.

70{
71 struct ast_geoloc_eprofile *eprofile = ao2_alloc_options(sizeof(*eprofile),
73
74 ast_string_field_init(eprofile, 256);
75 ast_string_field_set(eprofile, id, name); /* SAFE string fields handle NULL */
76
77 return eprofile;
78}
@ AO2_ALLOC_OPT_LOCK_NOLOCK
Definition: astobj2.h:367
#define ao2_alloc_options(data_size, destructor_fn, options)
Definition: astobj2.h:404
static const char name[]
Definition: format_mp3.c:68
static void geoloc_eprofile_destructor(void *obj)
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:521
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:359

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_alloc_options, ast_string_field_init, ast_string_field_set, geoloc_eprofile_destructor(), and name.

Referenced by ast_geoloc_eprofile_create_from_profile(), ast_geoloc_eprofile_create_from_uri(), ast_geoloc_eprofile_dup(), geoloc_eprofile_create_from_xslt_result(), and geoloc_profile_write().

◆ ast_geoloc_eprofile_create_from_pidf()

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.

Parameters
pidf_xmldocThe ast_xml_doc to use.
geoloc_uriThe URI that referenced this document.
reference_stringAn identifying string to use in error messages.
Returns
The effective profile ao2 object.

Definition at line 756 of file geoloc_eprofile.c.

758{
759 struct ast_xml_doc *result_doc = NULL;
760 struct ast_geoloc_eprofile *eprofile = NULL;
761
762 SCOPE_ENTER(3, "%s\n", ref_str);
763
764 result_doc = ast_xslt_apply(pidf_to_eprofile_xslt, pidf_xmldoc, NULL);
765 if (!is_pidf_lo(result_doc)) {
766 SCOPE_EXIT_RTN_VALUE(NULL, "%s: Not a PIDF-LO. Skipping.\n", ref_str);
767 }
768
769 /*
770 * The document returned from the stylesheet application looks like this...
771 * <presence id="presence-entity">
772 * <tuple id="element-id">
773 * <location-info format="gml">shape="Ellipsoid", crs="3d", ...</location-info>
774 * <usage-rules>retransmission-allowed="no", retention-expiry="2010-11-14T20:00:00Z"</usage-rules>
775 * <method>Hybrid_A-GPS</method>
776 * </tuple>
777 * </presence>
778 *
779 * Regardless of whether the pidf-element was tuple, device or person and whether
780 * the format is gml or civicAddress, the presence, pidf-element and location-info
781 * elements should be there.
782 *
783 * The confidence, usage-rules and note-well elements are optional.
784 */
785
786 if (TRACE_ATLEAST(5)) {
787 char *doc_str = NULL;
788 int doc_len = 0;
789
790 ast_xml_doc_dump_memory(result_doc, &doc_str, &doc_len);
791 ast_trace(5, "Intermediate doc len: %d\n%s\n", doc_len, doc_len ? doc_str : "<empty>");
792 ast_xml_free_text(doc_str);
793 doc_str = NULL;
794 doc_len = 0;
795 }
796
797 eprofile = geoloc_eprofile_create_from_xslt_result(result_doc, ref_str);
798 ast_xml_close(result_doc);
799
800 if (eprofile && geoloc_uri) {
801 set_loc_src(eprofile, geoloc_uri, ref_str);
802 }
803
804 SCOPE_EXIT_RTN_VALUE(eprofile, "%s: Done.\n", ref_str);
805}
static struct ast_xslt_doc * pidf_to_eprofile_xslt
static int set_loc_src(struct ast_geoloc_eprofile *eprofile, const char *uri, const char *ref_str)
static int is_pidf_lo(struct ast_xml_doc *result_doc)
static struct ast_geoloc_eprofile * geoloc_eprofile_create_from_xslt_result(struct ast_xml_doc *result_doc, const char *ref_str)
#define TRACE_ATLEAST(level)
#define SCOPE_EXIT_RTN_VALUE(__return_value,...)
#define SCOPE_ENTER(level,...)
#define ast_trace(level,...)
void ast_xml_close(struct ast_xml_doc *doc)
Close an already open document and free the used structure.
Definition: xml.c:213
void ast_xml_doc_dump_memory(struct ast_xml_doc *doc, char **buffer, int *length)
Dump the specified document to a buffer.
Definition: xml.c:387
void ast_xml_free_text(const char *text)
Free a content element that was returned by ast_xml_get_text()
Definition: xml.c:262

References ast_trace, ast_xml_close(), ast_xml_doc_dump_memory(), ast_xml_free_text(), geoloc_eprofile_create_from_xslt_result(), is_pidf_lo(), NULL, pidf_to_eprofile_xslt, SCOPE_ENTER, SCOPE_EXIT_RTN_VALUE, set_loc_src(), and TRACE_ATLEAST.

Referenced by handle_incoming_request().

◆ ast_geoloc_eprofile_create_from_profile()

struct ast_geoloc_eprofile * ast_geoloc_eprofile_create_from_profile ( struct ast_geoloc_profile profile)

Allocate a new effective profile from an existing profile.

Parameters
profileThe profile to use.
Returns
The effective profile ao2 object.

Definition at line 220 of file geoloc_eprofile.c.

221{
222 struct ast_geoloc_eprofile *eprofile;
223 const char *profile_id;
224 int rc = 0;
225
226 if (!profile) {
227 return NULL;
228 }
229
230 profile_id = ast_sorcery_object_get_id(profile);
231
232 eprofile = ast_geoloc_eprofile_alloc(profile_id);
233 if (!eprofile) {
234 return NULL;
235 }
236
237 ao2_lock(profile);
238 eprofile->allow_routing_use = profile->allow_routing_use;
239 eprofile->pidf_element = profile->pidf_element;
241 eprofile->format = profile->format;
242
243
245 if (rc == 0) {
246 ast_string_field_set(eprofile, notes, profile->notes);
247 }
248 if (rc == 0) {
249 ast_string_field_set(eprofile, method, profile->method);
250 }
251 if (rc == 0) {
253 }
254 if (rc == 0) {
255 rc = DUP_VARS(eprofile->location_info, profile->location_info);
256 }
257 if (rc == 0) {
258 rc = DUP_VARS(eprofile->location_refinement, profile->location_refinement);
259 }
260 if (rc == 0) {
261 rc = DUP_VARS(eprofile->location_variables, profile->location_variables);
262 }
263 if (rc == 0) {
264 rc = DUP_VARS(eprofile->usage_rules, profile->usage_rules);
265 }
266 if (rc == 0) {
267 rc = DUP_VARS(eprofile->confidence, profile->confidence);
268 }
269 if (rc != 0) {
270 ao2_unlock(profile);
271 ao2_ref(eprofile, -1);
272 return NULL;
273 }
274
275 eprofile->precedence = profile->precedence;
276 ao2_unlock(profile);
277
278 if (ast_geoloc_eprofile_refresh_location(eprofile) != 0) {
279 ao2_ref(eprofile, -1);
280 return NULL;
281 }
282
283 return eprofile;
284}
#define ao2_unlock(a)
Definition: astobj2.h:729
#define ao2_lock(a)
Definition: astobj2.h:717
int ast_geoloc_eprofile_refresh_location(struct ast_geoloc_eprofile *eprofile)
Refresh the effective profile with any changed info.
struct ast_geoloc_eprofile * ast_geoloc_eprofile_alloc(const char *name)
Geolocation Effective Profile Functions.
#define DUP_VARS(_dest, _source)
static int notes
Definition: pval.c:66
const char * method
Definition: res_pjsip.c:1279
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
Definition: sorcery.c:2317
const ast_string_field location_reference
enum ast_geoloc_format format
enum ast_geoloc_pidf_element pidf_element
struct ast_variable * location_refinement
enum ast_geoloc_precedence precedence
struct ast_variable * location_variables
struct ast_variable * confidence
struct ast_variable * usage_rules
const ast_string_field location_source
struct ast_variable * location_info
const ast_string_field location_reference
enum ast_geoloc_format format
enum ast_geoloc_pidf_element pidf_element
const ast_string_field method
struct ast_variable * location_refinement
enum ast_geoloc_precedence precedence
const ast_string_field notes
struct ast_variable * location_variables
struct ast_variable * confidence
struct ast_variable * usage_rules
const ast_string_field location_source
struct ast_variable * location_info

References ast_geoloc_profile::allow_routing_use, ast_geoloc_eprofile::allow_routing_use, ao2_lock, ao2_ref, ao2_unlock, ast_geoloc_eprofile_alloc(), ast_geoloc_eprofile_refresh_location(), ast_sorcery_object_get_id(), ast_string_field_set, ast_geoloc_profile::confidence, ast_geoloc_eprofile::confidence, DUP_VARS, ast_geoloc_profile::format, ast_geoloc_eprofile::format, ast_geoloc_profile::location_info, ast_geoloc_eprofile::location_info, ast_geoloc_profile::location_reference, ast_geoloc_eprofile::location_reference, ast_geoloc_profile::location_refinement, ast_geoloc_eprofile::location_refinement, ast_geoloc_profile::location_source, ast_geoloc_eprofile::location_source, ast_geoloc_profile::location_variables, ast_geoloc_eprofile::location_variables, ast_geoloc_profile::method, method, ast_geoloc_profile::notes, notes, NULL, ast_geoloc_profile::pidf_element, ast_geoloc_eprofile::pidf_element, ast_geoloc_profile::precedence, ast_geoloc_eprofile::precedence, ast_geoloc_profile::suppress_empty_ca_elements, ast_geoloc_eprofile::suppress_empty_ca_elements, ast_geoloc_profile::usage_rules, and ast_geoloc_eprofile::usage_rules.

Referenced by ast_geoloc_datastore_create_from_profile_name(), geoloc_config_show_profiles(), handle_incoming_request(), and handle_outgoing_request().

◆ ast_geoloc_eprofile_create_from_uri()

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.

Parameters
uriThe URI to use.
reference_stringAn identifying string to use in error messages.
Returns
The effective profile ao2 object.

Definition at line 316 of file geoloc_eprofile.c.

318{
319 struct ast_geoloc_eprofile *eprofile = NULL;
320 char *ra = NULL;
321 char *local_uri;
322
323 if (ast_strlen_zero(uri)) {
324 return NULL;
325 }
326 local_uri = ast_strdupa(uri);
327
328 if (local_uri[0] == '<') {
329 local_uri++;
330 }
331 ra = strchr(local_uri, '>');
332 if (ra) {
333 *ra = '\0';
334 }
335
336 ast_strip(local_uri);
337
338 eprofile = ast_geoloc_eprofile_alloc(local_uri);
339 if (!eprofile) {
340 return NULL;
341 }
342
343 set_loc_src(eprofile, uri, ref_str);
344
345 eprofile->format = AST_GEOLOC_FORMAT_URI;
346 eprofile->location_info = ast_variable_new("URI", local_uri, "");
347
348 return eprofile;
349}
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
#define ast_variable_new(name, value, filename)
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
Definition: strings.h:223

References ast_geoloc_eprofile_alloc(), AST_GEOLOC_FORMAT_URI, ast_strdupa, ast_strip(), ast_strlen_zero(), ast_variable_new, ast_geoloc_eprofile::format, ast_geoloc_eprofile::location_info, NULL, and set_loc_src().

Referenced by handle_incoming_request().

◆ ast_geoloc_eprofile_dup()

struct ast_geoloc_eprofile * ast_geoloc_eprofile_dup ( struct ast_geoloc_eprofile src)

Duplicate an effective profile.

Parameters
srcThe eprofile to duplicate.
Returns
The duplicated effective profile ao2 object.

Definition at line 159 of file geoloc_eprofile.c.

160{
161 struct ast_geoloc_eprofile *eprofile;
162 const char *profile_id;
163 int rc = 0;
164
165 if (!src) {
166 return NULL;
167 }
168
169 profile_id = ast_strdupa(src->id);
170
171 eprofile = ast_geoloc_eprofile_alloc(profile_id);
172 if (!eprofile) {
173 return NULL;
174 }
175
176 eprofile->allow_routing_use = src->allow_routing_use;
177 eprofile->pidf_element = src->pidf_element;
179 eprofile->format = src->format;
180 eprofile->precedence = src->precedence;
181
182
184 if (rc == 0) {
185 ast_string_field_set(eprofile, notes, src->notes);
186 }
187 if (rc == 0) {
188 ast_string_field_set(eprofile, method, src->method);
189 }
190 if (rc == 0) {
192 }
193 if (rc == 0) {
194 rc = DUP_VARS(eprofile->location_info, src->location_info);
195 }
196 if (rc == 0) {
197 rc = DUP_VARS(eprofile->effective_location, src->effective_location);
198 }
199 if (rc == 0) {
201 }
202 if (rc == 0) {
203 rc = DUP_VARS(eprofile->location_variables, src->location_variables);
204 }
205 if (rc == 0) {
206 rc = DUP_VARS(eprofile->usage_rules, src->usage_rules);
207 }
208 if (rc == 0) {
209 rc = DUP_VARS(eprofile->confidence, src->confidence);
210 }
211 if (rc != 0) {
212 ao2_ref(eprofile, -1);
213 return NULL;
214 }
215
216
217 return eprofile;
218}
struct ast_variable * effective_location
const ast_string_field method
const ast_string_field notes

References ast_geoloc_eprofile::allow_routing_use, ao2_ref, ast_geoloc_eprofile_alloc(), ast_strdupa, ast_string_field_set, ast_geoloc_eprofile::confidence, DUP_VARS, ast_geoloc_eprofile::effective_location, ast_geoloc_eprofile::format, ast_geoloc_eprofile::id, ast_geoloc_eprofile::location_info, ast_geoloc_eprofile::location_reference, ast_geoloc_eprofile::location_refinement, ast_geoloc_eprofile::location_source, ast_geoloc_eprofile::location_variables, ast_geoloc_eprofile::method, method, ast_geoloc_eprofile::notes, notes, NULL, ast_geoloc_eprofile::pidf_element, ast_geoloc_eprofile::precedence, ast_geoloc_eprofile::suppress_empty_ca_elements, and ast_geoloc_eprofile::usage_rules.

Referenced by geoloc_profile_read().

◆ ast_geoloc_eprofile_refresh_location()

int ast_geoloc_eprofile_refresh_location ( struct ast_geoloc_eprofile eprofile)

Refresh the effective profile with any changed info.

Parameters
eprofileThe eprofile to refresh.
Returns
0 on success, any other value on error.

Definition at line 80 of file geoloc_eprofile.c.

81{
82 struct ast_geoloc_location *loc = NULL;
83 RAII_VAR(struct ast_variable *, temp_locinfo, NULL, ast_variables_destroy);
84 RAII_VAR(struct ast_variable *, temp_effloc, NULL, ast_variables_destroy);
85 RAII_VAR(struct ast_variable *, temp_confidence, NULL, ast_variables_destroy);
86 const char *method = NULL;
87 const char *location_source = NULL;
89 struct ast_variable *var;
90 int rc = 0;
91
92 if (!eprofile) {
93 return -1;
94 }
95
96 if (!ast_strlen_zero(eprofile->location_reference)) {
98 if (!loc) {
99 ast_log(LOG_ERROR, "Profile '%s' referenced location '%s' does not exist!", eprofile->id,
100 eprofile->location_reference);
101 return -1;
102 }
103
104 format = loc->format;
105 method = loc->method;
106 location_source = loc->location_source;
107 rc = DUP_VARS(temp_locinfo, loc->location_info);
108 if (rc == 0) {
109 rc = DUP_VARS(temp_confidence, loc->confidence);
110 }
111 ao2_ref(loc, -1);
112 if (rc != 0) {
113 return -1;
114 }
115 } else {
116 format = eprofile->format;
117 method = eprofile->method;
118 location_source = eprofile->location_source;
119 rc = DUP_VARS(temp_locinfo, eprofile->location_info);
120 if (rc == 0) {
121 rc = DUP_VARS(temp_confidence, eprofile->confidence);
122 }
123 if (rc != 0) {
124 return -1;
125 }
126 }
127
128 rc = DUP_VARS(temp_effloc, temp_locinfo);
129 if (rc != 0) {
130 return -1;
131 }
132
133 if (eprofile->location_refinement) {
134 for (var = eprofile->location_refinement; var; var = var->next) {
135 struct ast_variable *newvar = ast_variable_new(var->name, var->value, "");
136 if (!newvar) {
137 return -1;
138 }
139 if (ast_variable_list_replace(&temp_effloc, newvar)) {
140 ast_variable_list_append(&temp_effloc, newvar);
141 }
142 }
143 }
144
145 eprofile->format = format;
147 ast_string_field_set(eprofile, location_source, location_source);
148
150 eprofile->location_info = temp_locinfo;
151 temp_locinfo = NULL;
153 eprofile->effective_location = temp_effloc;
154 temp_effloc = NULL;
155
156 return 0;
157}
static struct ast_sorcery * geoloc_sorcery
#define ast_variable_list_append(head, new_var)
int ast_variable_list_replace(struct ast_variable **head, struct ast_variable *replacement)
Replace a variable in the given list with a new value.
Definition: main/config.c:667
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1262
ast_geoloc_format
enum ast_geoloc_format format
const ast_string_field method
struct ast_variable * confidence
const ast_string_field location_source
struct ast_variable * location_info
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941

References ao2_ref, ast_log, ast_sorcery_retrieve_by_id(), ast_string_field_set, ast_strlen_zero(), ast_variable_list_append, ast_variable_list_replace(), ast_variable_new, ast_variables_destroy(), ast_geoloc_location::confidence, ast_geoloc_eprofile::confidence, DUP_VARS, ast_geoloc_eprofile::effective_location, ast_geoloc_location::format, ast_geoloc_eprofile::format, geoloc_sorcery, ast_geoloc_eprofile::id, ast_geoloc_location::location_info, ast_geoloc_eprofile::location_info, ast_geoloc_eprofile::location_reference, ast_geoloc_eprofile::location_refinement, ast_geoloc_location::location_source, ast_geoloc_eprofile::location_source, LOG_ERROR, ast_geoloc_location::method, ast_geoloc_eprofile::method, method, NULL, RAII_VAR, and var.

Referenced by ast_geoloc_eprofile_create_from_profile(), geoloc_profile_read(), geoloc_profile_write(), and handle_outgoing_request().

◆ ast_geoloc_eprofile_to_pidf()

const char * ast_geoloc_eprofile_to_pidf ( struct ast_geoloc_eprofile eprofile,
struct ast_channel chan,
struct ast_str **  buf,
const char *  ref_string 
)

Convert a single eprofile to a PIDF-LO document.

Parameters
eprofileEffective profile to convert
chanChannel to use to resolve variables
bufPointer to ast_str pointer to use for work
ref_stringAn identifying string to use in error messages.
Returns
String representation PIDF-LO allocated from buf or NULL on failure.

Definition at line 1061 of file geoloc_eprofile.c.

1063{
1064 RAII_VAR(struct ast_xml_doc *, intermediate, NULL, ast_xml_close);
1065 RAII_VAR(struct ast_xml_doc *, pidf_doc, NULL, ast_xml_close);
1066 struct ast_xml_node *root_node;
1067 char *doc_str = NULL;
1068 int doc_len;
1069 int rc = 0;
1070 struct ast_xml_node *temp_node = NULL;
1071 const char *entity = NULL;
1072 int has_no_entity = 0;
1073 const char *params[] = { "suppress_empty_ca_elements", "false()", NULL };
1074
1075 SCOPE_ENTER(3, "%s\n", ref_string);
1076
1077 if (!eprofile || !chan || !buf || !*buf || ast_strlen_zero(ref_string)) {
1078 SCOPE_EXIT_RTN_VALUE(NULL, "%s: One of eprofile, chan or buf was NULL\n",
1079 ref_string);
1080 }
1081
1082 if (eprofile->format == AST_GEOLOC_FORMAT_URI) {
1083 SCOPE_EXIT_RTN_VALUE(NULL, "%s: eprofile '%s' was a URI format\n",
1084 ref_string, eprofile->id);
1085 }
1086
1087 intermediate = ast_xml_new();
1088 if (!intermediate) {
1089 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR, "%s: Unable to create XML document\n", ref_string);
1090 }
1091 root_node = ast_xml_new_node("presence");
1092 if (!root_node) {
1093 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR, "%s: Unable to create root XML node\n", ref_string);
1094 }
1095 ast_xml_set_root(intermediate, root_node);
1096
1097 entity = ast_xml_get_attribute(root_node, "entity");
1098 has_no_entity = ast_strlen_zero(entity);
1099 ast_xml_free_attr(entity);
1100 if (has_no_entity) {
1101 rc = ast_xml_set_attribute(root_node, "entity", eprofile->id);
1102 if (rc != 0) {
1103 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR, "%s: Unable to set 'entity' XML attribute\n", ref_string);
1104 }
1105 }
1106
1108 ast_geoloc_pidf_element_to_name(eprofile->pidf_element), eprofile, chan, ref_string);
1109 if (!temp_node) {
1110 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR, "%s: Unable to create temp_node for eprofile '%s'\n",
1111 ref_string, eprofile->id);
1112 }
1113
1114 ast_xml_add_child(root_node, temp_node);
1115
1116 if (TRACE_ATLEAST(5)) {
1117 ast_xml_doc_dump_memory(intermediate, &doc_str, &doc_len);
1118 ast_trace(5, "Intermediate doc len: %d\n%s\n", doc_len, doc_len ? doc_str : "<empty>");
1119 ast_xml_free_text(doc_str);
1120 doc_str = NULL;
1121 doc_len = 0;
1122 }
1123
1124 if (eprofile->suppress_empty_ca_elements) {
1125 params[1] = "true()";
1126 }
1127 pidf_doc = ast_xslt_apply(eprofile_to_pidf_xslt, intermediate, params);
1128 if (!pidf_doc) {
1129 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR, "%s: Unable to create final PIDF-LO doc from intermediate doc\n",
1130 ref_string);
1131 }
1132
1133 ast_xml_doc_dump_memory(pidf_doc, &doc_str, &doc_len);
1134 if (doc_len == 0 || !doc_str) {
1135 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR, "%s: Unable to dump final PIDF-LO doc to string\n",
1136 ref_string);
1137 }
1138
1139 rc = ast_str_set(buf, 0, "%s", doc_str);
1140 ast_xml_free_text(doc_str);
1141 if (rc <= 0) {
1142 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR, "%s: Unable to extend buffer (%d)\n",
1143 ref_string, rc);
1144 }
1145
1146 ast_trace(5, "Final doc:\n%s\n", ast_str_buffer(*buf));
1147
1148 SCOPE_EXIT_RTN_VALUE(ast_str_buffer(*buf), "%s: Done\n", ref_string);
1149}
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
static struct ast_xslt_doc * eprofile_to_pidf_xslt
static struct ast_xml_node * geoloc_eprofile_to_intermediate(const char *element_name, struct ast_geoloc_eprofile *eprofile, struct ast_channel *chan, const char *ref_string)
#define SCOPE_EXIT_LOG_RTN_VALUE(__value, __log_level,...)
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:761
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1113
struct ast_xml_node * ast_xml_add_child(struct ast_xml_node *parent, struct ast_xml_node *child)
Add a child node, to a specified parent node.
Definition: xml.c:170
const char * ast_xml_get_attribute(struct ast_xml_node *node, const char *attrname)
Get a node attribute by name.
Definition: xml.c:269
struct ast_xml_node * ast_xml_new_node(const char *name)
Create a XML node.
Definition: xml.c:146
void ast_xml_free_attr(const char *attribute)
Free an attribute returned by ast_xml_get_attribute()
Definition: xml.c:255
struct ast_xml_doc * ast_xml_new(void)
Create a XML document.
Definition: xml.c:138
int ast_xml_set_attribute(struct ast_xml_node *node, const char *name, const char *value)
Set an attribute to a node.
Definition: xml.c:286
void ast_xml_set_root(struct ast_xml_doc *doc, struct ast_xml_node *node)
Specify the root node of a XML document.
Definition: xml.c:223

References AST_GEOLOC_FORMAT_URI, ast_str_buffer(), ast_str_set(), ast_strlen_zero(), ast_trace, ast_xml_add_child(), ast_xml_close(), ast_xml_doc_dump_memory(), ast_xml_free_attr(), ast_xml_free_text(), ast_xml_get_attribute(), ast_xml_new(), ast_xml_new_node(), ast_xml_set_attribute(), ast_xml_set_root(), buf, eprofile_to_pidf_xslt, ast_geoloc_eprofile::format, geoloc_eprofile_to_intermediate(), ast_geoloc_eprofile::id, LOG_ERROR, NULL, ast_geoloc_eprofile::pidf_element, RAII_VAR, SCOPE_ENTER, SCOPE_EXIT_LOG_RTN_VALUE, SCOPE_EXIT_RTN_VALUE, ast_geoloc_eprofile::suppress_empty_ca_elements, and TRACE_ATLEAST.

Referenced by add_eprofile_to_tdata().

◆ ast_geoloc_eprofile_to_uri()

const char * ast_geoloc_eprofile_to_uri ( struct ast_geoloc_eprofile eprofile,
struct ast_channel chan,
struct ast_str **  buf,
const char *  ref_string 
)

Convert a URI eprofile to a URI string.

Parameters
eprofileEffective profile to convert
chanChannel to use to resolve variables
bufPointer to ast_str pointer to use for work
ref_stringAn identifying string to use in error messages.
Returns
String representation of URI allocated from buf or NULL on failure

Definition at line 400 of file geoloc_eprofile.c.

402{
403 const char *uri = NULL;
404 struct ast_variable *resolved = NULL;
405 char *result;
406 int we_created_buf = 0;
407
408 if (!eprofile || !buf || !chan) {
409 return NULL;
410 }
411
412 if (eprofile->format != AST_GEOLOC_FORMAT_URI) {
413 ast_log(LOG_ERROR, "%s: '%s' is not a URI profile. It's '%s'\n",
414 ref_str, eprofile->id, ast_geoloc_format_to_name(eprofile->format));
415 return NULL;
416 }
417
419 eprofile->location_variables, chan);
420 if (!resolved) {
421 return NULL;
422 }
423
424 uri = ast_variable_find_in_list(resolved, "URI");
425 result = uri ? ast_strdupa(uri) : NULL;
426 ast_variables_destroy(resolved);
427
428 if (ast_strlen_zero(result)) {
429 ast_log(LOG_ERROR, "%s: '%s' is a URI profile but had no, or an empty, 'URI' entry in location_info\n",
430 ref_str, eprofile->id);
431 return NULL;
432 }
433
434 if (!*buf) {
435 *buf = ast_str_create(256);
436 if (!*buf) {
437 return NULL;
438 }
439 we_created_buf = 1;
440 }
441
442 if (ast_str_append(buf, 0, "%s", result) <= 0) {
443 if (we_created_buf) {
444 ast_free(*buf);
445 *buf = NULL;
446 return NULL;
447 }
448 }
449
450 return ast_str_buffer(*buf);
451}
#define ast_free(a)
Definition: astmm.h:180
struct ast_variable * geoloc_eprofile_resolve_varlist(struct ast_variable *source, struct ast_variable *variables, struct ast_channel *chan)
const char * ast_variable_find_in_list(const struct ast_variable *list, const char *variable)
Gets the value of a variable from a variable list by name.
Definition: main/config.c:919
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1139
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition: strings.h:659

References ast_free, AST_GEOLOC_FORMAT_URI, ast_log, ast_str_append(), ast_str_buffer(), ast_str_create, ast_strdupa, ast_strlen_zero(), ast_variable_find_in_list(), ast_variables_destroy(), buf, ast_geoloc_eprofile::effective_location, ast_geoloc_eprofile::format, geoloc_eprofile_resolve_varlist(), ast_geoloc_eprofile::id, ast_geoloc_eprofile::location_variables, LOG_ERROR, NULL, and result.

Referenced by handle_outgoing_request().

◆ ast_geoloc_eprofiles_to_pidf()

const char * ast_geoloc_eprofiles_to_pidf ( struct ast_datastore ds,
struct ast_channel chan,
struct ast_str **  buf,
const char *  ref_string 
)

Convert a datastore containing eprofiles to a PIDF-LO document.

Parameters
dsDatastore containing effective profiles to convert
chanChannel to use to resolve variables
bufPointer to ast_str pointer to use for work
ref_stringAn identifying string to use in error messages.
Returns
String representation PIDF-LO allocated from buf or NULL on failure.

Definition at line 954 of file geoloc_eprofile.c.

956{
957 RAII_VAR(struct ast_xml_doc *, intermediate, NULL, ast_xml_close);
958 RAII_VAR(struct ast_xml_doc *, pidf_doc, NULL, ast_xml_close);
959 struct ast_xml_node *root_node;
960 struct ast_xml_node *pidfs[AST_PIDF_ELEMENT_LAST] = {NULL, };
961 struct ast_geoloc_eprofile *eprofile;
962 int eprofile_count = 0;
963 int i;
964 char *doc_str = NULL;
965 int doc_len = 0;
966 int rc = 0;
967 SCOPE_ENTER(3, "%s\n", ref_string);
968
969 if (!ds || !chan || !buf || !*buf || ast_strlen_zero(ref_string)) {
970 SCOPE_EXIT_RTN_VALUE(NULL, "%s: Either or both datastore or chan were NULL\n",
971 ref_string);
972 }
973
974 intermediate = ast_xml_new();
975 if (!intermediate) {
976 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR, "%s: Unable to create XML document\n", ref_string);
977 }
978 root_node = ast_xml_new_node("presence");
979 if (!root_node) {
980 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR, "%s: Unable to create root XML node\n", ref_string);
981 }
982 ast_xml_set_root(intermediate, root_node);
983
984 eprofile_count = ast_geoloc_datastore_size(ds);
985 for (i = 0; i < eprofile_count; i++) {
986 struct ast_xml_node *temp_node = NULL;
987 struct ast_xml_node *curr_loc = NULL;
988 struct ast_xml_node *new_loc = NULL;
989 struct ast_xml_node *new_loc_child = NULL;
990 struct ast_xml_node *new_loc_child_dup = NULL;
991 const char *entity = NULL;
992 int has_no_entity = 0;
993 eprofile = ast_geoloc_datastore_get_eprofile(ds, i);
994 if (eprofile->format == AST_GEOLOC_FORMAT_URI) {
995 continue;
996 }
997
998 entity = ast_xml_get_attribute(root_node, "entity");
999 has_no_entity = ast_strlen_zero(entity);
1000 ast_xml_free_attr(entity);
1001 if (has_no_entity) {
1002 rc = ast_xml_set_attribute(root_node, "entity", eprofile->id);
1003 if (rc != 0) {
1004 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR, "%s: Unable to set 'entity' XML attribute\n", ref_string);
1005 }
1006 }
1007
1008 temp_node = geoloc_eprofile_to_intermediate(ast_geoloc_pidf_element_to_name(eprofile->pidf_element),
1009 eprofile, chan, ref_string);
1010 if (!temp_node) {
1011 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR, "%s: Unable to create temp_node\n", ref_string);
1012 }
1013
1014 if (!pidfs[eprofile->pidf_element]) {
1015 pidfs[eprofile->pidf_element] = temp_node;
1016 ast_xml_add_child(root_node, temp_node);
1017 continue;
1018 }
1019
1020 curr_loc = ast_xml_find_child_element(pidfs[eprofile->pidf_element], "location-info", NULL, NULL);
1021 new_loc = ast_xml_find_child_element(temp_node, "location-info", NULL, NULL);
1022 new_loc_child = ast_xml_node_get_children(new_loc);
1023 new_loc_child_dup = ast_xml_copy_node_list(new_loc_child);
1024 ast_xml_add_child_list(curr_loc, new_loc_child_dup);
1025
1026 ast_xml_free_node(temp_node);
1027 }
1028
1029 if (TRACE_ATLEAST(5)) {
1030 ast_xml_doc_dump_memory(intermediate, &doc_str, &doc_len);
1031 ast_trace(5, "Intermediate doc len: %d\n%s\n", doc_len, doc_len ? doc_str : "<empty>");
1032 ast_xml_free_text(doc_str);
1033 doc_str = NULL;
1034 doc_len = 0;
1035 }
1036
1037 pidf_doc = ast_xslt_apply(eprofile_to_pidf_xslt, intermediate, NULL);
1038 if (!pidf_doc) {
1039 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR, "%s: Unable to create final PIDF-LO doc from intermediate docs\n",
1040 ref_string);
1041 }
1042
1043 ast_xml_doc_dump_memory(pidf_doc, &doc_str, &doc_len);
1044 if (doc_len == 0 || !doc_str) {
1045 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR, "%s: Unable to dump final PIDF-LO doc to string\n",
1046 ref_string);
1047 }
1048
1049 rc = ast_str_set(buf, 0, "%s", doc_str);
1050 ast_xml_free_text(doc_str);
1051 if (rc <= 0) {
1052 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR, "%s: Unable to extend buffer (%d)\n",
1053 ref_string, rc);
1054 }
1055
1056 ast_trace(5, "Final doc:\n%s\n", ast_str_buffer(*buf));
1057
1058 SCOPE_EXIT_RTN_VALUE(ast_str_buffer(*buf), "%s: Done\n", ref_string);
1059}
struct ast_geoloc_eprofile * ast_geoloc_datastore_get_eprofile(struct ast_datastore *ds, int ix)
Retrieve a specific eprofile from a datastore by index.
int ast_geoloc_datastore_size(struct ast_datastore *ds)
Retrieves the number of eprofiles in the datastore.
#define ast_xml_find_child_element(_parent_node, _name, _attrname, _attrvalue)
Find a direct child element by name.
Definition: xml.h:201
struct ast_xml_node * ast_xml_copy_node_list(struct ast_xml_node *list)
Create a copy of a n ode list.
Definition: xml.c:186
struct ast_xml_node * ast_xml_node_get_children(struct ast_xml_node *node)
Get the node's children.
Definition: xml.c:397
struct ast_xml_node * ast_xml_add_child_list(struct ast_xml_node *parent, struct ast_xml_node *child)
Add a list of child nodes, to a specified parent node.
Definition: xml.c:178
void ast_xml_free_node(struct ast_xml_node *node)
Free node.
Definition: xml.c:245

References ast_geoloc_datastore_get_eprofile(), ast_geoloc_datastore_size(), AST_GEOLOC_FORMAT_URI, AST_PIDF_ELEMENT_LAST, ast_str_buffer(), ast_str_set(), ast_strlen_zero(), ast_trace, ast_xml_add_child(), ast_xml_add_child_list(), ast_xml_close(), ast_xml_copy_node_list(), ast_xml_doc_dump_memory(), ast_xml_find_child_element, ast_xml_free_attr(), ast_xml_free_node(), ast_xml_free_text(), ast_xml_get_attribute(), ast_xml_new(), ast_xml_new_node(), ast_xml_node_get_children(), ast_xml_set_attribute(), ast_xml_set_root(), buf, eprofile_to_pidf_xslt, ast_geoloc_eprofile::format, geoloc_eprofile_to_intermediate(), ast_geoloc_eprofile::id, LOG_ERROR, NULL, ast_geoloc_eprofile::pidf_element, RAII_VAR, SCOPE_ENTER, SCOPE_EXIT_LOG_RTN_VALUE, SCOPE_EXIT_RTN_VALUE, and TRACE_ATLEAST.

◆ ast_geoloc_get_location()

struct ast_geoloc_location * ast_geoloc_get_location ( const char *  id)

Retrieve a geolocation location object by id.

Parameters
idLocation object id.
Returns
Location object or NULL if not found.

Definition at line 580 of file geoloc_config.c.

581{
582 if (ast_strlen_zero(id)) {
583 return NULL;
584 }
585
586 return ast_sorcery_retrieve_by_id(geoloc_sorcery, "location", id);
587}
static struct ast_sorcery * geoloc_sorcery
Definition: geoloc_config.c:25

References ast_sorcery_retrieve_by_id(), ast_strlen_zero(), geoloc_sorcery, and NULL.

Referenced by geoloc_profile_write().

◆ ast_geoloc_get_profile()

struct ast_geoloc_profile * ast_geoloc_get_profile ( const char *  id)

Retrieve a geolocation profile by id.

Parameters
idprofile id.
Returns
Profile or NULL if not found.

Definition at line 589 of file geoloc_config.c.

590{
591 if (ast_strlen_zero(id)) {
592 return NULL;
593 }
594
595 return ast_sorcery_retrieve_by_id(geoloc_sorcery, "profile", id);
596}

References ast_sorcery_retrieve_by_id(), ast_strlen_zero(), geoloc_sorcery, and NULL.

Referenced by handle_incoming_request(), handle_outgoing_request(), and sip_endpoint_apply_handler().

◆ ast_geoloc_gml_validate_varlist()

enum ast_geoloc_validate_result ast_geoloc_gml_validate_varlist ( const struct ast_variable varlist,
const char **  result 
)

Validate that the variables in the list represent a valid GML shape.

Parameters
varlistVariable list to check.
[out]resultPointer to char * to receive failing item.
Returns
result code.

Definition at line 124 of file geoloc_gml.c.

126{
127 int def_index = -1;
128 const struct ast_variable *var;
129 int i;
130 const char *shape_type = ast_variable_find_in_list(varlist, "shape");
131
132 if (!shape_type) {
134 }
135
136 for (i = 0; i < ARRAY_LEN(gml_shape_defs); i++) {
137 if (ast_strings_equal(gml_shape_defs[i].shape_type, shape_type)) {
138 def_index = i;
139 }
140 }
141 if (def_index < 0) {
143 }
144
145 for (var = varlist; var; var = var->next) {
146 int vname_index = -1;
147 if (ast_strings_equal("shape", var->name)) {
148 continue;
149 }
150 for (i = 0; i < ARRAY_LEN(gml_shape_defs[def_index].required_attributes); i++) {
151 if (gml_shape_defs[def_index].required_attributes[i].attribute == NULL) {
152 break;
153 }
154 if (ast_strings_equal(gml_shape_defs[def_index].required_attributes[i].attribute, var->name)) {
155 vname_index = i;
156 break;
157 }
158 }
159 if (vname_index < 0) {
160 *result = var->name;
162 }
163 if (!gml_shape_defs[def_index].required_attributes[vname_index].validator(var->value)) {
164 *result = var->name;
166 }
167 }
168
169 for (i = 0; i < ARRAY_LEN(gml_shape_defs[def_index].required_attributes); i++) {
170 int count = 0;
171 if (gml_shape_defs[def_index].required_attributes[i].attribute == NULL) {
172 break;
173 }
174
175 for (var = varlist; var; var = var->next) {
176 if (ast_strings_equal(gml_shape_defs[def_index].required_attributes[i].attribute, var->name)) {
177 count++;
178 }
179 }
180 if (count < gml_shape_defs[def_index].required_attributes[i].min_required) {
183 }
184 if (gml_shape_defs[def_index].required_attributes[i].max_allowed > 0 &&
185 count > gml_shape_defs[def_index].required_attributes[i].max_allowed) {
188 }
189 }
191}
static struct geoloc_gml_shape_def gml_shape_defs[8]
Definition: geoloc_gml.c:106
int ast_strings_equal(const char *str1, const char *str2)
Compare strings for equality checking for NULL.
Definition: strings.c:238
const char * attribute
Definition: geoloc_gml.c:68
struct geoloc_gml_attr required_attributes[8]
Definition: geoloc_gml.c:76

References ARRAY_LEN, AST_GEOLOC_VALIDATE_INVALID_SHAPE, AST_GEOLOC_VALIDATE_INVALID_VALUE, AST_GEOLOC_VALIDATE_INVALID_VARNAME, AST_GEOLOC_VALIDATE_MISSING_SHAPE, AST_GEOLOC_VALIDATE_NOT_ENOUGH_VARNAMES, AST_GEOLOC_VALIDATE_SUCCESS, AST_GEOLOC_VALIDATE_TOO_MANY_VARNAMES, ast_strings_equal(), ast_variable_find_in_list(), geoloc_gml_attr::attribute, gml_shape_defs, NULL, geoloc_gml_shape_def::required_attributes, result, and var.

Referenced by validate_location_info().

◆ ast_geoloc_is_loaded()

int ast_geoloc_is_loaded ( void  )

Check if res_geolocation is available.

Returns
1 if available, 0 otherwise.

Definition at line 763 of file geoloc_config.c.

764{
765 return 1;
766}

Referenced by sip_endpoint_apply_handler().

◆ ast_geoloc_validate_result_to_str()

const char * ast_geoloc_validate_result_to_str ( enum ast_geoloc_validate_result  result)

Definition at line 32 of file geoloc_common.c.

33{
34 return result_names[result];
35}
static const char * result_names[]
Definition: geoloc_common.c:22

References result, and result_names.

Referenced by validate_location_info().

◆ CONFIG_STR_TO_ENUM_DECL() [1/2]

CONFIG_STR_TO_ENUM_DECL ( format  )

◆ CONFIG_STR_TO_ENUM_DECL() [2/2]

CONFIG_STR_TO_ENUM_DECL ( precedence  )

◆ GEOLOC_ENUM_TO_NAME_DECL() [1/2]

GEOLOC_ENUM_TO_NAME_DECL ( format  )

◆ GEOLOC_ENUM_TO_NAME_DECL() [2/2]

GEOLOC_ENUM_TO_NAME_DECL ( precedence  )