Просмотр исходного кода

Merge branch 'master' into outbound

* master:
  modules_s/usrloc: moved to obsolete folder
  modules_s/registrar: moved to obsolete folder
  modules_s/.gitkeep: added a placeholder to keep empty modules_s folder for a while
  Makefile: make TAGS skips the obsolete folder
  usrloc(k): fixed position of xavp_contact parameter in docs
  usrloc: store per-contact attributes in database
  core: fixed xavp level cloning function
  core: added a fuction that adds an xavp with an xavp value
  kamctl: regenerated database creation scripts
  lib/srdb1: added location_attrs table
Peter Dunkley 12 лет назад
Родитель
Сommit
3efe73dc00
85 измененных файлов с 810 добавлено и 87 удалено
  1. 1 1
      Makefile.defs
  2. 8 4
      Makefile.rules
  3. 1 0
      lib/srdb1/schema/kamailio-usrloc.xml
  4. 101 0
      lib/srdb1/schema/location_attrs.xml
  5. 54 53
      modules_k/usrloc/README
  6. 8 9
      modules_k/usrloc/doc/usrloc_admin.xml
  7. 190 1
      modules_k/usrloc/ucontact.c
  8. 27 0
      modules_k/usrloc/ucontact.h
  9. 182 0
      modules_k/usrloc/udomain.c
  10. 12 0
      modules_k/usrloc/udomain.h
  11. 18 0
      modules_k/usrloc/ul_mod.c
  12. 9 0
      modules_k/usrloc/ul_mod.h
  13. 0 0
      modules_s/.gitkeep
  14. 0 0
      obsolete/registrar/Makefile
  15. 0 0
      obsolete/registrar/README
  16. 0 0
      obsolete/registrar/common.c
  17. 0 0
      obsolete/registrar/common.h
  18. 0 0
      obsolete/registrar/doc/Makefile
  19. 0 0
      obsolete/registrar/doc/functions.xml
  20. 0 0
      obsolete/registrar/doc/params.xml
  21. 0 0
      obsolete/registrar/doc/registrar.xml
  22. 0 0
      obsolete/registrar/lookup.c
  23. 0 0
      obsolete/registrar/lookup.h
  24. 0 0
      obsolete/registrar/reg_mod.c
  25. 0 0
      obsolete/registrar/reg_mod.h
  26. 0 0
      obsolete/registrar/regtime.c
  27. 0 0
      obsolete/registrar/regtime.h
  28. 0 0
      obsolete/registrar/reply.c
  29. 0 0
      obsolete/registrar/reply.h
  30. 0 0
      obsolete/registrar/rerrno.c
  31. 0 0
      obsolete/registrar/rerrno.h
  32. 0 0
      obsolete/registrar/save.c
  33. 0 0
      obsolete/registrar/save.h
  34. 0 0
      obsolete/registrar/sip_msg.c
  35. 0 0
      obsolete/registrar/sip_msg.h
  36. 0 0
      obsolete/usrloc/Makefile
  37. 0 0
      obsolete/usrloc/README
  38. 0 0
      obsolete/usrloc/dlist.c
  39. 0 0
      obsolete/usrloc/dlist.h
  40. 0 0
      obsolete/usrloc/doc/Makefile
  41. 0 0
      obsolete/usrloc/doc/api.xml
  42. 0 0
      obsolete/usrloc/doc/functions.xml
  43. 0 0
      obsolete/usrloc/doc/params.xml
  44. 0 0
      obsolete/usrloc/doc/usrloc.xml
  45. 0 0
      obsolete/usrloc/doc/usrloc_states_w_zombie.png
  46. 0 0
      obsolete/usrloc/doc/usrloc_states_w_zombie.vsd
  47. 0 0
      obsolete/usrloc/hslot.c
  48. 0 0
      obsolete/usrloc/hslot.h
  49. 0 0
      obsolete/usrloc/notify.c
  50. 0 0
      obsolete/usrloc/notify.h
  51. 0 0
      obsolete/usrloc/reg_avps.c
  52. 0 0
      obsolete/usrloc/reg_avps.h
  53. 0 0
      obsolete/usrloc/reg_avps_db.c
  54. 0 0
      obsolete/usrloc/reg_avps_db.h
  55. 0 0
      obsolete/usrloc/ucontact.c
  56. 0 0
      obsolete/usrloc/ucontact.h
  57. 0 0
      obsolete/usrloc/udomain.c
  58. 0 0
      obsolete/usrloc/udomain.h
  59. 0 0
      obsolete/usrloc/ul_callback.c
  60. 0 0
      obsolete/usrloc/ul_callback.h
  61. 0 0
      obsolete/usrloc/ul_mod.c
  62. 0 0
      obsolete/usrloc/ul_mod.h
  63. 0 0
      obsolete/usrloc/ul_rpc.c
  64. 0 0
      obsolete/usrloc/ul_rpc.h
  65. 0 0
      obsolete/usrloc/urecord.c
  66. 0 0
      obsolete/usrloc/urecord.h
  67. 0 0
      obsolete/usrloc/usrloc.c
  68. 0 0
      obsolete/usrloc/usrloc.h
  69. 0 0
      obsolete/usrloc/utime.c
  70. 0 0
      obsolete/usrloc/utime.h
  71. 12 0
      utils/kamctl/db_berkeley/kamailio/location_attrs
  72. 2 2
      utils/kamctl/db_sqlite/sca-create.sql
  73. 15 0
      utils/kamctl/db_sqlite/usrloc-create.sql
  74. 2 0
      utils/kamctl/dbtext/kamailio/location_attrs
  75. 2 2
      utils/kamctl/mysql/sca-create.sql
  76. 15 0
      utils/kamctl/mysql/usrloc-create.sql
  77. 1 1
      utils/kamctl/oracle/sca-create.sql
  78. 23 0
      utils/kamctl/oracle/usrloc-create.sql
  79. 2 2
      utils/kamctl/postgres/sca-create.sql
  80. 15 0
      utils/kamctl/postgres/usrloc-create.sql
  81. 41 11
      utils/kamctl/xhttp_pi/pi_framework.xml
  82. 17 0
      utils/kamctl/xhttp_pi/usrloc-mod
  83. 13 0
      utils/kamctl/xhttp_pi/usrloc-table
  84. 38 1
      xavp.c
  85. 1 0
      xavp.h

+ 1 - 1
Makefile.defs

@@ -270,7 +270,7 @@ CC_LONGVER:=$(shell if  $(CC) -v 2>/dev/null; then \
 					else \
 					else \
 						$(CC) -V 2>&1 ; \
 						$(CC) -V 2>&1 ; \
 					fi )
 					fi )
-MKTAGS=ctags -R .
+MKTAGS=ctags
 
 
 #find-out the compiler's name
 #find-out the compiler's name
 
 

+ 8 - 4
Makefile.rules

@@ -288,10 +288,14 @@ clean_doxygen:
 
 
 .PHONY: TAGS
 .PHONY: TAGS
 TAGS:
 TAGS:
-	$(MKTAGS) 
-	
-	
-	
+	$(MKTAGS) --exclude="obsolete/*" -R .
+
+.PHONY: TAGS-ALL
+TAGS-ALL:
+	$(MKTAGS) -R .
+
+
+
 ifeq (,$(MAKECMDGOALS))
 ifeq (,$(MAKECMDGOALS))
 -include $(depends)
 -include $(depends)
 else
 else

+ 1 - 0
lib/srdb1/schema/kamailio-usrloc.xml

@@ -9,4 +9,5 @@
 <database xmlns:xi="http://www.w3.org/2001/XInclude">
 <database xmlns:xi="http://www.w3.org/2001/XInclude">
     <name>User location</name>
     <name>User location</name>
     <xi:include href="location.xml"/>
     <xi:include href="location.xml"/>
+    <xi:include href="location_attrs.xml"/>
 </database>
 </database>

+ 101 - 0
lib/srdb1/schema/location_attrs.xml

