Skip to content

Commit

Permalink
usrloc: Expose functions to store/retrieve/delete values from the Key…
Browse files Browse the repository at this point in the history
…/Value-Store
  • Loading branch information
carstenbock authored and liviuchircu committed Apr 10, 2024
1 parent 1a50d66 commit 2e485d5
Show file tree
Hide file tree
Showing 4 changed files with 264 additions and 3 deletions.
124 changes: 121 additions & 3 deletions modules/usrloc/doc/usrloc_admin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1475,9 +1475,127 @@ modparam("usrloc", "contact_refresh_timer", true)

<section id="exported_functions" xreflabel="exported_functions">
<title>Exported Functions</title>
<para>
There are no exported functions that could be used in scripts.
</para>

<section id="func_ul_add_key" xreflabel="ul_add_key(domain, aor, key_name[, key_value])">
<title>
<function moreinfo="none">ul_add_key(domain, aor, key_name[, key_value])</function>
</title>
<para>
Append a Key/Value to the Key-Value-Store of a Usrloc-Record.
</para>
<para>
Returns false, if no record is found is usrloc.
</para>
<para>Meaning of the parameters is as follows:</para>
<itemizedlist>
<listitem>
<para><emphasis>domain (string)</emphasis> - Domain of the
AOR, e.g. "location"
</para>
<para><emphasis>aor (string)</emphasis> - Address-of-Record,
save the key for a specific (registered) user.
</para>
<para><emphasis>key (string)</emphasis> - The name of the
key to be stored.
</para>
<para><emphasis>value (string, optional)</emphasis>
- The value to be stored. Not providing the value or
by providing an empty value, will delete the entry.
</para>
</listitem>
</itemizedlist>
<para>
This function can be used in ANY route.
</para>
<example>
<title><function>ul_add_key</function> usage</title>
<programlisting format="linespecific">
...
ul_add_key("location", "$tU@$td", "service_route", "$hdr(Service-Route)");
...
</programlisting>
</example>
</section>

<section id="func_ul_get_key" xreflabel="ul_get_key(domain, aor, key_name, destination)">
<title>
<function moreinfo="none">ul_get_key(domain, aor, key_name, destination)</function>
</title>
<para>
Retrieve a Key/Value from the Key-Value-Store of a Usrloc-Record.
</para>
<para>
Returns false, if no record is found is usrloc or no according key is found.
</para>
<para>Meaning of the parameters is as follows:</para>
<itemizedlist>
<listitem>
<para><emphasis>domain (string)</emphasis> - Domain of the
AOR, e.g. "location"
</para>
<para><emphasis>aor (string)</emphasis> - Address-of-Record,
save the key for a specific (registered) user.
</para>
<para><emphasis>key (string)</emphasis> - The name of the
key to be retrieved.
</para>
<para><emphasis>destination (variable)</emphasis>
- A variable, where to store the retrieved key.
</para>
</listitem>
</itemizedlist>
<para>
This function can be used in ANY route.
</para>
<example>
<title><function>ul_get_key</function> usage</title>
<programlisting format="linespecific">
...
if (ul_get_key("location", "$tU@$td", "service_route", "$avp(service_route)")) {
append_to_reply("Service-Route: $avp(service_route)\r\n");
}
...
</programlisting>
</example>
</section>

<section id="func_ul_del_key" xreflabel="ul_del_key(domain, aor, key_name)">
<title>
<function moreinfo="none">ul_del_key(domain, aor, key_name)</function>
</title>
<para>
Deletes a Key/Value from the Key-Value-Store of a Usrloc-Record.
</para>
<para>
Returns false, if no record is found is usrloc.
</para>
<para>Meaning of the parameters is as follows:</para>
<itemizedlist>
<listitem>
<para><emphasis>domain (string)</emphasis> - Domain of the
AOR, e.g. "location"
</para>
<para><emphasis>aor (string)</emphasis> - Address-of-Record,
save the key for a specific (registered) user.
</para>
<para><emphasis>key (string)</emphasis> - The name of the
key to be deleted.
</para>
</listitem>
</itemizedlist>
<para>
This function can be used in ANY route.
</para>
<example>
<title><function>ul_del_key</function> usage</title>
<programlisting format="linespecific">
...
ul_del_key("location", "$tU@$td", "service_route");
...
</programlisting>
</example>
</section>

</section>


Expand Down
91 changes: 91 additions & 0 deletions modules/usrloc/kv_store.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

#include "../../lib/cJSON.h"
#include "../../lib/osips_malloc.h"
#include "urecord.h"

int_str_t *kv_get(map_t _store, const str* _key)
{
Expand Down Expand Up @@ -238,3 +239,93 @@ void store_destroy(map_t _store)
if (_store)
map_destroy(_store, destroy_kv_store_val);
}


int w_add_key(struct sip_msg* _m, void* _d, str* aor, str* key, str* value) {
urecord_t *r;
udomain_t *domain = (udomain_t*)_d;
int_str_t insert_value;
lock_udomain(domain, aor);
get_urecord(domain, aor, &r);
if (r) {
if (value->len > 0) {
insert_value.is_str = 1;
insert_value.s.s = value->s;
insert_value.s.len = value->len;
kv_put(r->kv_storage, key, &insert_value);
} else {
kv_del(r->kv_storage, key);
}
} else {
LM_WARN("No record found - not inserting key into KV store - user not registered?\n");
unlock_udomain(domain, aor);
return -1;
}

unlock_udomain(domain, aor);
return 1;
}

