|
@@ -20,6 +20,7 @@
|
|
|
|
|
|
#include "../../ip_addr.h"
|
|
|
#include "../../dprint.h"
|
|
|
+#include "../../lib/srutils/sruid.h"
|
|
|
|
|
|
#include "ul_rpc.h"
|
|
|
#include "dlist.h"
|
|
@@ -28,6 +29,17 @@
|
|
|
#include "ul_mod.h"
|
|
|
#include "utime.h"
|
|
|
|
|
|
+/*! CSEQ nr used */
|
|
|
+#define RPC_UL_CSEQ 1
|
|
|
+/*! call-id used for ul_add and ul_rm_contact */
|
|
|
+static str rpc_ul_cid = str_init("[email protected]");
|
|
|
+/*! path used for ul_add and ul_rm_contact */
|
|
|
+static str rpc_ul_path = str_init("dummypath");
|
|
|
+/*! user agent used for ul_add */
|
|
|
+static str rpc_ul_ua = str_init("SIP Router MI Server");
|
|
|
+
|
|
|
+extern sruid_t _ul_sruid;
|
|
|
+
|
|
|
static const char* ul_rpc_dump_doc[2] = {
|
|
|
"Dump user location tables",
|
|
|
0
|
|
@@ -393,9 +405,238 @@ static void ul_rpc_lookup(rpc_t* rpc, void* ctx)
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
+static void ul_rpc_rm_aor(rpc_t* rpc, void* ctx)
|
|
|
+{
|
|
|
+ udomain_t* dom;
|
|
|
+ str table = {0, 0};
|
|
|
+ str aor = {0, 0};
|
|
|
+
|
|
|
+ if (rpc->scan(ctx, "SS", &table, &aor) != 2) {
|
|
|
+ rpc->fault(ctx, 500, "Not enough parameters (table and AOR to lookup)");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* look for table */
|
|
|
+ dom = rpc_find_domain( &table );
|
|
|
+ if (dom == NULL) {
|
|
|
+ rpc->fault(ctx, 500, "Domain not found");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* process the aor */
|
|
|
+ if ( rpc_fix_aor(&aor) != 0 ) {
|
|
|
+ rpc->fault(ctx, 500, "Domain missing in AOR");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ lock_udomain( dom, &aor);
|
|
|
+ if (delete_urecord( dom, &aor, 0) < 0) {
|
|
|
+ unlock_udomain( dom, &aor);
|
|
|
+ rpc->fault(ctx, 500, "Failed to delete AOR");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ unlock_udomain( dom, &aor);
|
|
|
+ return;
|
|
|
+}
|
|
|
+
|
|
|
+static const char* ul_rpc_rm_aor_doc[2] = {
|
|
|
+ "Delete a address of record including its contacts",
|
|
|
+ 0
|
|
|
+};
|
|
|
+
|
|
|
+static void ul_rpc_rm_contact(rpc_t* rpc, void* ctx)
|
|
|
+{
|
|
|
+ udomain_t* dom;
|
|
|
+ str table = {0, 0};
|
|
|
+ str aor = {0, 0};
|
|
|
+ str contact = {0, 0};
|
|
|
+ urecord_t *rec;
|
|
|
+ ucontact_t* con;
|
|
|
+ int ret;
|
|
|
+
|
|
|
+ if (rpc->scan(ctx, "SSS", &table, &aor, &contact) != 3) {
|
|
|
+ rpc->fault(ctx, 500, "Not enough parameters (table, AOR and contact)");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* look for table */
|
|
|
+ dom = rpc_find_domain( &table );
|
|
|
+ if (dom == NULL) {
|
|
|
+ rpc->fault(ctx, 500, "Domain not found");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* process the aor */
|
|
|
+ if ( rpc_fix_aor(&aor) != 0 ) {
|
|
|
+ rpc->fault(ctx, 500, "Domain missing in AOR");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ lock_udomain( dom, &aor);
|
|
|
+
|
|
|
+ ret = get_urecord( dom, &aor, &rec);
|
|
|
+ if (ret == 1) {
|
|
|
+ unlock_udomain( dom, &aor);
|
|
|
+ rpc->fault(ctx, 404, "AOR not found");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ ret = get_ucontact( rec, &contact, &rpc_ul_cid, &rpc_ul_path, RPC_UL_CSEQ+1, &con);
|
|
|
+ if (ret < 0) {
|
|
|
+ unlock_udomain( dom, &aor);
|
|
|
+ rpc->fault(ctx, 500, "Internal error (can't get contact)");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (ret > 0) {
|
|
|
+ unlock_udomain( dom, &aor);
|
|
|
+ rpc->fault(ctx, 404, "Contact not found");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (delete_ucontact(rec, con) < 0) {
|
|
|
+ unlock_udomain( dom, &aor);
|
|
|
+ rpc->fault(ctx, 500, "Internal error (can't delete contact)");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ release_urecord(rec);
|
|
|
+ unlock_udomain( dom, &aor);
|
|
|
+ return;
|
|
|
+}
|
|
|
+
|
|
|
+static const char* ul_rpc_rm_contact_doc[2] = {
|
|
|
+ "Delete a contact from an AOR record",
|
|
|
+ 0
|
|
|
+};
|
|
|
+
|
|
|
+static void ul_rpc_flush(rpc_t* rpc, void* ctx)
|
|
|
+{
|
|
|
+ synchronize_all_udomains(0, 1);
|
|
|
+ return;
|
|
|
+}
|
|
|
+
|
|
|
+static const char* ul_rpc_flush_doc[2] = {
|
|
|
+ "Flush the usrloc memory cache to DB",
|
|
|
+ 0
|
|
|
+};
|
|
|
+
|
|
|
+/*!
|
|
|
+ * \brief Add a new contact for an address of record
|
|
|
+ * \note Expects 9 parameters: table name, AOR, contact, expires, Q,
|
|
|
+ * useless - backward compatible, flags, cflags, methods
|
|
|
+ */
|
|
|
+static void ul_rpc_add(rpc_t* rpc, void* ctx)
|
|
|
+{
|
|
|
+ str table = {0, 0};
|
|
|
+ str aor = {0, 0};
|
|
|
+ str contact = {0, 0};
|
|
|
+ str useless = {0, 0};
|
|
|
+ double dtemp;
|
|
|
+ ucontact_info_t ci;
|
|
|
+ urecord_t* r;
|
|
|
+ ucontact_t* c;
|
|
|
+ udomain_t *dom;
|
|
|
+ int ret;
|
|
|
+
|
|
|
+ memset( &ci, 0, sizeof(ucontact_info_t));
|
|
|
+
|
|
|
+ ret = rpc->scan(ctx, "SSSdf.Sddd", &table, &aor, &contact, &ci.expires,
|
|
|
+ &dtemp, &useless, &ci.flags, &ci.cflags, &ci.methods);
|
|
|
+ LM_DBG("ret: %d table:%.*s aor:%.*s contact:%.*s expires:%d dtemp:%f useless:%.*s flags:%d bflags:%d methods:%d\n",
|
|
|
+ ret, table.len, table.s, aor.len, aor.s, contact.len, contact.s,
|
|
|
+ (int) ci.expires, dtemp, useless.len, useless.s, ci.flags, ci.cflags, (int) ci.methods);
|
|
|
+ if ( ret != 9) {
|
|
|
+ rpc->fault(ctx, 500, "Not enough parameters or wrong format");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ ci.q = double2q(dtemp);
|
|
|
+ useless.s = q2str(ci.q, (unsigned int*)&useless.len);
|
|
|
+ LM_DBG("q:%.*s\n", useless.len, useless.s);
|
|
|
+ /* look for table */
|
|
|
+ dom = rpc_find_domain( &table );
|
|
|
+ if (dom == NULL) {
|
|
|
+ rpc->fault(ctx, 500, "Domain not found");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* process the aor */
|
|
|
+ if ( rpc_fix_aor(&aor) != 0 ) {
|
|
|
+ rpc->fault(ctx, 500, "Domain missing in AOR");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(sruid_next(&_ul_sruid)<0)
|
|
|
+ {
|
|
|
+ rpc->fault(ctx, 500, "Can't obtain next uid");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ ci.ruid = _ul_sruid.uid;
|
|
|
+
|
|
|
+ lock_udomain( dom, &aor);
|
|
|
+
|
|
|
+ ret = get_urecord( dom, &aor, &r);
|
|
|
+ if(ret==1) {
|
|
|
+ if (insert_urecord( dom, &aor, &r) < 0)
|
|
|
+ {
|
|
|
+ unlock_udomain( dom, &aor);
|
|
|
+ rpc->fault(ctx, 500, "Can't insert record");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ c = 0;
|
|
|
+ } else {
|
|
|
+ if (get_ucontact( r, &contact, &rpc_ul_cid, &rpc_ul_path, RPC_UL_CSEQ+1, &c) < 0)
|
|
|
+ {
|
|
|
+ unlock_udomain( dom, &aor);
|
|
|
+ rpc->fault(ctx, 500, "Can't get record");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ get_act_time();
|
|
|
+
|
|
|
+ ci.callid = &rpc_ul_cid;
|
|
|
+ ci.user_agent = &rpc_ul_ua;
|
|
|
+ ci.cseq = RPC_UL_CSEQ;
|
|
|
+ /* 0 expires means permanent contact */
|
|
|
+ if (ci.expires!=0)
|
|
|
+ ci.expires += act_time;
|
|
|
+
|
|
|
+ if (c) {
|
|
|
+ if (update_ucontact( r, c, &ci) < 0)
|
|
|
+ {
|
|
|
+ release_urecord(r);
|
|
|
+ unlock_udomain( dom, &aor);
|
|
|
+ rpc->fault(ctx, 500, "Can't update contact");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if ( insert_ucontact( r, &contact, &ci, &c) < 0 )
|
|
|
+ {
|
|
|
+ release_urecord(r);
|
|
|
+ unlock_udomain( dom, &aor);
|
|
|
+ rpc->fault(ctx, 500, "Can't insert contact");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ release_urecord(r);
|
|
|
+ unlock_udomain( dom, &aor);
|
|
|
+ return;
|
|
|
+}
|
|
|
+
|
|
|
+static const char* ul_rpc_add_doc[2] = {
|
|
|
+ "Add a new contact for an address of record",
|
|
|
+ 0
|
|
|
+};
|
|
|
+
|
|
|
rpc_export_t ul_rpc[] = {
|
|
|
{"ul.dump", ul_rpc_dump, ul_rpc_dump_doc, 0},
|
|
|
{"ul.lookup", ul_rpc_lookup, ul_rpc_lookup_doc, 0},
|
|
|
+ {"ul.rm", ul_rpc_rm_aor, ul_rpc_rm_aor_doc, 0},
|
|
|
+ {"ul.rm_contact", ul_rpc_rm_contact, ul_rpc_rm_contact_doc, 0},
|
|
|
+ {"ul.flush", ul_rpc_flush, ul_rpc_flush_doc, 0},
|
|
|
+ {"ul.add", ul_rpc_add, ul_rpc_add_doc, 0},
|
|
|
{0, 0, 0, 0}
|
|
|
};
|
|
|
|