@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE table PUBLIC "-//kamailio.org//DTD DBSchema V1.1//EN" 
+  "http://kamailio.org/pub/kamailio/dbschema/dtd/1.1/dbschema.dtd" [
+
+<!ENTITY % entities SYSTEM "entities.xml">
+%entities;
+
+]>
+
+<table id="location" xmlns:db="http://docbook.org/ns/docbook">
+    <name>location_attrs</name>
+    <version>1</version>
+    <type db="mysql">&MYSQL_TABLE_TYPE;</type>
+    <description>
+        <db:para>Persistent user location attributes for the usrloc module. More information can be found at: &KAMAILIO_MOD_DOC;usrloc.html
+        </db:para>
+    </description>
+
+    <column id="id">
+        <name>id</name>
+        <type>unsigned int</type>
+        <size>&table_id_len;</size>
+        <autoincrement/>
+        <primary/>
+        <type db="dbtext">int,auto</type>
+        <description>unique ID</description>
+    </column>
+
+    <column id="ruid">
+        <name>ruid</name>
+        <type>string</type>
+        <size>64</size>
+        <default/>
+        <description>Record internal unique id</description>
+        <natural/>
+    </column>
+
+	<column id="username">
+        <name>&USERCOL;</name>
+        <type>string</type>
+        <size>&user_len;</size>
+        <default/>
+        <description>Username / phone number </description>
+        <natural/>
+    </column>
+
+    <column id="domain">
+        <name>domain</name>
+        <type>string</type>
+        <size>&domain_len;</size>
+        <null/>
+        <default><null/></default>
+        <description>Domain name</description>
+        <natural/>
+    </column>
+
+    <column>
+        <name>aname</name>
+        <type>string</type>
+        <size>64</size>
+		<default/>
+        <description>Attribute name.</description>
+    </column>
+
+    <column>
+        <name>atype</name>
+        <type>int</type>
+        <size>11</size>
+        <default>0</default>
+        <description>Attribute type.</description>
+    </column>
+
+    <column>
+        <name>avalue</name>
+        <type>string</type>
+        <size>255</size>
+        <default/>
+        <description>Attribute value.</description>
+    </column>
+
+    <column id="last_modified">
+        <name>last_modified</name>
+        <type>datetime</type>
+        <default>&DEFAULT_DATETIME;</default>
+        <default db="oracle">to_date('&DEFAULT_DATETIME;','yyyy-mm-dd hh24:mi:ss')</default>
+        <description>Date and time when this entry was last modified.</description>
+    </column>
+
+    <index>
+        <name>account_record_idx</name>
+        <colref linkend="username"/>
+        <colref linkend="domain"/>
+        <colref linkend="ruid"/>
+    </index>
+    <index>
+        <name>last_modified_idx</name>
+        <colref linkend="last_modified"/>
+    </index>
+
+
+</table>

+ 54 - 53
modules_k/usrloc/README

@@ -66,24 +66,24 @@ Bogdan-Andrei Iancu
               3.28. db_update_as_insert (string)
               3.28. db_update_as_insert (string)
               3.29. db_check_update (string)
               3.29. db_check_update (string)
               3.30. timer_procs (string)
               3.30. timer_procs (string)
+              3.31. xavp_contact (string)
 
 
         4. Functions
         4. Functions
-        5. xavp_contact (string)
-        6. MI Commands
+        5. MI Commands
 
 
-              6.1. ul_rm
-              6.2. ul_rm_contact
-              6.3. ul_dump
-              6.4. ul_flush
-              6.5. ul_add
-              6.6. ul_show_contact
+              5.1. ul_rm
+              5.2. ul_rm_contact
+              5.3. ul_dump
+              5.4. ul_flush
+              5.5. ul_add
+              5.6. ul_show_contact
 
 
-        7. Statistics
+        6. Statistics
 
 
-              7.1. users
-              7.2. contacts
-              7.3. expires
-              7.4. registered_users
+              6.1. users
+              6.2. contacts
+              6.3. expires
+              6.4. registered_users
 
 
    2. Developer Guide
    2. Developer Guide
 
 
@@ -188,24 +188,24 @@ Chapter 1. Admin Guide
         3.28. db_update_as_insert (string)
         3.28. db_update_as_insert (string)
         3.29. db_check_update (string)
         3.29. db_check_update (string)
         3.30. timer_procs (string)
         3.30. timer_procs (string)
+        3.31. xavp_contact (string)
 
 
    4. Functions
    4. Functions
-   5. xavp_contact (string)
-   6. MI Commands
+   5. MI Commands
 
 
-        6.1. ul_rm
-        6.2. ul_rm_contact
-        6.3. ul_dump
-        6.4. ul_flush
-        6.5. ul_add
-        6.6. ul_show_contact
+        5.1. ul_rm
+        5.2. ul_rm_contact
+        5.3. ul_dump
+        5.4. ul_flush
+        5.5. ul_add
+        5.6. ul_show_contact
 
 
-   7. Statistics
+   6. Statistics
 
 
-        7.1. users
-        7.2. contacts
-        7.3. expires
-        7.4. registered_users
+        6.1. users
+        6.2. contacts
+        6.3. expires
+        6.4. registered_users
 
 
 1. Overview
 1. Overview
 
 
@@ -295,6 +295,7 @@ Chapter 1. Admin Guide
    3.28. db_update_as_insert (string)
    3.28. db_update_as_insert (string)
    3.29. db_check_update (string)
    3.29. db_check_update (string)
    3.30. timer_procs (string)
    3.30. timer_procs (string)
+   3.31. xavp_contact (string)
 
 
 3.1. nat_bflag (integer)
 3.1. nat_bflag (integer)
 
 
@@ -704,11 +705,7 @@ modparam("usrloc", "db_check_update", 1)
 modparam("usrloc", "timer_procs", 4)
 modparam("usrloc", "timer_procs", 4)
 ...
 ...
 
 
-4. Functions
-
-   There are no exported functions that could be used in scripts.
-
-5. xavp_contact (string)
+3.31. xavp_contact (string)
 
 
    The name of XAVP storring the attributes per contact. They are saved in
    The name of XAVP storring the attributes per contact. They are saved in
    location record and restored at lookup.
    location record and restored at lookup.
@@ -720,16 +717,20 @@ modparam("usrloc", "timer_procs", 4)
 modparam("usrloc", "xavp_contact", "ulattrs")
 modparam("usrloc", "xavp_contact", "ulattrs")
 ...
 ...
 
 
-6. MI Commands
+4. Functions
+
+   There are no exported functions that could be used in scripts.
+
+5. MI Commands
 
 
-   6.1. ul_rm
-   6.2. ul_rm_contact
-   6.3. ul_dump
-   6.4. ul_flush
-   6.5. ul_add
-   6.6. ul_show_contact
+   5.1. ul_rm
+   5.2. ul_rm_contact
+   5.3. ul_dump
+   5.4. ul_flush
+   5.5. ul_add
+   5.6. ul_show_contact
 
 
-6.1. ul_rm
+5.1. ul_rm
 
 
    Deletes an entire AOR record (including its contacts).
    Deletes an entire AOR record (including its contacts).
 
 
@@ -738,7 +739,7 @@ modparam("usrloc", "xavp_contact", "ulattrs")
      * AOR - user AOR in username[@domain] format (domain must be supplied
      * AOR - user AOR in username[@domain] format (domain must be supplied
        only if use_domain option is on).
        only if use_domain option is on).
 
 
-6.2. ul_rm_contact
+5.2. ul_rm_contact
 
 
    Deletes a contact from an AOR record.
    Deletes a contact from an AOR record.
 
 
@@ -748,7 +749,7 @@ modparam("usrloc", "xavp_contact", "ulattrs")
        only if use_domain option is on).
        only if use_domain option is on).
      * contact - exact contact to be removed
      * contact - exact contact to be removed
 
 
-6.3. ul_dump
+5.3. ul_dump
 
 
    Dumps the entire content of the USRLOC in memory cache
    Dumps the entire content of the USRLOC in memory cache
 
 
@@ -757,11 +758,11 @@ modparam("usrloc", "xavp_contact", "ulattrs")
        "brief", a brief dump will be done (only AOR and contacts, with no
        "brief", a brief dump will be done (only AOR and contacts, with no
        other details)
        other details)
 
 
-6.4. ul_flush
+5.4. ul_flush
 
 
    Triggers the flush of USRLOC memory cache into DB.
    Triggers the flush of USRLOC memory cache into DB.
 
 
-6.5. ul_add
+5.5. ul_add
 
 
    Adds a new contact for an user AOR.
    Adds a new contact for an user AOR.
 
 
@@ -777,7 +778,7 @@ modparam("usrloc", "xavp_contact", "ulattrs")
      * cflags - per branch flags of the contact
      * cflags - per branch flags of the contact
      * methods - mask with supported requests of the contact
      * methods - mask with supported requests of the contact
 
 
-6.6. ul_show_contact
+5.6. ul_show_contact
 
 
    Dumps the contacts of an user AOR.
    Dumps the contacts of an user AOR.
 
 
@@ -786,33 +787,33 @@ modparam("usrloc", "xavp_contact", "ulattrs")
      * AOR - user AOR in username[@domain] format (domain must be supplied
      * AOR - user AOR in username[@domain] format (domain must be supplied
        only if use_domain option is on).
        only if use_domain option is on).
 
 
-7. Statistics
+6. Statistics
 
 
-   7.1. users
-   7.2. contacts
-   7.3. expires
-   7.4. registered_users
+   6.1. users
+   6.2. contacts
+   6.3. expires
+   6.4. registered_users
 
 
    Exported statistics are listed in the next sections.
    Exported statistics are listed in the next sections.
 
 
-7.1. users
+6.1. users
 
 
    Number of AOR existing in the USRLOC memory cache for that domain - can
    Number of AOR existing in the USRLOC memory cache for that domain - can
    not be resetted; this statistic will be register for each used domain
    not be resetted; this statistic will be register for each used domain
    (Ex: location).
    (Ex: location).
 
 