int w_get_key(struct sip_msg* _m, void* _d, str* aor, str* key, pv_spec_t* destination) {
urecord_t *r;
udomain_t *domain = (udomain_t*)_d;
int_str_t * key_value;
pv_value_t out_val;

lock_udomain(domain, aor);
get_urecord(domain, aor, &r);

if (r) {
key_value = kv_get(r->kv_storage, key);
if (key_value) {
if (key_value->is_str) {
out_val.flags = PV_VAL_STR;
out_val.rs = key_value->s;
if (pv_set_value(_m, destination, 0, &out_val) != 0) {
LM_ERR("failed to write to destination variable.\n");
unlock_udomain(domain, aor);
return -1;
}
} else {
out_val.flags = PV_VAL_INT;
out_val.ri = key_value->i;
if (pv_set_value(_m, destination, 0, &out_val) != 0) {
LM_ERR("failed to write to destination variable.\n");
unlock_udomain(domain, aor);
return -1;
}
}
} else {
LM_WARN("Key not found in record - unable to retrieve value from KV store\n");
unlock_udomain(domain, aor);
return -1;
}
} else {
LM_WARN("No record found - unable to retrieve value from KV store - user not registered?\n");
unlock_udomain(domain, aor);
return -1;
}


unlock_udomain(domain, aor);
return 1;
}

int w_delete_key(struct sip_msg* _m, void* _d, str* aor, str* key) {
urecord_t *r;
udomain_t *domain = (udomain_t*)_d;


lock_udomain(domain, aor);
get_urecord(domain, aor, &r);
if (r) {
kv_del(r->kv_storage, key);
} else {
LM_WARN("No record found - not deleting value from KV store - user not registered?\n");
unlock_udomain(domain, aor);
return -1;
}

unlock_udomain(domain, aor);
return 1;
}
5 changes: 5 additions & 0 deletions modules/usrloc/kv_store.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#define __KV_STORE_H__

#include "../../map.h"
#include "../../pvar.h"

int_str_t *kv_get(map_t _store, const str* _key);
int_str_t *kv_put(map_t _store, const str* _key, const int_str_t* _val);
Expand All @@ -46,4 +47,8 @@ map_t store_deserialize(const str *input);

void store_destroy(map_t _store);

int w_add_key(struct sip_msg* _m, void* _d, str* aor, str* key, str* value);
int w_get_key(struct sip_msg* _m, void* _d, str* aor, str* key, pv_spec_t* destination);
int w_delete_key(struct sip_msg* _m, void* _d, str* aor, str* key);

#endif /* __KV_STORE_H__ */
47 changes: 47 additions & 0 deletions modules/usrloc/ul_mod.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
#include "../../globals.h" /* is_main */
#include "../../ut.h" /* str_init */
#include "../../ipc.h"
#include "../../pvar.h"

#include "ul_mod.h"
#include "dlist.h" /* register_udomain */
Expand All @@ -61,6 +62,7 @@
#include "ul_mi.h"
#include "ul_callback.h"
#include "usrloc.h"
#include "kv_store.h"

#define CONTACTID_COL "contact_id"
#define USER_COL "username"
Expand Down Expand Up @@ -91,6 +93,9 @@ int ul_check_config(void);
int ul_check_db(void);
int ul_deprec_shp(modparam_t _, void *modparam);

/*! \brief Fixup functions */
static int domain_fixup(void** param);

//static int add_replication_dest(modparam_t type, void *val);

extern int bind_usrloc(usrloc_api_t* api);
Expand Down Expand Up @@ -187,6 +192,26 @@ int latency_event_min_us;
*/
static const cmd_export_t cmds[] = {
{"ul_bind_usrloc", (cmd_function)bind_usrloc, {{0,0,0}},0},
{"ul_add_key", (cmd_function)w_add_key, {
{CMD_PARAM_STR|CMD_PARAM_STATIC, domain_fixup, 0},
{CMD_PARAM_STR, 0, 0},
{CMD_PARAM_STR, 0, 0},
{CMD_PARAM_STR|CMD_PARAM_OPT, 0, 0},
{0,0,0}},
ALL_ROUTES},
{"ul_get_key", (cmd_function)w_get_key, {
{CMD_PARAM_STR|CMD_PARAM_STATIC, domain_fixup, 0},
{CMD_PARAM_STR, 0, 0},
{CMD_PARAM_STR, 0, 0},
{CMD_PARAM_VAR, 0, 0},
{0,0,0}},
ALL_ROUTES},
{"ul_del_key", (cmd_function)w_delete_key, {
{CMD_PARAM_STR|CMD_PARAM_STATIC, domain_fixup, 0},
{CMD_PARAM_STR, 0, 0},
{CMD_PARAM_STR, 0, 0},
{0,0,0}},
ALL_ROUTES},
{0,0,{{0,0,0}},0}
};

Expand Down Expand Up @@ -933,3 +958,25 @@ int ul_check_db(void)

return 0;
}

/*! \brief
* Convert char* parameter to udomain_t* pointer
*/
static int domain_fixup(void** param)
{
udomain_t* d;
str d_nt;

if (pkg_nt_str_dup(&d_nt, (str*)*param) < 0)
return E_OUT_OF_MEM;

if (register_udomain(d_nt.s, &d) < 0) {
LM_ERR("failed to register domain\n");
return E_UNSPEC;
}

pkg_free(d_nt.s);

*param = (void*)d;
return 0;
}

0 comments on commit 2e485d5

Please sign in to comment.