Asterisk - The Open Source Telephony Project GIT-master-55f4e6d
geoloc_datastore.c
Go to the documentation of this file.
1/*
2 * Asterisk -- An open source telephony toolkit.
3 *
4 * Copyright (C) 2022, Sangoma Technologies Corporation
5 *
6 * George Joseph <gjoseph@sangoma.com>
7 *
8 * See http://www.asterisk.org for more information about
9 * the Asterisk project. Please do not directly contact
10 * any of the maintainers of this project for assistance;
11 * the project provides a web site, mailing lists and IRC
12 * channels for your use.
13 *
14 * This program is free software, distributed under the terms of
15 * the GNU General Public License Version 2. See the LICENSE file
16 * at the top of the source tree.
17 */
18
19#include "asterisk.h"
20#include "asterisk/astobj2.h"
21#include "asterisk/datastore.h"
22#include "asterisk/channel.h"
24#include "asterisk/vector.h"
25#include "geoloc_private.h"
26
27#define GEOLOC_DS_TYPE "geoloc_eprofiles"
28
30
32 const char *id;
34};
35
36static void geoloc_datastore_free(void *obj)
37{
38 struct eprofiles_datastore *eds = obj;
39
42 ast_free(eds);
43}
44
45static void *geoloc_datastore_duplicate(void *obj)
46{
47 struct eprofiles_datastore *in_eds = obj;
48 struct eprofiles_datastore *out_eds;
49 int rc = 0;
50 int i = 0;
51 int eprofile_count = 0;
52
53 out_eds = ast_calloc(1, sizeof(*out_eds));
54 if (!out_eds) {
55 return NULL;
56 }
57
58 rc = AST_VECTOR_INIT(&out_eds->eprofiles, 2);
59 if (rc != 0) {
60 ast_free(out_eds);
61 return NULL;
62 }
63
64 eprofile_count = AST_VECTOR_SIZE(&in_eds->eprofiles);
65 for (i = 0; i < eprofile_count; i++) {
66 struct ast_geoloc_eprofile *ep = AST_VECTOR_GET(&in_eds->eprofiles, i);
67 rc = AST_VECTOR_APPEND(&out_eds->eprofiles, ao2_bump(ep));
68 if (rc != 0) {
69 /* This will clean up the bumped reference to the eprofile */
70 geoloc_datastore_free(out_eds);
71 return NULL;
72 }
73 }
74
75 return out_eds;
76}
77
80 .destroy = geoloc_datastore_free,
81 .duplicate = geoloc_datastore_duplicate,
82};
83
84#define IS_GEOLOC_DS(_ds) (_ds && _ds->data && ast_strings_equal(_ds->info->type, GEOLOC_DS_TYPE))
85
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}
98
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}
134
136 struct ast_geoloc_eprofile *eprofile)
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}
155
157 struct ast_geoloc_eprofile *eprofile, int index)
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}
177
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}
190
192{
193 if (!IS_GEOLOC_DS(ds)) {
194 return -1;
195 }
196 ds->inheritance = inherit ? DATASTORE_INHERIT_FOREVER : 0;
197 return 0;
198}
199
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}
218
220{
222}
223
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}
241
243 struct ast_geoloc_eprofile *eprofile)
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}
265
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}
307
309{
310 if (geoloc_sorcery) {
312 }
314}
315
317{
320}
321
323{
325}
Asterisk main include file. File version handling, generic pbx functions.
#define ast_free(a)
Definition: astmm.h:180
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
#define ast_log
Definition: astobj2.c:42
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
#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
General Asterisk PBX channel definitions.
#define DATASTORE_INHERIT_FOREVER
Definition: channel.h:192
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
Asterisk datastore objects.
#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
struct ast_sorcery * geoloc_get_sorcery(void)
struct ast_datastore * ast_geoloc_datastore_create_from_profile_name(const char *profile_name)
Geolocation datastore Functions.
int geoloc_channel_reload(void)
struct ast_geoloc_eprofile * ast_geoloc_datastore_get_eprofile(struct ast_datastore *ds, int ix)
Retrieve a specific eprofile from a datastore by index.
struct ast_datastore * ast_geoloc_datastore_create_from_eprofile(struct ast_geoloc_eprofile *eprofile)
Create a geoloc datastore from an effective profile.
static void geoloc_datastore_free(void *obj)
static void * geoloc_datastore_duplicate(void *obj)
struct ast_sorcery * geoloc_sorcery
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.
#define GEOLOC_DS_TYPE
int geoloc_channel_load(void)
const char * ast_geoloc_datastore_get_id(struct ast_datastore *ds)
Retrieve a geoloc datastore's id.
struct ast_datastore * ast_geoloc_datastore_create(const char *id)
Create an empty geoloc datastore.
#define IS_GEOLOC_DS(_ds)
static const struct ast_datastore_info geoloc_datastore_info
int ast_geoloc_datastore_set_inheritance(struct ast_datastore *ds, int inherit)
Sets the inheritance flag on the datastore.
int ast_geoloc_datastore_add_eprofile(struct ast_datastore *ds, struct ast_geoloc_eprofile *eprofile)
Add an eprofile to a datastore.
int ast_geoloc_datastore_size(struct ast_datastore *ds)
Retrieves the number of eprofiles in the datastore.
struct ast_datastore * ast_geoloc_datastore_find(struct ast_channel *chan)
Retrieves the geoloc datastore from a channel, if any.
int geoloc_channel_unload(void)
int ast_geoloc_datastore_delete_eprofile(struct ast_datastore *ds, int ix)
Delete a specific eprofile from a datastore by index.
#define LOG_ERROR
@ AST_MODULE_LOAD_SUCCESS
Definition: module.h:70
struct ast_geoloc_eprofile * ast_geoloc_eprofile_create_from_profile(struct ast_geoloc_profile *profile)
Allocate a new effective profile from an existing profile.
#define NULL
Definition: resample.c:96
#define ast_sorcery_unref(sorcery)
Decrease the reference count of a sorcery structure.
Definition: sorcery.h:1500
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
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
Main Channel structure associated with a channel.
Structure for a data store type.
Definition: datastore.h:31
const char * type
Definition: datastore.h:32
Structure for a data store object.
Definition: datastore.h:64
void * data
Definition: datastore.h:66
unsigned int inheritance
Definition: datastore.h:69
const ast_string_field id
Full structure for sorcery.
Definition: sorcery.c:230
struct eprofiles_datastore::geoloc_eprofiles eprofiles
Vector container support.
#define AST_VECTOR_RESET(vec, cleanup)
Reset vector.
Definition: vector.h:625
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:609
#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
#define AST_VECTOR_FREE(vec)
Deallocates this vector.
Definition: vector.h:174
#define AST_VECTOR_REMOVE(vec, idx, preserve_ordered)
Remove an element from a vector by index.
Definition: vector.h:412
#define AST_VECTOR_INIT(vec, size)
Initialize a vector.
Definition: vector.h:113
#define AST_VECTOR_APPEND(vec, elem)
Append an element to a vector, growing the vector if needed.
Definition: vector.h:256
#define AST_VECTOR(name, type)
Define a vector structure.
Definition: vector.h:44
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:680