-7.2. contacts
+6.2. contacts
 
 
    Number of contacts existing in the USRLOC memory cache for that domain
    Number of contacts existing in the USRLOC memory cache for that domain
    - can not be resetted; this statistic will be register for each used
    - can not be resetted; this statistic will be register for each used
    domain (Ex: location).
    domain (Ex: location).
 
 
-7.3. expires
+6.3. expires
 
 
    Total number of expired contacts for that domain - can be resetted;
    Total number of expired contacts for that domain - can be resetted;
    this statistic will be register for each used domain (Ex: location).
    this statistic will be register for each used domain (Ex: location).
 
 
-7.4. registered_users
+6.4. registered_users
 
 
    Total number of AOR existing in the USRLOC memory cache for all domains
    Total number of AOR existing in the USRLOC memory cache for all domains
    - can not be resetted.
    - can not be resetted.

+ 8 - 9
modules_k/usrloc/doc/usrloc_admin.xml

@@ -823,15 +823,6 @@ modparam("usrloc", "timer_procs", 4)
 		</example>
 		</example>
 	</section>
 	</section>
 
 
-	</section>
-
-	<section>
-	<title>Functions</title>
-	<para>
-		There are no exported functions that could be used in scripts.
-	</para>
-	</section>
-
 	<section id="xavp_contact">
 	<section id="xavp_contact">
 		<title><varname>xavp_contact</varname> (string)</title>
 		<title><varname>xavp_contact</varname> (string)</title>
 		<para>
 		<para>
@@ -853,6 +844,14 @@ modparam("usrloc", "xavp_contact", "ulattrs")
 		</example>
 		</example>
 	</section>
 	</section>
 
 
+	</section>
+
+	<section>
+	<title>Functions</title>
+	<para>
+		There are no exported functions that could be used in scripts.
+	</para>
+	</section>
 
 
 	<section>
 	<section>
 	<title>MI Commands</title>
 	<title>MI Commands</title>

+ 190 - 1
modules_k/usrloc/ucontact.c

@@ -75,6 +75,7 @@ void ucontact_xavp_store(ucontact_t *_c)
 	if(xavp==NULL)
 	if(xavp==NULL)
 		return;
 		return;
 	/* clone the xavp found in core */
 	/* clone the xavp found in core */
+	LM_DBG("trying to clone per contact xavps\n");
 	_c->xavp = xavp_clone_level_nodata(xavp);
 	_c->xavp = xavp_clone_level_nodata(xavp);
 	return;
 	return;
 }
 }
@@ -615,6 +616,9 @@ int db_insert_ucontact(ucontact_t* _c)
 		return -1;
 		return -1;
 	}
 	}
 
 
+	uldb_insert_attrs(_c->domain, &vals[0].val.str_val, &vals[nr_cols-1].val.str_val,
+		&_c->ruid, _c->xavp);
+
 	return 0;
 	return 0;
 }
 }
 
 
@@ -786,9 +790,15 @@ int db_update_ucontact(ucontact_t* _c)
 		 * to do an INSERT */
 		 * to do an INSERT */
 		if(ul_dbf.affected_rows(ul_dbh)==0) {
 		if(ul_dbf.affected_rows(ul_dbh)==0) {
 			LM_DBG("affected rows by UPDATE was 0, doing an INSERT\n");
 			LM_DBG("affected rows by UPDATE was 0, doing an INSERT\n");
-			return db_insert_ucontact(_c);
+			if(db_insert_ucontact(_c)<0)
+				return -1;
 		}
 		}
 	}
 	}
+	/* delete old db attrs and add the current list */
+	uldb_delete_attrs(_c->domain, &vals1[0].val.str_val,
+			&vals1[3].val.str_val, &_c->ruid);
+	uldb_insert_attrs(_c->domain, &vals1[0].val.str_val, &vals1[3].val.str_val,
+		&_c->ruid, _c->xavp);
 
 
 	return 0;
 	return 0;
 }
 }
@@ -840,6 +850,9 @@ int db_delete_ucontact(ucontact_t* _c)
 		}
 		}
 	}
 	}
 
 
+	uldb_delete_attrs(_c->domain, &vals[0].val.str_val,
+			&vals[3].val.str_val, &_c->ruid);
+
 	if (ul_dbf.use_table(ul_dbh, _c->domain) < 0) {
 	if (ul_dbf.use_table(ul_dbh, _c->domain) < 0) {
 		LM_ERR("sql use_table failed\n");
 		LM_ERR("sql use_table failed\n");
 		return -1;
 		return -1;
@@ -969,3 +982,179 @@ int update_ucontact(struct urecord* _r, ucontact_t* _c, ucontact_info_t* _ci)
 	}
 	}
 	return 0;
 	return 0;
 }
 }
