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