1 /*
2  * $Id$
3  *
4  * Copyright (C) 2012 Smile Communications, jason.penton@smilecoms.com
5  * Copyright (C) 2012 Smile Communications, richard.good@smilecoms.com
6  *
7  * The initial version of this code was written by Dragos Vingarzan
8  * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
9  * Fruanhofer Institute. It was and still is maintained in a separate
10  * branch of the original SER. We are therefore migrating it to
11  * Kamailio/SR and look forward to maintaining it from here on out.
12  * 2011/2012 Smile Communications, Pty. Ltd.
13  * ported/maintained/improved by
14  * Jason Penton (jason(dot)penton(at)smilecoms.com and
15  * Richard Good (richard(dot)good(at)smilecoms.com) as part of an
16  * effort to add full IMS support to Kamailio/SR using a new and
17  * improved architecture
18  *
19  * NB: Alot of this code was originally part of OpenIMSCore,
20  * FhG Fokus.
21  * Copyright (C) 2004-2006 FhG Fokus
22  * Thanks for great work! This is an effort to
23  * break apart the various CSCF functions into logically separate
24  * components. We hope this will drive wider use. We also feel
25  * that in this way the architecture is more complete and thereby easier
26  * to manage in the Kamailio/SR environment
27  *
28  * This file is part of Kamailio, a free SIP server.
29  *
30  * Kamailio is free software; you can redistribute it and/or modify
31  * it under the terms of the GNU General Public License as published by
32  * the Free Software Foundation; either version 2 of the License, or
33  * (at your option) any later version
34  *
35  * Kamailio is distributed in the hope that it will be useful,
36  * but WITHOUT ANY WARRANTY; without even the implied warranty of
37  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
38  * GNU General Public License for more details.
39  *
40  * You should have received a copy of the GNU General Public License
41  * along with this program; if not, write to the Free Software
42  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
43  *
44  */
45 
46 #ifndef USRLOC_H
47 #define USRLOC_H
48 
49 #include <time.h>
50 #include "ul_callback.h"
51 #include "../../core/qvalue.h"
52 #include "../../core/str.h"
53 #include "../../modules/tm/dlg.h"
54 #include "../cdp/diameter_ims_code_avp.h"
55 
56 #define DEFAULT_DBG_FILE "/var/log/usrloc_debug"
57 #define MAX_CONTACTS_PER_IMPU 100
58 
59 /* DB modes */
60 #define NO_DB         0
61 #define WRITE_THROUGH 1
62 #define WRITE_BACK    2		//not implemented yet
63 #define DB_ONLY	      3		//not implemented yet
64 
65 /*IMPU states*/
66 #define IMS_USER_NOT_REGISTERED 0		/** User not registered */
67 #define IMS_USER_REGISTERED 1			/** User registered */
68 #define IMS_USER_UNREGISTERED -1		/** User unregistered (not registered but with services for unregistered state) */
69 
70 /** Conjunctive Normal Format */
71 #define IFC_CNF 1
72 /** Disjunctive Normal Format */
73 #define IFC_DNF 0
74 
75 #define IFC_UNKNOWN -1				/** unknown SPT type */
76 #define IFC_REQUEST_URI 1			/** SPT for checking the Request-URI */
77 #define IFC_METHOD 2				/** SPT for checking the Method */
78 #define IFC_SIP_HEADER 3			/** SPT for checking a SIP Header */
79 #define IFC_SESSION_CASE 4			/** SPT for checking the Session Case */
80 #define IFC_SESSION_DESC 5			/** SPT for checking a SDP line */
81 
82 #define IFC_ORIGINATING_SESSION 0	/** Session case originating */
83 #define IFC_TERMINATING_SESSION 1	/** Session case terminating */
84 #define IFC_TERMINATING_UNREGISTERED 2	/** Session case terminating to unregistered user*/
85 
86 #define IFC_INITIAL_REGISTRATION 	1		/** Initial Registration */
87 #define IFC_RE_REGISTRATION 		1<<1	/** Re-Registration */
88 #define IFC_DE_REGISTRATION 		1<<2	/** De-Registration */
89 
90 #define IFC_NO_DEFAULT_HANDLING -1	/** No default handling */
91 #define IFC_SESSION_CONTINUED 0		/** Session should continue on failure to contact AS */
92 #define IFC_SESSION_TERMINATED 1	/** Session should be terminated on failure to contact AS */
93 
94 
95 /*forward declaration necessary for udomain*/
96 struct udomain;
97 typedef struct udomain udomain_t;
98 
99 
100 typedef struct _subscriber_data {
101 	int event;
102 	int expires;
103 	int version;
104 	str* callid;
105 	str* ftag;
106 	str* ttag;
107 	unsigned int local_cseq;
108 	str* record_route;
109 	str* sockinfo_str;
110 	str* presentity_uri;
111 	str *watcher_uri;
112 	str* watcher_contact;
113 } subscriber_data_t;
114 
115 typedef struct _reg_subscriber {
116     int event;
117     time_t expires; /**< Time of expiration		 			*/
118     int version; /**< Last version sent to this subs.	*/
119 
120     str watcher_uri;
121     str watcher_contact;
122     str presentity_uri;
123 
124     unsigned int local_cseq;
125     str call_id;
126     str from_tag;
127     str to_tag;
128     str record_route;
129     str sockinfo_str;
130 
131     struct _reg_subscriber *next; /**< the next subscriber in the list		*/
132     struct _reg_subscriber *prev; /**< the previous subscriber in the list	*/
133 } reg_subscriber;
134 
135 /*!
136  * \brief States for in-memory contacts in regards to contact storage handler (db, in-memory, ldap etc)
137  */
138 typedef enum cstate {
139     CS_NEW, /*!< New contact - not flushed yet */
140     CS_SYNC, /*!< Synchronized contact with the database */
141     CS_DIRTY /*!< Update contact - not flushed yet */
142 } cstate_t;
143 
144 typedef enum contact_state {
145     CONTACT_VALID,
146     CONTACT_DELETE_PENDING,
147     CONTACT_EXPIRE_PENDING_NOTIFY,
148     CONTACT_DELETED,
149     CONTACT_DELAYED_DELETE
150 } contact_state_t;
151 
152 /*! \brief Valid contact is a contact that either didn't expire yet or is permanent */
153 #define VALID_CONTACT(c, t)   (((c->expires>t) || (c->expires==0)) && c->state!=CONTACT_DELETED && c->state!=CONTACT_DELETE_PENDING && c->state!=CONTACT_EXPIRE_PENDING_NOTIFY && c->state!=CONTACT_DELAYED_DELETE)
154 
155 #define VALID_UE_TYPE(c, t)   ((t==0) || (t==1 && c->is_3gpp) || (t==2 && !c->is_3gpp))
156 
157 struct hslot;
158 /*!< Hash table slot */
159 struct socket_info;
160 
161 /** SPT for checking a SIP Header */
162 typedef struct _ims_sip_header {
163     str header; /**< name of the header to match	*/
164     str content; /**< regex to match             	*/
165     short type; /**< if known header, precalculated	*/
166 } ims_sip_header;
167 
168 /** SPT for checking a SDP line */
169 typedef struct _ims_session_desc {
170     str line; /**< name of line from description */
171     str content; /**< regex to match                */
172 } ims_session_desc;
173 
174 /** Service Point Trigger Structure */
175 typedef struct _ims_spt {
176     char condition_negated; /**< if to negate entire condition	*/
177     int group; /**< group to which it belongs		*/
178     char type; /**< type of condition				*/
179 
180     union {
181         str request_uri; /**< Request URI regex				*/
182         str method; /**< the SIP method should be this	*/
183         ims_sip_header sip_header; /**< match of a certain SIP header	*/
184         char session_case; /**< session direction and case		*/
185         ims_session_desc session_desc; /**< session description match 		*/
186     };
187     /**< union for SPT 					*/
188     char registration_type; /**< set of registration types		*/
189 } ims_spt;
190 
191 /** Trigger Point Structure */
192 
193 typedef struct _ims_trigger_point {
194     char condition_type_cnf; /**< if it's CNF or DNF     		*/
195     ims_spt *spt; /**< service point triggers 1..n 		*/
196     unsigned short spt_cnt; /**< number of service point triggers 	*/
197 } ims_trigger_point;
198 
199 /** Application Server Structure */
200 typedef struct _ims_application_server {
201     str server_name; /**< SIP URL of the app server                      */
202     char default_handling; /**< enum SESSION_CONTINUED SESSION_TERMINATED 0..1 */
203     str service_info; /**< optional info to be sent to AS 0..1            */
204     int include_register_request;
205     int include_register_response;
206 } ims_application_server;
207 
208 /** Public Identity Structure */
209 typedef struct {
210     char barring; /**< Barring state									*/
211     str public_identity; /**< Public Identity string							*/
212     str wildcarded_psi; /** if exists is the wildcarded psi					*/
213 } ims_public_identity;
214 
215 /** Initial Filter Criteria Structure */
216 typedef struct _ims_filter_criteria {
217     int priority; /**< checking priority, lower means more important */
218     ims_trigger_point *trigger_point; /**< definition of trigger 0..1 */
219     ims_application_server application_server; /**< target of the trigger   */
220     char *profile_part_indicator; /**< profile part indicator 0..1 */
221 } ims_filter_criteria;
222 
223 /** CoreNetwork Service Authorization */
224 typedef struct _ims_cn_service_auth {
225     int subscribed_media_profile_id; /* must be >=0 */
226 } ims_cn_service_auth;
227 
228 /** Service Profile Structure */
229 typedef struct {
230     ims_public_identity *public_identities; /**< array of public identities		*/
231     unsigned short public_identities_cnt; /**< number of public identities	*/
232     ims_filter_criteria *filter_criteria; /**< vector of filter criteria 0..n */
233     unsigned short filter_criteria_cnt; /**< size of the vector above		*/
234     ims_cn_service_auth *cn_service_auth; /**< core net. services auth. 0..1	*/
235     int *shared_ifc_set; /**< shared ifc set ids 0..n 		*/
236     unsigned short shared_ifc_set_cnt; /**< size of above vector 			*/
237 } ims_service_profile;
238 
239 /** User Subscription Structure */
240 typedef struct ims_subscription_s {
241     str private_identity; /**< private identity 				*/
242     struct hslot_sp* slot; /*!< Collision slot in the hash table array we belong to */
243     int sl;                 /*!< slot number we belong to */
244     int wpsi; /** This is not in the standards
245 	 	 	 	 	 	 	 	 	 	 	 	0 normal user or distinct psi inside
246 	 	 	 	 	 	 	 	 	 	 	 	1 wildcarded psi
247 	 	 	 	 	 	 	 	 	 	 	 **/
248     ims_service_profile *service_profiles; /**< array of service profiles		*/
249     unsigned short service_profiles_cnt; /**< size of the array above		*/
250 
251     int ref_count; /**< referenced count 				*/
252     gen_lock_t *lock; /**< lock for operations on it 		*/
253     struct ims_subscription_s* next;
254     struct ims_subscription_s* prev;
255 } ims_subscription;
256 
257 /** IPSec SA Information */
258 typedef struct ipsec {
259     unsigned int spi_uc; /**< SPI Client to use					*/
260     unsigned int spi_us; /**< SPI Server to use					*/
261     unsigned int spi_pc; /**< SPI Client to use					*/
262     unsigned int spi_ps; /**< SPI Server to use					*/
263     unsigned short port_uc; /**< Port UE Client						*/
264     unsigned short port_us; /**< Port UE Server						*/
265 
266     str ealg; /**< Cypher Algorithm - ESP				*/
267     str r_ealg; /**< received Cypher Algorithm - ESP	*/
268     str ck; /**< Cypher Key							*/
269     str alg; /**< Integrity Algorithm - AH			*/
270     str r_alg; /**<received Integrity Algorithm - AH	*/
271     str ik; /**< Integrity Key						*/
272     str prot; /**< Protocol (ah/esp) */
273     str mod; /**< Mode (transport/tunnel) */
274 } ipsec_t;
275 
276 typedef enum sec_type {
277     SECURITY_NONE = 0,
278     SECURITY_IPSEC = 1,
279 } security_type;
280 
281 typedef struct security {
282     str sec_header; /**< Security Header value 				*/
283     security_type type; /**< Type of security in use			*/
284 
285     union {
286         ipsec_t *ipsec; /**< IPSec SA information, if any		*/
287     } data;
288     float q;
289 } security_t;
290 
291 /*! \brief Structure to hold dialog data used when this contact is part of a confirmed dialog so we can tear down the dialog if the contact is removed */
292 typedef struct contact_dialog_data {
293     unsigned int h_entry;
294     unsigned int h_id;
295 
296     struct contact_dialog_data* next; /*!< Next contact in the linked list */
297     struct contact_dialog_data* prev; /*!< Previous contact in the linked list */
298 } contact_dialog_data_t;
299 
300 
301 typedef struct impu_contact_holder {
302     unsigned int numcontacts;
303     unsigned int num3gppcontacts;
304     struct impu_contact *head;
305     struct impu_contact *tail;
306 } impu_contact_holder_t;
307 
308 typedef struct impu_contact {
309     struct ucontact *contact;
310     struct impu_contact *next;
311     struct impu_contact *prev;
312 } impu_contact_t;
313 
314 /*! \brief Main structure for handling of registered Contact data */
315 typedef struct ucontact {
316     gen_lock_t *lock;           /**< we have to lock the contact as it is shared by many impu structs and has reference conting	*/
317     struct contact_hslot* slot; /*!< Collision slot in the hash table array we belong to */
318     unsigned int sl; 			/*!< Hash slot number we belong to */
319     int ref_count;
320     int is_3gpp;
321     contact_state_t state;
322     str domain; /*!< Pointer to domain name (NULL terminated) */
323     str aor; /*!< Pointer to the AOR string in record structure*/
324     str c; /*!< Contact address */
325     param_t *params; /*!< Params header details> */
326     str received; /*!< IP+port+protocol we received the REGISTER from */
327     str path; /*!< Path header */
328     time_t expires; /*!< Expires parameter */
329     qvalue_t q; /*!< q parameter */
330     str callid; /*!< Call-ID header field of registration */
331     int cseq; /*!< CSeq value */
332 //    cstate_t state; /*!< State of the contact (\ref cstate) */
333     unsigned int flags; /*!< Various flags (NAT, ping type, etc) */
334     unsigned int cflags; /*!< Custom contact flags (from script) */
335     str user_agent; /*!< User-Agent header field */
336     struct socket_info *sock; /*!< received socket */
337     time_t last_modified; /*!< When the record was last modified */
338     unsigned int methods; /*!< Supported methods */
339 
340     struct socket_info *si_ps;
341     struct socket_info *sipc;
342     security_t *security_temp; /**< Security-Client Information		*/
343     security_t *security; /**< Security-Client Information		*/
344 
345     struct ulcb_head_list* cbs;	/**< individual callbacks per contact */
346 
347     struct contact_dialog_data *first_dialog_data;
348     struct contact_dialog_data *last_dialog_data;
349 
350     struct ucontact* next; /*!< Next contact in the linked list */
351     struct ucontact* prev; /*!< Previous contact in the linked list */
352 } ucontact_t;
353 
354 /*! \brief Informations related to a contact (used mainly for passing data around */
355 typedef struct ucontact_info {
356     str received; /*!< Received interface */
357     str* path; /*!< Path informations */
358     time_t expires; /*!< Contact expires */
359     qvalue_t q; /*!< Q-value */
360     str* callid; /*!< call-ID */
361     param_t *params;
362     int cseq; /*!< CSEQ number */
363     unsigned int flags; /*!< message flags */
364     unsigned int cflags; /*!< contact flags */
365     str *user_agent; /*!< user agent header */
366     struct socket_info *sock; /*!< socket informations */
367 
368     unsigned int methods; /*!< supported methods */
369     time_t last_modified; /*!< last modified */
370 } ucontact_info_t;
371 
372 typedef struct udomain_head {
373     str* name;
374 } udomain_head_t;
375 
376 /** Enumeration for public identity Registration States */
377 enum pi_reg_states {
378     IMPU_NOT_REGISTERED = 0, 	/**< User not-registered, no profile stored	*/
379     IMPU_REGISTERED = 1, 		/**< User registered						*/
380     IMPU_UNREGISTERED = -1 		/**< User not-registered, profile stored	*/
381 };
382 
get_impu_regstate_as_string(enum pi_reg_states reg_state)383 static inline char* get_impu_regstate_as_string(enum pi_reg_states reg_state) {
384     switch (reg_state) {
385         case IMPU_NOT_REGISTERED:
386             return "not registered";
387         case IMPU_REGISTERED:
388             return "registered";
389         case IMPU_UNREGISTERED:
390             return "unregistered";
391         default:
392             return "unknown";
393     }
394 }
395 
get_contact_state_as_string(enum contact_state c_state)396 static inline char* get_contact_state_as_string(enum contact_state c_state) {
397     switch(c_state) {
398         case CONTACT_VALID:
399             return "Contact valid";
400         case CONTACT_DELETE_PENDING:
401             return "Contact in delete pending";
402         case CONTACT_EXPIRE_PENDING_NOTIFY:
403             return "Contact expired with pending NOTIFY";
404         case CONTACT_DELETED:
405             return "Contact deleted";
406         case CONTACT_DELAYED_DELETE:
407             return "Contact with delayed delete";
408         default:
409             return "unknown";
410     }
411 }
412 
413 typedef struct _contact_ptr {
414     ucontact_t* contact;
415     struct contact_ptr* prev;
416     struct contact_ptr* next;
417 } contact_ptr;
418 
419 typedef struct _contact_ptr_list {
420     int n;
421     gen_lock_t* lock;
422     struct contact_ptr* first;
423 } contact_ptr_list;
424 
425 /*! \brief
426  * Basic hash table element
427  */
428 typedef struct impurecord {
429     str* domain; 				/*!< Pointer to domain we belong to (null terminated string) */
430     int is_primary;				/*!< first IMPU (in implicit set this is the one that will trigger a SAR, if no implicit set - we should still be safe with first) */
431     str public_identity; 			/*!< Address of record */
432     str private_identity;                       /*!< Subscription to which we be long */
433     unsigned int aorhash; 			/*!< Hash over address of record */
434     int barring;
435     enum pi_reg_states reg_state;
436     ims_subscription *s; 			/**< subscription to which it belongs 		*/
437     str ccf1, ccf2, ecf1, ecf2; 	/**< charging functions						*/
438     impu_contact_holder_t linked_contacts;
439     reg_subscriber *shead, *stail; 	/**< list of subscribers attached			*/
440     time_t expires; 				/*!< timer when this IMPU expires - currently only used for unreg IMPU */
441     int send_sar_on_delete;			/* used to distinguish between explicit contact removal and contact expiry - SAR only sent on contact expiry*/
442 
443     struct hslot* slot; 			/*!< Collision slot in the hash table array we belong to */
444     struct ulcb_head_list* cbs;		/**< individual callbacks per impurecord */
445     struct impurecord* prev; 		/*!< Next item in the hash entry */
446     struct impurecord* next; 		/*!< Previous item in the hash entry */
447 } impurecord_t;
448 
449 /** a parcel for transporting impurecord information */
450 typedef struct impurecord_info {
451     int barring;
452     enum pi_reg_states reg_state;
453     ims_subscription *s;
454     str *ccf1, *ccf2, *ecf1, *ecf2;
455 } impurecord_info_t;
456 
457 typedef struct contact_list {
458     struct contact_hslot* slot;
459     int size;
460     int max_collisions;
461 //    stat_var *contacts;        /*!< no of contacts in table */
462 }contact_list_t;
463 
464 typedef struct ims_subscription_list {
465     struct hslot_sp* slot;
466     int size;               /* size of list (slots) */
467     int subscriptions;      /* total number of subscriptions in storage */
468     int max_collisions;
469 }ims_subscription_list_t;
470 
471 typedef int (*insert_impurecord_t)(struct udomain* _d, str* public_identity, str* private_identity, int reg_state, int barring,
472         ims_subscription** s, str* ccf1, str* ccf2, str* ecf1, str* ecf2,
473         struct impurecord** _r);
474 
475 typedef int (*get_impurecord_t)(struct udomain* _d, str* _aor, struct impurecord** _r);
476 
477 typedef int (*delete_impurecord_t)(struct udomain* _d, str* _aor, struct impurecord* _r);
478 
479 typedef int (*update_impurecord_t)(struct udomain* _d, str* public_identity, impurecord_t* impu_rec, int reg_state, int send_sar_on_delete, int barring, int is_primary, ims_subscription** s, str* ccf1, str* ccf2, str* ecf1, str* ecf2, struct impurecord** _r);
480 
481 typedef void (*lock_contact_slot_t)(str* contact_uri);
482 
483 typedef void (*unlock_contact_slot_t)(str* contact_uri);
484 
485 typedef void (*lock_contact_slot_i_t)(int sl);
486 
487 typedef void (*unlock_contact_slot_i_t)(int sl);
488 
489 typedef void (*lock_subscription_t)(ims_subscription* s);
490 
491 typedef void (*unlock_subscription_t)(ims_subscription* s);
492 typedef void (*unref_subscription_t) (ims_subscription* s);
493 typedef void (*ref_subscription_t) (ims_subscription* s);
494 
495 typedef int (*update_ucontact_t)(struct impurecord* _r, struct ucontact* _c, struct ucontact_info* _ci);
496 
497 typedef int (*expire_ucontact_t)(struct impurecord* _r, struct ucontact* _c);
498 
499 typedef int (*unlink_contact_from_impu_t)(struct impurecord* _r, struct ucontact* _c, int write_to_db, int is_explicit);
500 
501 typedef int (*link_contact_to_impu_t)(struct impurecord* _r, struct ucontact* _c, int wirte_to_db);
502 
503 typedef int (*insert_ucontact_t)(struct impurecord* _r, str* _contact, struct ucontact_info* _ci, struct ucontact** _c);
504 
505 typedef int (*delete_ucontact_t)(struct ucontact* _c);
506 
507 typedef int (*get_ucontact_t)(str* _c, str* _callid, str* _path, int _cseq, struct ucontact** _co);
508 
509 typedef void (*release_ucontact_t)(struct ucontact* _c);
510 
511 typedef int (*add_dialog_data_to_contact_t)(struct ucontact* _c, unsigned int h_entry, unsigned int h_id);
512 
513 typedef int (*remove_dialog_data_from_contact_t)(struct ucontact* _c, unsigned int h_entry, unsigned int h_id);
514 
515 typedef void (*lock_udomain_t)(struct udomain* _d, str *_aor);
516 
517 typedef void (*unlock_udomain_t)(struct udomain* _d, str *_aor);
518 
519 typedef int (*register_udomain_t)(const char* _n, struct udomain** _d);
520 
521 typedef int (*get_all_ucontacts_t)(void* buf, int len, unsigned int flags, unsigned int part_idx, unsigned int part_max);
522 
523 typedef int (*get_udomain_t)(const char* _n, udomain_t** _d);
524 
525 typedef int (*update_subscriber_t)(impurecord_t* urec, reg_subscriber** _reg_subscriber,
526         int *expires, int *local_cseq, int *version);
527 
528 typedef void (*external_delete_subscriber_t)(reg_subscriber *s, udomain_t* _t, int lock_domain);
529 
530 typedef int (*get_subscriber_t)(impurecord_t* urec, str *watcher_contact, str *presentity_uri, int event, reg_subscriber** reg_subscriber);
531 
532 typedef int (*add_subscriber_t)(impurecord_t* urec,
533 		subscriber_data_t* subscriber_data, reg_subscriber** _reg_subscriber, int db_load);
534 
535 typedef int (*get_impus_from_subscription_as_string_t)(udomain_t* _d, impurecord_t* impu_rec, int barring, str** impus, int* num_impus, int is_shm);
536 
537 typedef str (*get_presentity_from_subscriber_dialog_t)(str *callid, str *to_tag, str *from_tag);
538 
539 /*! usrloc API export structure */
540 typedef struct usrloc_api {
541     int use_domain; /*! use_domain module parameter */
542     int db_mode; /*! db_mode module parameter */
543     unsigned int nat_flag; /*! nat_flag module parameter */
544 
545     register_udomain_t register_udomain;
546     get_udomain_t get_udomain;
547     lock_udomain_t lock_udomain;
548     unlock_udomain_t unlock_udomain;
549 
550     insert_impurecord_t insert_impurecord;
551     delete_impurecord_t delete_impurecord;
552     get_impurecord_t get_impurecord;
553     update_impurecord_t update_impurecord;
554 
555     lock_contact_slot_t lock_contact_slot;
556     unlock_contact_slot_t unlock_contact_slot;
557     lock_contact_slot_i_t lock_contact_slot_i;
558     unlock_contact_slot_i_t unlock_contact_slot_i;
559     lock_subscription_t lock_subscription;
560     unlock_subscription_t unlock_subscription;
561     unref_subscription_t unref_subscription;
562     ref_subscription_t ref_subscription;
563 
564     insert_ucontact_t insert_ucontact;
565     delete_ucontact_t delete_ucontact;
566     get_ucontact_t get_ucontact;
567     release_ucontact_t release_ucontact;
568     get_all_ucontacts_t get_all_ucontacts;
569     update_ucontact_t update_ucontact;
570     expire_ucontact_t expire_ucontact;
571     unlink_contact_from_impu_t unlink_contact_from_impu;
572     link_contact_to_impu_t link_contact_to_impu;
573     //update_user_profile_t update_user_profile;
574 
575     add_dialog_data_to_contact_t add_dialog_data_to_contact;
576     remove_dialog_data_from_contact_t remove_dialog_data_from_contact;
577 
578     add_subscriber_t add_subscriber;
579     update_subscriber_t update_subscriber;
580     external_delete_subscriber_t external_delete_subscriber;
581     get_subscriber_t get_subscriber;
582 
583     get_impus_from_subscription_as_string_t get_impus_from_subscription_as_string;
584 
585     register_ulcb_t register_ulcb;
586 
587     get_presentity_from_subscriber_dialog_t get_presentity_from_subscriber_dialog;
588 
589 } usrloc_api_t;
590 
591 /*! usrloc API export bind function */
592 typedef int (*bind_usrloc_t)(usrloc_api_t* api);
593 
594 #endif
595