+
+/*!
+ * \brief Load all location attributes from a udomain
+ *
+ * Load all location attributes from a udomain, useful to populate the
+ * memory cache on startup.
+ * \param _dname loaded domain name
+ * \param _user sip username
+ * \param _domain sip domain
+ * \param _ruid usrloc record unique id
+ * \return 0 on success, -1 on failure
+ */
+int uldb_delete_attrs(str* _dname, str *_user, str *_domain, str *_ruid)
+{
+	char tname_buf[64];
+	str tname;
+	db_key_t keys[3];
+	db_val_t vals[3];
+
+	LM_DBG("trying to delete location attributes\n");
+
+	if(ul_xavp_contact_name.s==NULL) {
+		/* feature disabled by mod param */
+		return 0;
+	}
+
+	if(_dname->len+6>=64) {
+		LM_ERR("attributes table name is too big\n");
+		return -1;
+	}
+	strncpy(tname_buf, _dname->s, _dname->len);
+	tname_buf[_dname->len] = '\0';
+	strcat(tname_buf, "_attrs");
+	tname.s = tname_buf;
+	tname.len = _dname->len + 6;
+
+	keys[0] = &ulattrs_user_col;
+	keys[1] = &ulattrs_ruid_col;
+	keys[2] = &ulattrs_domain_col;
+
+	vals[0].type = DB1_STR;
+	vals[0].nul = 0;
+	vals[0].val.str_val = *_user;
+
+	vals[1].type = DB1_STR;
+	vals[1].nul = 0;
+	vals[1].val.str_val = *_ruid;
+
+	if (use_domain) {
+		vals[2].type = DB1_STR;
+		vals[2].nul = 0;
+		vals[2].val.str_val = *_domain;
+	}
+
+	if (ul_dbf.use_table(ul_dbh, &tname) < 0) {
+		LM_ERR("sql use_table failed\n");
+		return -1;
+	}
+
+	if (ul_dbf.delete(ul_dbh, keys, 0, vals, (use_domain) ? (3) : (2)) < 0) {
+		LM_ERR("deleting from database failed\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+/*!
+ * \brief Insert contact attributes into the database
+ * \param _dname loaded domain name
+ * \param _user sip username
+ * \param _domain sip domain
+ * \param _ruid record unique id
+ * \param _xhead head of xavp list
+ * \return 0 on success, -1 on failure
+ */
+int uldb_insert_attrs(str *_dname, str *_user, str *_domain,
+		str *_ruid, sr_xavp_t *_xhead)
+{
+	char tname_buf[64];
+	str tname;
+	str avalue;
+	sr_xavp_t *xavp;
+	db_key_t keys[7];
+	db_val_t vals[7];
+	int nr_cols;
+
+	LM_DBG("trying to insert location attributes\n");
+
+	if(ul_xavp_contact_name.s==NULL) {
+		/* feature disabled by mod param */
+		LM_DBG("location attributes disabled\n");
+		return 0;
+	}
+
+	if(_xhead==NULL || _xhead->val.type!=SR_XTYPE_XAVP
+			|| _xhead->val.v.xavp==NULL) {
+		/* nothing to write */
+		LM_DBG("no location attributes\n");
+		return 0;
+	}
+
+	if(_dname->len+6>=64) {
+		LM_ERR("attributes table name is too big\n");
+		return -1;
+	}
+	strncpy(tname_buf, _dname->s, _dname->len);
+	tname_buf[_dname->len] = '\0';
+	strcat(tname_buf, "_attrs");
+	tname.s = tname_buf;
+	tname.len = _dname->len + 6;
+
+	if (ul_dbf.use_table(ul_dbh, &tname) < 0) {
+		LM_ERR("sql use_table failed for %.*s\n", tname.len, tname.s);
+		return -1;
+	}
+
+	keys[0] = &ulattrs_user_col;
+	keys[1] = &ulattrs_ruid_col;
+	keys[2] = &ulattrs_last_mod_col;
+	keys[3] = &ulattrs_aname_col;
+	keys[4] = &ulattrs_atype_col;
+	keys[5] = &ulattrs_avalue_col;
+	keys[6] = &ulattrs_domain_col;
+
+	vals[0].type = DB1_STR;
+	vals[0].nul = 0;
+	vals[0].val.str_val = *_user;
+
+	vals[1].type = DB1_STR;
+	vals[1].nul = 0;
+	vals[1].val.str_val = *_ruid;
+
+	vals[2].type = DB1_DATETIME;
+	vals[2].nul = 0;
+	vals[2].val.time_val = time(NULL);
+
+	if (use_domain && _domain!=NULL && _domain->s!=NULL) {
+		nr_cols = 7;
+		vals[6].type = DB1_STR;
+		vals[6].nul = 0;
+		vals[6].val.str_val = *_domain;
+
+	} else {
+		nr_cols = 6;
+	}
+
+	for(xavp=_xhead->val.v.xavp; xavp; xavp=xavp->next) {
+		vals[3].type = DB1_STR;
+		vals[3].nul = 0;
+		vals[3].val.str_val = xavp->name;
+
+		vals[4].type = DB1_INT;
+		vals[4].nul = 0;
+		if(xavp->val.type==SR_XTYPE_STR) {
+			vals[4].val.int_val = 0;
+			avalue = xavp->val.v.s;
+		} else if(xavp->val.type==SR_XTYPE_INT) {
+			vals[4].val.int_val = 1;
+			avalue.s = sint2str((long)xavp->val.v.i, &avalue.len);
+		} else {
+			continue;
+		}
+
+		vals[5].type = DB1_STR;
+		vals[5].nul = 0;
+		vals[5].val.str_val = avalue;
+
+		if (ul_dbf.insert(ul_dbh, keys, vals, nr_cols) < 0) {
+			LM_ERR("inserting contact in db failed\n");
+			return -1;
+		}
+
+	}
+	return 0;
+}

+ 27 - 0
modules_k/usrloc/ucontact.h

@@ -37,6 +37,7 @@
 
 
 
 
 #include <stdio.h>
 #include <stdio.h>
+#include "../../xavp.h"
 #include "usrloc.h"
 #include "usrloc.h"
 
 
 
 
@@ -149,4 +150,30 @@ int db_delete_ucontact(ucontact_t* _c);
  */
  */
 int update_ucontact(struct urecord* _r, ucontact_t* _c, ucontact_info_t* _ci);
 int update_ucontact(struct urecord* _r, ucontact_t* _c, ucontact_info_t* _ci);
 
 
+/* ====== per contact attributes ====== */
+
+/*!
+ * \brief Load all location attributes from a udomain
+ *
+ * Load all location attributes from a udomain, useful to populate the
+ * memory cache on startup.
+ * \param _dname loaded domain name
+ * \param _user sip username
+ * \param _domain sip domain
+ * \param _ruid usrloc record unique id
+ * \return 0 on success, -1 on failure
+ */
+int uldb_delete_attrs(str* _dname, str *_user, str *_domain, str *_ruid);
+
+/*!
+ * \brief Insert contact attributes into the database
+ * \param _dname loaded domain name
+ * \param _user sip username
+ * \param _domain sip domain
+ * \param _ruid record unique id
+ * \param _xhead head of xavp list
+ * \return 0 on success, -1 on failure
+ */
+int uldb_insert_attrs(str *_dname, str *_user, str *_domain,
+        str *_ruid, sr_xavp_t *_xhead);
 #endif
 #endif

+ 182 - 0
modules_k/usrloc/udomain.c

@@ -1123,3 +1123,185 @@ int delete_urecord(udomain_t* _d, str* _aor, struct urecord* _r)
 	release_urecord(_r);
 	release_urecord(_r);
 	return 0;
 	return 0;
 }
 }
+
+
+/*!
+ * \brief Load all location attributes from an udomain
+ *
+ * Load all location attributes from a udomain, useful to populate the
+ * memory cache on startup.
+ * \param _d loaded domain
+ * \return 0 on success, -1 on failure
+ */
+int uldb_preload_attrs(udomain_t *_d)
+{
+	char uri[MAX_URI_SIZE];
+	str  suri;
+	char tname_buf[64];
+	str tname;
+	db_row_t *row;
+	db_key_t columns[6];
+	db1_res_t* res = NULL;
+	str user = {0};
+	str domain = {0};
+	str ruid;
+	str aname;
+	str avalue;
+	sr_xval_t aval;
+	int i;
+	int n;
+
+	urecord_t* r;
+	ucontact_t* c;
+
+	if(ul_xavp_contact_name.s==NULL) {
+		/* feature disabled by mod param */
+		return 0;
+	}
+
+	if(_d->name->len + 6>=64) {
+		LM_ERR("attributes table name is too big\n");
+		return -1;
+	}
+	strncpy(tname_buf, _d->name->s, _d->name->len);
+	tname_buf[_d->name->len] = '\0';
+	strcat(tname_buf, "_attrs");
+	tname.s = tname_buf;
+	tname.len = _d->name->len + 6;
+
+	columns[0] = &ulattrs_user_col;
+	columns[1] = &ulattrs_ruid_col;
+	columns[2] = &ulattrs_aname_col;
+	columns[3] = &ulattrs_atype_col;
+	columns[4] = &ulattrs_avalue_col;
+	columns[5] = &ulattrs_domain_col;
+
+	if (ul_dbf.use_table(ul_dbh, &tname) < 0) {
+		LM_ERR("sql use_table failed for %.*s\n", tname.len, tname.s);
+		return -1;
+	}
+
+#ifdef EXTRA_DEBUG
+	LM_NOTICE("load start time [%d]\n", (int)time(NULL));
+#endif
+
+	if (DB_CAPABILITY(ul_dbf, DB_CAP_FETCH)) {
+		if (ul_dbf.query(ul_dbh, 0, 0, 0, columns, 0, (use_domain)?(6):(5), 0,
+					0) < 0) {
+			LM_ERR("db_query (1) failed\n");
+			return -1;
+		}
+		if(ul_dbf.fetch_result(ul_dbh, &res, ul_fetch_rows)<0) {
+			LM_ERR("fetching rows failed\n");
+			return -1;
+		}
+	} else {
+		if (ul_dbf.query(ul_dbh, 0, 0, 0, columns, 0, (use_domain)?(6):(5), 0,
+		&res) < 0) {
+			LM_ERR("db_query failed\n");
+			return -1;
+		}
+	}
+
+	if (RES_ROW_N(res) == 0) {
+		LM_DBG("location attrs table is empty\n");
+		ul_dbf.free_result(ul_dbh, res);
+		return 0;
+	}
+
+
+	n = 0;
+	do {
+		LM_DBG("loading records - cycle [%d]\n", ++n);
+		for(i = 0; i < RES_ROW_N(res); i++) {
+			row = RES_ROWS(res) + i;
+
+			user.s = (char*)VAL_STRING(ROW_VALUES(row));
+			if (VAL_NULL(ROW_VALUES(row)) || user.s==0 || user.s[0]==0) {
+				LM_CRIT("empty username record in table %s...skipping\n",
+						_d->name->s);
+				continue;
+			}
+			user.len = strlen(user.s);
+
+			ruid.s = (char*)VAL_STRING(ROW_VALUES(row) + 1);
+			ruid.len = strlen(ruid.s);
+			aname.s = (char*)VAL_STRING(ROW_VALUES(row) + 2);
+			aname.len = strlen(aname.s);
+			avalue.s = (char*)VAL_STRING(ROW_VALUES(row) + 4);
+			avalue.len = strlen(avalue.s);
+			memset(&aval, 0, sizeof(sr_xval_t));
+			if(VAL_INT(ROW_VALUES(row)+3)==0) {
+				/* string value */
+				aval.v.s = avalue;
+				aval.type = SR_XTYPE_STR;
+			} else if(VAL_INT(ROW_VALUES(row)+3)==1) {
+				/* int value */
+				str2sint(&avalue, &aval.v.i);
+				aval.type = SR_XTYPE_INT;
+			} else {
+				/* unknown type - ignore */
+				continue;
+			}
+
+			if (use_domain) {
+				domain.s = (char*)VAL_STRING(ROW_VALUES(row) + 6);
+				if (VAL_NULL(ROW_VALUES(row)+6) || domain.s==0 || domain.s[0]==0){
+					LM_CRIT("empty domain record for user %.*s...skipping\n",
+							user.len, user.s);
+					continue;
+				}
+				domain.len = strlen(domain.s);
+				/* user.s cannot be NULL - checked previosly */
+				suri.len = snprintf(uri, MAX_URI_SIZE, "%.*s@%s",
+					user.len, user.s, domain.s);
+				suri.s = uri;
+				if (suri.s[suri.len]!=0) {
+					LM_CRIT("URI '%.*s@%s' longer than %d\n", user.len, user.s,
+							domain.s, MAX_URI_SIZE);
+					continue;
+				}
+			} else {
+				suri = user;
+			}
+
+			lock_udomain(_d, &suri);
+			if (get_urecord_by_ruid(_d, ul_get_aorhash(&suri), &ruid, &r, &c) > 0) {
+				/* delete attrs records from db table */
+				LM_INFO("no contact record for this ruid\n");
+				uldb_delete_attrs(_d->name, &user, &domain, &ruid);
+			} else {
+				/* add xavp to contact */
+				if(c->xavp==NULL) {
+					if(xavp_add_xavp_value(&ul_xavp_contact_name, &aname,
+								&aval, &c->xavp)==NULL)
+						LM_INFO("cannot add first xavp to contact - ignoring\n");
+				} else {
+					if(c->xavp->val.type==SR_XTYPE_XAVP) {
+						if(xavp_add_value(&aname, &aval, &c->xavp->val.v.xavp)==NULL)
+							LM_INFO("cannot add values to contact xavp\n");
+					}
+				}
+			}
+			unlock_udomain(_d, &user);
+		}
+
+		if (DB_CAPABILITY(ul_dbf, DB_CAP_FETCH)) {
+			if(ul_dbf.fetch_result(ul_dbh, &res, ul_fetch_rows)<0) {
+				LM_ERR("fetching rows (1) failed\n");
+				ul_dbf.free_result(ul_dbh, res);
+				return -1;
+			}
+		} else {
+			break;
+		}
+	} while(RES_ROW_N(res)>0);
+
+	ul_dbf.free_result(ul_dbh, res);
+
+#ifdef EXTRA_DEBUG
+	LM_NOTICE("load end time [%d]\n", (int)time(NULL));
+#endif
+
+	return 0;
+}

+ 12 - 0
modules_k/usrloc/udomain.h

@@ -213,4 +213,16 @@ int get_urecord_by_ruid(udomain_t* _d, unsigned int _aorhash,
 int delete_urecord(udomain_t* _d, str* _aor, struct urecord* _r);
 int delete_urecord(udomain_t* _d, str* _aor, struct urecord* _r);
 
 
 
 
+/* ===== per-contact attributes ======= */
+
+/*!
+ * \brief Load all location attributes from an udomain
+ *
+ * Load all location attributes from a udomain, useful to populate the
+ * memory cache on startup.
+ * \param _d loaded domain
+ * \return 0 on success, -1 on failure
+ */
+int uldb_preload_attrs(udomain_t *_d);
+
 #endif
 #endif

+ 18 - 0
modules_k/usrloc/ul_mod.c

@@ -91,6 +91,14 @@ MODULE_VERSION
 #define REG_ID_COL     "reg_id"
 #define REG_ID_COL     "reg_id"
 #define LAST_MOD_COL   "last_modified"
 #define LAST_MOD_COL   "last_modified"
 
 
+#define ULATTRS_USER_COL       "username"
+#define ULATTRS_DOMAIN_COL     "domain"
+#define ULATTRS_RUID_COL       "ruid"
+#define ULATTRS_ANAME_COL      "aname"
+#define ULATTRS_ATYPE_COL      "atype"
+#define ULATTRS_AVALUE_COL     "avalue"
+#define ULATTRS_LAST_MOD_COL   "last_modified"
+
 static int mod_init(void);                          /*!< Module initialization function */
 static int mod_init(void);                          /*!< Module initialization function */
 static void destroy(void);                          /*!< Module destroy function */
 static void destroy(void);                          /*!< Module destroy function */
 static void ul_core_timer(unsigned int ticks, void* param);  /*!< Core timer handler */
 static void ul_core_timer(unsigned int ticks, void* param);  /*!< Core timer handler */
@@ -137,6 +145,15 @@ str methods_col     = str_init(METHODS_COL);	/*!< Name of column containing the
 str instance_col    = str_init(INSTANCE_COL);	/*!< Name of column containing the SIP instance value */
 str instance_col    = str_init(INSTANCE_COL);	/*!< Name of column containing the SIP instance value */
 str reg_id_col      = str_init(REG_ID_COL);		/*!< Name of column containing the reg-id value */
 str reg_id_col      = str_init(REG_ID_COL);		/*!< Name of column containing the reg-id value */
 str last_mod_col    = str_init(LAST_MOD_COL);	/*!< Name of column containing the last modified date */
 str last_mod_col    = str_init(LAST_MOD_COL);	/*!< Name of column containing the last modified date */
+
+str ulattrs_user_col   = str_init(ULATTRS_USER_COL);   /*!< Name of column containing username */
+str ulattrs_domain_col = str_init(ULATTRS_DOMAIN_COL); /*!< Name of column containing domain */
+str ulattrs_ruid_col   = str_init(ULATTRS_RUID_COL);   /*!< Name of column containing record unique id */
+str ulattrs_aname_col  = str_init(ULATTRS_ANAME_COL);  /*!< Name of column containing attribute name */
+str ulattrs_atype_col  = str_init(ULATTRS_ATYPE_COL);  /*!< Name of column containing attribute type */
+str ulattrs_avalue_col = str_init(ULATTRS_AVALUE_COL); /*!< Name of column containing attribute value */
+str ulattrs_last_mod_col = str_init(ULATTRS_LAST_MOD_COL);	/*!< Name of column containing the last modified date */
+
 str db_url          = str_init(DEFAULT_DB_URL);	/*!< Database URL */
 str db_url          = str_init(DEFAULT_DB_URL);	/*!< Database URL */
 int timer_interval  = 60;				/*!< Timer interval in seconds */
 int timer_interval  = 60;				/*!< Timer interval in seconds */
 int db_mode         = 0;				/*!< Database sync scheme: 0-no db, 1-write through, 2-write back, 3-only db */
 int db_mode         = 0;				/*!< Database sync scheme: 0-no db, 1-write through, 2-write back, 3-only db */
@@ -423,6 +440,7 @@ static int child_init(int _rank)
 						_rank, ptr->name.len, ZSW(ptr->name.s));
 						_rank, ptr->name.len, ZSW(ptr->name.s));
 				return -1;
 				return -1;
 			}
 			}
+			uldb_preload_attrs(ptr->d);
 		}
 		}
 	}
 	}
 
 

+ 9 - 0
modules_k/usrloc/ul_mod.h

@@ -64,6 +64,15 @@ extern str instance_col;
 extern str reg_id_col;
 extern str reg_id_col;
 extern str last_mod_col;
 extern str last_mod_col;
 
 
+extern str ulattrs_user_col;
+extern str ulattrs_domain_col;
+extern str ulattrs_ruid_col;
+extern str ulattrs_aname_col;
+extern str ulattrs_atype_col;
+extern str ulattrs_avalue_col;
+extern str ulattrs_last_mod_col;
+
+
 extern str db_url;
 extern str db_url;
 extern int timer_interval;
 extern int timer_interval;
 extern int db_mode;
 extern int db_mode;

+ 0 - 0
modules_s/.gitkeep


+ 0 - 0
modules_s/registrar/Makefile → obsolete/registrar/Makefile


+ 0 - 0
modules_s/registrar/README → obsolete/registrar/README


+ 0 - 0
modules_s/registrar/common.c → obsolete/registrar/common.c


+ 0 - 0
modules_s/registrar/common.h → obsolete/registrar/common.h


+ 0 - 0
modules_s/registrar/doc/Makefile → obsolete/registrar/doc/Makefile


+ 0 - 0
modules_s/registrar/doc/functions.xml → obsolete/registrar/doc/functions.xml


+ 0 - 0
modules_s/registrar/doc/params.xml → obsolete/registrar/doc/params.xml


+ 0 - 0
modules_s/registrar/doc/registrar.xml → obsolete/registrar/doc/registrar.xml


+ 0 - 0
modules_s/registrar/lookup.c → obsolete/registrar/lookup.c


+ 0 - 0
modules_s/registrar/lookup.h → obsolete/registrar/lookup.h


+ 0 - 0
modules_s/registrar/reg_mod.c → obsolete/registrar/reg_mod.c


+ 0 - 0
modules_s/registrar/reg_mod.h → obsolete/registrar/reg_mod.h


+ 0 - 0
modules_s/registrar/regtime.c → obsolete/registrar/regtime.c


+ 0 - 0
modules_s/registrar/regtime.h → obsolete/registrar/regtime.h


+ 0 - 0
modules_s/registrar/reply.c → obsolete/registrar/reply.c


+ 0 - 0
modules_s/registrar/reply.h → obsolete/registrar/reply.h


+ 0 - 0
modules_s/registrar/rerrno.c → obsolete/registrar/rerrno.c


+ 0 - 0
modules_s/registrar/rerrno.h → obsolete/registrar/rerrno.h


+ 0 - 0
modules_s/registrar/save.c → obsolete/registrar/save.c


+ 0 - 0
modules_s/registrar/save.h → obsolete/registrar/save.h


+ 0 - 0
modules_s/registrar/sip_msg.c → obsolete/registrar/sip_msg.c


+ 0 - 0
modules_s/registrar/sip_msg.h → obsolete/registrar/sip_msg.h


+ 0 - 0
modules_s/usrloc/Makefile → obsolete/usrloc/Makefile


+ 0 - 0
modules_s/usrloc/README → obsolete/usrloc/README


+ 0 - 0
modules_s/usrloc/dlist.c → obsolete/usrloc/dlist.c


+ 0 - 0
modules_s/usrloc/dlist.h → obsolete/usrloc/dlist.h


+ 0 - 0
modules_s/usrloc/doc/Makefile → obsolete/usrloc/doc/Makefile


+ 0 - 0
modules_s/usrloc/doc/api.xml → obsolete/usrloc/doc/api.xml


+ 0 - 0
modules_s/usrloc/doc/functions.xml → obsolete/usrloc/doc/functions.xml


+ 0 - 0
modules_s/usrloc/doc/params.xml → obsolete/usrloc/doc/params.xml


+ 0 - 0
modules_s/usrloc/doc/usrloc.xml → obsolete/usrloc/doc/usrloc.xml


+ 0 - 0
modules_s/usrloc/doc/usrloc_states_w_zombie.png → obsolete/usrloc/doc/usrloc_states_w_zombie.png


+ 0 - 0
modules_s/usrloc/doc/usrloc_states_w_zombie.vsd → obsolete/usrloc/doc/usrloc_states_w_zombie.vsd


+ 0 - 0
modules_s/usrloc/hslot.c → obsolete/usrloc/hslot.c


+ 0 - 0
modules_s/usrloc/hslot.h → obsolete/usrloc/hslot.h


+ 0 - 0
modules_s/usrloc/notify.c → obsolete/usrloc/notify.c


+ 0 - 0
modules_s/usrloc/notify.h → obsolete/usrloc/notify.h


+ 0 - 0
modules_s/usrloc/reg_avps.c → obsolete/usrloc/reg_avps.c


+ 0 - 0
modules_s/usrloc/reg_avps.h → obsolete/usrloc/reg_avps.h


+ 0 - 0
modules_s/usrloc/reg_avps_db.c → obsolete/usrloc/reg_avps_db.c


+ 0 - 0
modules_s/usrloc/reg_avps_db.h → obsolete/usrloc/reg_avps_db.h


+ 0 - 0
modules_s/usrloc/ucontact.c → obsolete/usrloc/ucontact.c


+ 0 - 0
modules_s/usrloc/ucontact.h → obsolete/usrloc/ucontact.h


+ 0 - 0
modules_s/usrloc/udomain.c → obsolete/usrloc/udomain.c


+ 0 - 0
modules_s/usrloc/udomain.h → obsolete/usrloc/udomain.h


+ 0 - 0
modules_s/usrloc/ul_callback.c → obsolete/usrloc/ul_callback.c


+ 0 - 0
modules_s/usrloc/ul_callback.h → obsolete/usrloc/ul_callback.h


+ 0 - 0
modules_s/usrloc/ul_mod.c → obsolete/usrloc/ul_mod.c


+ 0 - 0
modules_s/usrloc/ul_mod.h → obsolete/usrloc/ul_mod.h


+ 0 - 0
modules_s/usrloc/ul_rpc.c → obsolete/usrloc/ul_rpc.c


+ 0 - 0
modules_s/usrloc/ul_rpc.h → obsolete/usrloc/ul_rpc.h


+ 0 - 0
modules_s/usrloc/urecord.c → obsolete/usrloc/urecord.c


+ 0 - 0
modules_s/usrloc/urecord.h → obsolete/usrloc/urecord.h


+ 0 - 0
modules_s/usrloc/usrloc.c → obsolete/usrloc/usrloc.c


+ 0 - 0
modules_s/usrloc/usrloc.h → obsolete/usrloc/usrloc.h


+ 0 - 0
modules_s/usrloc/utime.c → obsolete/usrloc/utime.c


+ 0 - 0
modules_s/usrloc/utime.h → obsolete/usrloc/utime.h


+ 12 - 0
utils/kamctl/db_berkeley/kamailio/location_attrs

@@ -0,0 +1,12 @@
+METADATA_COLUMNS
+id(int) ruid(str) username(str) domain(str) aname(str) atype(int) avalue(str) last_modified(datetime)
+METADATA_KEY
+1 2 3 
+METADATA_READONLY
+0
+METADATA_LOGFLAGS
+0
+METADATA_DEFAULTS
+NIL|''|''|NULL|''|0|''|'1900-01-01 00:00:01'
+location_attrs|
+location_attrs|1

+ 2 - 2
utils/kamctl/db_sqlite/sca-create.sql

@@ -1,4 +1,4 @@
-INSERT INTO version (table_name, table_version) values ('sca_subscriptions','1');
+INSERT INTO version (table_name, table_version) values ('sca_subscriptions','0');
 CREATE TABLE sca_subscriptions (
 CREATE TABLE sca_subscriptions (
     id INTEGER PRIMARY KEY NOT NULL,
     id INTEGER PRIMARY KEY NOT NULL,
     subscriber VARCHAR(255) NOT NULL,
     subscriber VARCHAR(255) NOT NULL,
@@ -10,7 +10,7 @@ CREATE TABLE sca_subscriptions (
     call_id VARCHAR(255) NOT NULL,
     call_id VARCHAR(255) NOT NULL,
     from_tag VARCHAR(64) NOT NULL,
     from_tag VARCHAR(64) NOT NULL,
     to_tag VARCHAR(64) NOT NULL,
     to_tag VARCHAR(64) NOT NULL,
-    record_route TEXT DEFAULT NULL,
+    record_route TEXT,
     notify_cseq INTEGER NOT NULL,
     notify_cseq INTEGER NOT NULL,
     subscribe_cseq INTEGER NOT NULL,
     subscribe_cseq INTEGER NOT NULL,
     CONSTRAINT sca_subscriptions_sca_subscriptions_idx UNIQUE (subscriber, call_id, from_tag, to_tag)
     CONSTRAINT sca_subscriptions_sca_subscriptions_idx UNIQUE (subscriber, call_id, from_tag, to_tag)

+ 15 - 0
utils/kamctl/db_sqlite/usrloc-create.sql

@@ -25,3 +25,18 @@ CREATE TABLE location (
 CREATE INDEX location_account_contact_idx ON location (username, domain, contact);
 CREATE INDEX location_account_contact_idx ON location (username, domain, contact);
 CREATE INDEX location_expires_idx ON location (expires);
 CREATE INDEX location_expires_idx ON location (expires);
 
 
+INSERT INTO version (table_name, table_version) values ('location_attrs','1');
+CREATE TABLE location_attrs (
+    id INTEGER PRIMARY KEY NOT NULL,
+    ruid VARCHAR(64) DEFAULT '' NOT NULL,
+    username VARCHAR(64) DEFAULT '' NOT NULL,
+    domain VARCHAR(64) DEFAULT NULL,
+    aname VARCHAR(64) DEFAULT '' NOT NULL,
+    atype INTEGER DEFAULT 0 NOT NULL,
+    avalue VARCHAR(255) DEFAULT '' NOT NULL,
+    last_modified TIMESTAMP WITHOUT TIME ZONE DEFAULT '1900-01-01 00:00:01' NOT NULL
+);
+
+CREATE INDEX location_attrs_account_record_idx ON location_attrs (username, domain, ruid);
+CREATE INDEX location_attrs_last_modified_idx ON location_attrs (last_modified);
+

+ 2 - 0
utils/kamctl/dbtext/kamailio/location_attrs

@@ -0,0 +1,2 @@
+id(int,auto) ruid(string) username(string) domain(string,null) aname(string) atype(int) avalue(string) last_modified(int) 
+location_attrs:1

+ 2 - 2
utils/kamctl/mysql/sca-create.sql

@@ -1,4 +1,4 @@
-INSERT INTO version (table_name, table_version) values ('sca_subscriptions','1');
+INSERT INTO version (table_name, table_version) values ('sca_subscriptions','0');
 CREATE TABLE sca_subscriptions (
 CREATE TABLE sca_subscriptions (
     id INT(10) UNSIGNED AUTO_INCREMENT PRIMARY KEY NOT NULL,
     id INT(10) UNSIGNED AUTO_INCREMENT PRIMARY KEY NOT NULL,
     subscriber VARCHAR(255) NOT NULL,
     subscriber VARCHAR(255) NOT NULL,
@@ -10,7 +10,7 @@ CREATE TABLE sca_subscriptions (
     call_id VARCHAR(255) NOT NULL,
     call_id VARCHAR(255) NOT NULL,
     from_tag VARCHAR(64) NOT NULL,
     from_tag VARCHAR(64) NOT NULL,
     to_tag VARCHAR(64) NOT NULL,
     to_tag VARCHAR(64) NOT NULL,
-    record_route TEXT DEFAULT NULL,
+    record_route TEXT,
     notify_cseq INT(11) NOT NULL,
     notify_cseq INT(11) NOT NULL,
     subscribe_cseq INT(11) NOT NULL,
     subscribe_cseq INT(11) NOT NULL,
     CONSTRAINT sca_subscriptions_idx UNIQUE (subscriber, call_id, from_tag, to_tag)
     CONSTRAINT sca_subscriptions_idx UNIQUE (subscriber, call_id, from_tag, to_tag)

+ 15 - 0
utils/kamctl/mysql/usrloc-create.sql

@@ -25,3 +25,18 @@ CREATE TABLE location (
 CREATE INDEX account_contact_idx ON location (username, domain, contact);
 CREATE INDEX account_contact_idx ON location (username, domain, contact);
 CREATE INDEX expires_idx ON location (expires);
 CREATE INDEX expires_idx ON location (expires);
 
 
+INSERT INTO version (table_name, table_version) values ('location_attrs','1');
+CREATE TABLE location_attrs (
+    id INT(10) UNSIGNED AUTO_INCREMENT PRIMARY KEY NOT NULL,
+    ruid VARCHAR(64) DEFAULT '' NOT NULL,
+    username VARCHAR(64) DEFAULT '' NOT NULL,
+    domain VARCHAR(64) DEFAULT NULL,
+    aname VARCHAR(64) DEFAULT '' NOT NULL,
+    atype INT(11) DEFAULT 0 NOT NULL,
+    avalue VARCHAR(255) DEFAULT '' NOT NULL,
+    last_modified DATETIME DEFAULT '1900-01-01 00:00:01' NOT NULL
+) ENGINE=MyISAM;
+
+CREATE INDEX account_record_idx ON location_attrs (username, domain, ruid);
+CREATE INDEX last_modified_idx ON location_attrs (last_modified);
+

+ 1 - 1
utils/kamctl/oracle/sca-create.sql

@@ -1,4 +1,4 @@
-INSERT INTO version (table_name, table_version) values ('sca_subscriptions','1');
+INSERT INTO version (table_name, table_version) values ('sca_subscriptions','0');
 CREATE TABLE sca_subscriptions (
 CREATE TABLE sca_subscriptions (
     id NUMBER(10) PRIMARY KEY,
     id NUMBER(10) PRIMARY KEY,
     subscriber VARCHAR2(255),
     subscriber VARCHAR2(255),

+ 23 - 0
utils/kamctl/oracle/usrloc-create.sql

@@ -33,3 +33,26 @@ BEGIN map2users('location'); END;
 CREATE INDEX location_account_contact_idx  ON location (username, domain, contact);
 CREATE INDEX location_account_contact_idx  ON location (username, domain, contact);
 CREATE INDEX location_expires_idx  ON location (expires);
 CREATE INDEX location_expires_idx  ON location (expires);
 
 
+INSERT INTO version (table_name, table_version) values ('location_attrs','1');
+CREATE TABLE location_attrs (
+    id NUMBER(10) PRIMARY KEY,
+    ruid VARCHAR2(64) DEFAULT '',
+    username VARCHAR2(64) DEFAULT '',
+    domain VARCHAR2(64) DEFAULT NULL,
+    aname VARCHAR2(64) DEFAULT '',
+    atype NUMBER(10) DEFAULT 0 NOT NULL,
+    avalue VARCHAR2(255) DEFAULT '',
+    last_modified DATE DEFAULT to_date('1900-01-01 00:00:01','yyyy-mm-dd hh24:mi:ss')
+);
+
+CREATE OR REPLACE TRIGGER location_attrs_tr
+before insert on location_attrs FOR EACH ROW
+BEGIN
+  auto_id(:NEW.id);
+END location_attrs_tr;
+/
+BEGIN map2users('location_attrs'); END;
+/
+CREATE INDEX ORA_account_record_idx  ON location_attrs (username, domain, ruid);
+CREATE INDEX ORA_last_modified_idx  ON location_attrs (last_modified);
+

+ 2 - 2
utils/kamctl/postgres/sca-create.sql

@@ -1,4 +1,4 @@
-INSERT INTO version (table_name, table_version) values ('sca_subscriptions','1');
+INSERT INTO version (table_name, table_version) values ('sca_subscriptions','0');
 CREATE TABLE sca_subscriptions (
 CREATE TABLE sca_subscriptions (
     id SERIAL PRIMARY KEY NOT NULL,
     id SERIAL PRIMARY KEY NOT NULL,
     subscriber VARCHAR(255) NOT NULL,
     subscriber VARCHAR(255) NOT NULL,
@@ -10,7 +10,7 @@ CREATE TABLE sca_subscriptions (
     call_id VARCHAR(255) NOT NULL,
     call_id VARCHAR(255) NOT NULL,
     from_tag VARCHAR(64) NOT NULL,
     from_tag VARCHAR(64) NOT NULL,
     to_tag VARCHAR(64) NOT NULL,
     to_tag VARCHAR(64) NOT NULL,
-    record_route TEXT DEFAULT NULL,
+    record_route TEXT,
     notify_cseq INTEGER NOT NULL,
     notify_cseq INTEGER NOT NULL,
     subscribe_cseq INTEGER NOT NULL,
     subscribe_cseq INTEGER NOT NULL,
     CONSTRAINT sca_subscriptions_sca_subscriptions_idx UNIQUE (subscriber, call_id, from_tag, to_tag)
     CONSTRAINT sca_subscriptions_sca_subscriptions_idx UNIQUE (subscriber, call_id, from_tag, to_tag)

+ 15 - 0
utils/kamctl/postgres/usrloc-create.sql

@@ -25,3 +25,18 @@ CREATE TABLE location (
 CREATE INDEX location_account_contact_idx ON location (username, domain, contact);
 CREATE INDEX location_account_contact_idx ON location (username, domain, contact);
 CREATE INDEX location_expires_idx ON location (expires);
 CREATE INDEX location_expires_idx ON location (expires);
 
 
+INSERT INTO version (table_name, table_version) values ('location_attrs','1');
+CREATE TABLE location_attrs (
+    id SERIAL PRIMARY KEY NOT NULL,
+    ruid VARCHAR(64) DEFAULT '' NOT NULL,
+    username VARCHAR(64) DEFAULT '' NOT NULL,
+    domain VARCHAR(64) DEFAULT NULL,
+    aname VARCHAR(64) DEFAULT '' NOT NULL,
+    atype INTEGER DEFAULT 0 NOT NULL,
+    avalue VARCHAR(255) DEFAULT '' NOT NULL,
+    last_modified TIMESTAMP WITHOUT TIME ZONE DEFAULT '1900-01-01 00:00:01' NOT NULL
+);
+
+CREATE INDEX location_attrs_account_record_idx ON location_attrs (username, domain, ruid);
+CREATE INDEX location_attrs_last_modified_idx ON location_attrs (last_modified);
+

+ 41 - 11
utils/kamctl/xhttp_pi/pi_framework.xml

@@ -212,17 +212,6 @@
 		<column><field>attrs</field><type>DB1_STR</type></column>
 		<column><field>attrs</field><type>DB1_STR</type></column>
 		<column><field>description</field><type>DB1_STR</type></column>
 		<column><field>description</field><type>DB1_STR</type></column>
 	</db_table>
 	</db_table>
-	<!-- Declaration of domainpolicy table-->
-	<db_table id="domainpolicy">
-		<table_name>domainpolicy</table_name>
-		<db_url_id>mysql</db_url_id>
-		<column><field>id</field><type>DB1_INT</type></column>
-		<column><field>rule</field><type>DB1_STR</type></column>
-		<column><field>type</field><type>DB1_STR</type></column>
-		<column><field>att</field><type>DB1_STR</type></column>
-		<column><field>val</field><type>DB1_STR</type></column>
-		<column><field>description</field><type>DB1_STR</type></column>
-	</db_table>
 	<!-- Declaration of domain table-->
 	<!-- Declaration of domain table-->
 	<db_table id="domain">
 	<db_table id="domain">
 		<table_name>domain</table_name>
 		<table_name>domain</table_name>
@@ -243,6 +232,17 @@
 		<column><field>value</field><type>DB1_STR</type></column>
 		<column><field>value</field><type>DB1_STR</type></column>
 		<column><field>last_modified</field><type>DB1_DATETIME</type></column>
 		<column><field>last_modified</field><type>DB1_DATETIME</type></column>
 	</db_table>
 	</db_table>
+	<!-- Declaration of domainpolicy table-->
+	<db_table id="domainpolicy">
+		<table_name>domainpolicy</table_name>
+		<db_url_id>mysql</db_url_id>
+		<column><field>id</field><type>DB1_INT</type></column>
+		<column><field>rule</field><type>DB1_STR</type></column>
+		<column><field>type</field><type>DB1_STR</type></column>
+		<column><field>att</field><type>DB1_STR</type></column>
+		<column><field>val</field><type>DB1_STR</type></column>
+		<column><field>description</field><type>DB1_STR</type></column>
+	</db_table>
 	<!-- Declaration of dr_gateways table-->
 	<!-- Declaration of dr_gateways table-->
 	<db_table id="dr_gateways">
 	<db_table id="dr_gateways">
 		<table_name>dr_gateways</table_name>
 		<table_name>dr_gateways</table_name>
@@ -755,6 +755,19 @@
 		<column><field>instance</field><type>DB1_STR</type></column>
 		<column><field>instance</field><type>DB1_STR</type></column>
 		<column><field>reg_id</field><type>DB1_INT</type></column>
 		<column><field>reg_id</field><type>DB1_INT</type></column>
 	</db_table>
 	</db_table>
+	<!-- Declaration of location_attrs table-->
+	<db_table id="location_attrs">
+		<table_name>location_attrs</table_name>
+		<db_url_id>mysql</db_url_id>
+		<column><field>id</field><type>DB1_INT</type></column>
+		<column><field>ruid</field><type>DB1_STR</type></column>
+		<column><field>username</field><type>DB1_STR</type></column>
+		<column><field>domain</field><type>DB1_STR</type></column>
+		<column><field>aname</field><type>DB1_STR</type></column>
+		<column><field>atype</field><type>DB1_INT</type></column>
+		<column><field>avalue</field><type>DB1_STR</type></column>
+		<column><field>last_modified</field><type>DB1_DATETIME</type></column>
+	</db_table>
 	<!-- Declare all mods
 	<!-- Declare all mods
 		Each mod must have:
 		Each mod must have:
 		- a 'mod_name'
 		- a 'mod_name'
@@ -1739,4 +1752,21 @@
 			</query_cols>
 			</query_cols>
 		</cmd>
 		</cmd>
 	</mod>
 	</mod>
+	<!-- location_attrs provisionning -->
+	<mod><mod_name>location_attrs</mod_name>
+		<cmd><cmd_name>show</cmd_name>
+			<db_table_id>location_attrs</db_table_id>
+			<cmd_type>DB1_QUERY</cmd_type>
+			<query_cols>
+				<col><field>id</field></col>
+				<col><field>ruid</field></col>
+				<col><field>username</field></col>
+				<col><field>domain</field></col>
+				<col><field>aname</field></col>
+				<col><field>atype</field></col>
+				<col><field>avalue</field></col>
+				<col><field>last_modified</field></col>
+			</query_cols>
+		</cmd>
+	</mod>
 </framework>
 </framework>

+ 17 - 0
utils/kamctl/xhttp_pi/usrloc-mod

@@ -26,3 +26,20 @@
 			</query_cols>
 			</query_cols>
 		</cmd>
 		</cmd>
 	</mod>
 	</mod>
+	<!-- location_attrs provisionning -->
+	<mod><mod_name>location_attrs</mod_name>
+		<cmd><cmd_name>show</cmd_name>
+			<db_table_id>location_attrs</db_table_id>
+			<cmd_type>DB1_QUERY</cmd_type>
+			<query_cols>
+				<col><field>id</field></col>
+				<col><field>ruid</field></col>
+				<col><field>username</field></col>
+				<col><field>domain</field></col>
+				<col><field>aname</field></col>
+				<col><field>atype</field></col>
+				<col><field>avalue</field></col>
+				<col><field>last_modified</field></col>
+			</query_cols>
+		</cmd>
+	</mod>

+ 13 - 0
utils/kamctl/xhttp_pi/usrloc-table

@@ -22,3 +22,16 @@
 		<column><field>instance</field><type>DB1_STR</type></column>
 		<column><field>instance</field><type>DB1_STR</type></column>
 		<column><field>reg_id</field><type>DB1_INT</type></column>
 		<column><field>reg_id</field><type>DB1_INT</type></column>
 	</db_table>
 	</db_table>
+	<!-- Declaration of location_attrs table-->
+	<db_table id="location_attrs">
+		<table_name>location_attrs</table_name>
+		<db_url_id>mysql</db_url_id>
+		<column><field>id</field><type>DB1_INT</type></column>
+		<column><field>ruid</field><type>DB1_STR</type></column>
+		<column><field>username</field><type>DB1_STR</type></column>
+		<column><field>domain</field><type>DB1_STR</type></column>
+		<column><field>aname</field><type>DB1_STR</type></column>
+		<column><field>atype</field><type>DB1_INT</type></column>
+		<column><field>avalue</field><type>DB1_STR</type></column>
+		<column><field>last_modified</field><type>DB1_DATETIME</type></column>
+	</db_table>

+ 38 - 1
xavp.c

@@ -183,6 +183,38 @@ sr_xavp_t *xavp_add_value(str *name, sr_xval_t *val, sr_xavp_t **list)
 	return avp;
 	return avp;
 }
 }
 
 
+sr_xavp_t *xavp_add_xavp_value(str *rname, str *name, sr_xval_t *val, sr_xavp_t **list)
+{
+	sr_xavp_t *ravp=0;
+	sr_xavp_t *cavp=0;
+	sr_xval_t rval;
+
+	cavp = xavp_new_value(name, val);
+	if (cavp==NULL)
+		return NULL;
+
+	memset(&rval, 0, sizeof(sr_xval_t));
+	rval.type = SR_XTYPE_XAVP;
+	rval.v.xavp = cavp;
+
+	ravp = xavp_new_value(rname, &rval);
+	if (ravp==NULL) {
+		xavp_destroy_list(&cavp);
+		return NULL;
+	}
+
+	/* Prepend new value to the list */
+	if(list) {
+		ravp->next = *list;
+		*list = ravp;
+	} else {
+		ravp->next = *_xavp_list_crt;
+		*_xavp_list_crt = ravp;
+	}
+
+	return ravp;
+}
+
 sr_xavp_t *xavp_set_value(str *name, int idx, sr_xval_t *val, sr_xavp_t **list)
 sr_xavp_t *xavp_set_value(str *name, int idx, sr_xval_t *val, sr_xavp_t **list)
 {
 {
 	sr_xavp_t *avp;
 	sr_xavp_t *avp;
@@ -517,7 +549,9 @@ sr_xavp_t *xavp_clone_level_nodata(sr_xavp_t *xold)
 	sr_xavp_t *pavp = NULL;
 	sr_xavp_t *pavp = NULL;
 
 
 	if(xold == NULL)
 	if(xold == NULL)
+	{
 		return NULL;
 		return NULL;
+	}
 	if(xold->val.type==SR_XTYPE_DATA)
 	if(xold->val.type==SR_XTYPE_DATA)
 	{
 	{
 		LM_INFO("xavp value type is 'data' - ignoring in clone\n");
 		LM_INFO("xavp value type is 'data' - ignoring in clone\n");
@@ -531,18 +565,21 @@ sr_xavp_t *xavp_clone_level_nodata(sr_xavp_t *xold)
 	}
 	}
 
 
 	if(xold->val.type!=SR_XTYPE_XAVP)
 	if(xold->val.type!=SR_XTYPE_XAVP)
+	{
 		return xnew;
 		return xnew;
+	}
 
 
 	xnew->val.v.xavp = NULL;
 	xnew->val.v.xavp = NULL;
 	oavp = xold->val.v.xavp;
 	oavp = xold->val.v.xavp;
 
 
 	while(oavp)
 	while(oavp)
 	{
 	{
-		if(xold->val.type!=SR_XTYPE_DATA && xold->val.type!=SR_XTYPE_XAVP)
+		if(oavp->val.type!=SR_XTYPE_DATA && oavp->val.type!=SR_XTYPE_XAVP)
 		{
 		{
 			navp =  xavp_new_value(&oavp->name, &oavp->val);
 			navp =  xavp_new_value(&oavp->name, &oavp->val);
 			if(navp==NULL)
 			if(navp==NULL)
 			{
 			{
+				LM_ERR("cannot create cloned embedded xavp\n");
 				if(xnew->val.v.xavp == NULL)
 				if(xnew->val.v.xavp == NULL)
 				{
 				{
 					shm_free(xnew);
 					shm_free(xnew);

+ 1 - 0
xavp.h

@@ -81,6 +81,7 @@ void avpx_free(sr_xavp_t *xa);
 int xavp_add(sr_xavp_t *xavp, sr_xavp_t **list);
 int xavp_add(sr_xavp_t *xavp, sr_xavp_t **list);
 int xavp_add_last(sr_xavp_t *xavp, sr_xavp_t **list);
 int xavp_add_last(sr_xavp_t *xavp, sr_xavp_t **list);
 sr_xavp_t *xavp_add_value(str *name, sr_xval_t *val, sr_xavp_t **list);
 sr_xavp_t *xavp_add_value(str *name, sr_xval_t *val, sr_xavp_t **list);
+sr_xavp_t *xavp_add_xavp_value(str *rname, str *name, sr_xval_t *val, sr_xavp_t **list);
 sr_xavp_t *xavp_set_value(str *name, int idx, sr_xval_t *val, sr_xavp_t **list);
 sr_xavp_t *xavp_set_value(str *name, int idx, sr_xval_t *val, sr_xavp_t **list);
 sr_xavp_t *xavp_get(str *name, sr_xavp_t *start);
 sr_xavp_t *xavp_get(str *name, sr_xavp_t *start);
 sr_xavp_t *xavp_get_by_index(str *name, int idx, sr_xavp_t **start);
 sr_xavp_t *xavp_get_by_index(str *name, int idx, sr_xavp_t **start);