1 /* $Id$ */
2 /*
3  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
4  * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20 #ifndef __PJSIP_SIP_URI_H__
21 #define __PJSIP_SIP_URI_H__
22 
23 /**
24  * @file sip_uri.h
25  * @brief SIP URL Structures and Manipulations
26  */
27 
28 #include <pjsip/sip_types.h>
29 #include <pjsip/sip_config.h>
30 #include <pj/list.h>
31 #include <pjlib-util/scanner.h>
32 
33 PJ_BEGIN_DECL
34 
35 
36 /**
37  * @defgroup PJSIP_URI URI
38  * @brief URI types and manipulations.
39  * @ingroup PJSIP_MSG
40  */
41 
42 /**
43  * @addtogroup PJSIP_URI_PARAM URI Parameter Container
44  * @ingroup PJSIP_URI
45  * @brief Generic parameter elements container.
46  * @{
47  */
48 
49 /**
50  * Generic parameter, normally used in other_param or header_param.
51  */
52 typedef struct pjsip_param
53 {
54     PJ_DECL_LIST_MEMBER(struct pjsip_param);	/**< Generic list member.   */
55     pj_str_t	    name;			/**< Param/header name.	    */
56     pj_str_t	    value;			/**< Param/header value.    */
57 } pjsip_param;
58 
59 
60 /**
61  * Find the specified parameter name in the list. The name will be compared
62  * in case-insensitive comparison.
63  *
64  * @param param_list	List of parameters to find.
65  * @param name		Parameter/header name to find.
66  *
67  * @return		The parameter if found, or NULL.
68  */
69 PJ_DECL(pjsip_param*) pjsip_param_find( const pjsip_param *param_list,
70 					const pj_str_t *name );
71 
72 
73 /**
74  * Alias for pjsip_param_find()
75  */
pjsip_param_cfind(const pjsip_param * param_list,const pj_str_t * name)76 PJ_INLINE(pjsip_param*) pjsip_param_cfind(const pjsip_param *param_list,
77 					  const pj_str_t *name)
78 {
79     return pjsip_param_find(param_list, name);
80 }
81 
82 /**
83  * Compare two parameter lists.
84  *
85  * @param param_list1	First parameter list.
86  * @param param_list2	Second parameter list.
87  * @param ig_nf		If set to 1, do not compare parameters that only
88  * 			appear in one of the list.
89  *
90  * @return		Zero if the parameter list are equal, non-zero
91  * 			otherwise.
92  */
93 PJ_DECL(int) pjsip_param_cmp(const pjsip_param *param_list1,
94 			     const pjsip_param *param_list2,
95 			     pj_bool_t ig_nf);
96 
97 /**
98  * Duplicate the parameters.
99  *
100  * @param pool		Pool to allocate memory from.
101  * @param dst_list	Destination list.
102  * @param src_list	Source list.
103  */
104 PJ_DECL(void) pjsip_param_clone(pj_pool_t *pool, pjsip_param *dst_list,
105 				const pjsip_param *src_list);
106 
107 /**
108  * Duplicate the parameters.
109  *
110  * @param pool		Pool to allocate memory from.
111  * @param dst_list	Destination list.
112  * @param src_list	Source list.
113  */
114 PJ_DECL(void) pjsip_param_shallow_clone(pj_pool_t *pool,
115 					pjsip_param *dst_list,
116 					const pjsip_param *src_list);
117 
118 /**
119  * Print parameters.
120  *
121  * @param param_list	The parameter list.
122  * @param buf		Buffer.
123  * @param size		Size of buffer.
124  * @param pname_unres	Specification of allowed characters in pname.
125  * @param pvalue_unres	Specification of allowed characters in pvalue.
126  * @param sep		Separator character (either ';', ',', or '?').
127  *			When separator is set to '?', this function will
128  *			automatically adjust the separator character to
129  *			'&' after the first parameter is printed.
130  *
131  * @return		The number of bytes printed, or -1 on errr.
132  */
133 PJ_DECL(pj_ssize_t) pjsip_param_print_on(const pjsip_param *param_list,
134 					 char *buf, pj_size_t size,
135 					 const pj_cis_t *pname_unres,
136 					 const pj_cis_t *pvalue_unres,
137 					 int sep);
138 
139 /**
140  * @}
141  */
142 
143 /**
144  * @defgroup PJSIP_URI_GENERIC Generic URI
145  * @ingroup PJSIP_URI
146  * @brief Generic representation for all types of URI.
147  * @{
148  */
149 
150 /**
151  * URI context.
152  */
153 typedef enum pjsip_uri_context_e
154 {
155     PJSIP_URI_IN_REQ_URI,	/**< The URI is in Request URI. */
156     PJSIP_URI_IN_FROMTO_HDR,	/**< The URI is in From/To header. */
157     PJSIP_URI_IN_CONTACT_HDR,	/**< The URI is in Contact header. */
158     PJSIP_URI_IN_ROUTING_HDR,	/**< The URI is in Route/Record-Route header. */
159     PJSIP_URI_IN_OTHER		/**< Other context (web page, business card, etc.) */
160 } pjsip_uri_context_e;
161 
162 /**
163  * URI 'virtual' function table.
164  * All types of URI in this library (such as sip:, sips:, tel:, and name-addr)
165  * will have pointer to this table as their first struct member. This table
166  * provides polimorphic behaviour to the URI.
167  */
168 typedef struct pjsip_uri_vptr
169 {
170     /**
171      * Get URI scheme.
172      * @param uri the URI (self).
173      * @return the URI scheme.
174      */
175     const pj_str_t* (*p_get_scheme)(const void *uri);
176 
177     /**
178      * Get the URI object contained by this URI, or the URI itself if
179      * it doesn't contain another URI.
180      * @param uri the URI (self).
181      */
182     void* (*p_get_uri)(void *uri);
183 
184     /**
185      * Print URI components to the buffer, following the rule of which
186      * components are allowed for the context.
187      * @param context the context where the URI will be placed.
188      * @param uri the URI (self).
189      * @param buf the buffer.
190      * @param size the size of the buffer.
191      * @return the length printed.
192      */
193     pj_ssize_t (*p_print)(pjsip_uri_context_e context,
194 			  const void *uri,
195 		          char *buf, pj_size_t size);
196 
197     /**
198      * Compare two URIs according to the context.
199      * @param context the context.
200      * @param uri1 the first URI (self).
201      * @param uri2 the second URI.
202      * @return PJ_SUCCESS if equal, or otherwise the error status which
203      *		    should point to the mismatch part.
204      */
205     pj_status_t	(*p_compare)(pjsip_uri_context_e context,
206 			     const void *uri1, const void *uri2);
207 
208     /**
209      * Clone URI.
210      * @param pool the pool.
211      * @param the URI to clone (self).
212      * @return new URI.
213      */
214     void *(*p_clone)(pj_pool_t *pool, const void *uri);
215 
216 } pjsip_uri_vptr;
217 
218 
219 /**
220  * The declaration of 'base class' for all URI scheme.
221  */
222 struct pjsip_uri
223 {
224     /** All URIs must have URI virtual function table as their first member. */
225     pjsip_uri_vptr *vptr;
226 };
227 
228 /**
229  * This macro checks that the URL is a "sip:" URL.
230  * @param url The URL (pointer to)
231  * @return non-zero if TRUE.
232  */
233 #define PJSIP_URI_SCHEME_IS_SIP(url)	\
234     (pj_stricmp2(pjsip_uri_get_scheme(url), "sip")==0)
235 
236 /**
237  * This macro checks that the URL is a "sips:" URL (not SIP).
238  * @param url The URL (pointer to)
239  * @return non-zero if TRUE.
240  */
241 #define PJSIP_URI_SCHEME_IS_SIPS(url)	\
242     (pj_stricmp2(pjsip_uri_get_scheme(url), "sips")==0)
243 
244 /**
245  * This macro checks that the URL is a "tel:" URL.
246  * @param url The URL (pointer to)
247  * @return non-zero if TRUE.
248  */
249 #define PJSIP_URI_SCHEME_IS_TEL(url)	\
250     (pj_stricmp2(pjsip_uri_get_scheme(url), "tel")==0)
251 
252 
253 /**
254  * Generic function to get the URI scheme.
255  * @param uri	    the URI object.
256  * @return	    the URI scheme.
257  */
pjsip_uri_get_scheme(const void * uri)258 PJ_INLINE(const pj_str_t*) pjsip_uri_get_scheme(const void *uri)
259 {
260     return (*((pjsip_uri*)uri)->vptr->p_get_scheme)(uri);
261 }
262 
263 /**
264  * Generic function to get the URI object contained by this URI, or the URI
265  * itself if it doesn't contain another URI.
266  *
267  * @param uri	    the URI.
268  * @return	    the URI.
269  */
pjsip_uri_get_uri(const void * uri)270 PJ_INLINE(void*) pjsip_uri_get_uri(const void *uri)
271 {
272     return (*((pjsip_uri*)uri)->vptr->p_get_uri)((void*)uri);
273 }
274 
275 /**
276  * Generic function to compare two URIs.
277  *
278  * @param context   Comparison context.
279  * @param uri1	    The first URI.
280  * @param uri2	    The second URI.
281  * @return	    PJ_SUCCESS if equal, or otherwise the error status which
282  *		    should point to the mismatch part.
283  */
pjsip_uri_cmp(pjsip_uri_context_e context,const void * uri1,const void * uri2)284 PJ_INLINE(pj_status_t) pjsip_uri_cmp(pjsip_uri_context_e context,
285 				     const void *uri1, const void *uri2)
286 {
287     return (*((const pjsip_uri*)uri1)->vptr->p_compare)(context, uri1, uri2);
288 }
289 
290 /**
291  * Generic function to print an URI object.
292  *
293  * @param context   Print context.
294  * @param uri	    The URI to print.
295  * @param buf	    The buffer.
296  * @param size	    Size of the buffer.
297  * @return	    Length printed if successful, negative value if failed.
298  */
pjsip_uri_print(pjsip_uri_context_e context,const void * uri,char * buf,pj_size_t size)299 PJ_INLINE(int) pjsip_uri_print(pjsip_uri_context_e context,
300 			       const void *uri,
301 			       char *buf, pj_size_t size)
302 {
303     return (int)(*((const pjsip_uri*)uri)->vptr->p_print)(context, uri,
304 							  buf, size);
305 }
306 
307 /**
308  * Generic function to clone an URI object.
309  *
310  * @param pool	    Pool.
311  * @param uri	    URI to clone.
312  * @return	    New URI.
313  */
pjsip_uri_clone(pj_pool_t * pool,const void * uri)314 PJ_INLINE(void*) pjsip_uri_clone( pj_pool_t *pool, const void *uri )
315 {
316     return (*((const pjsip_uri*)uri)->vptr->p_clone)(pool, uri);
317 }
318 
319 
320 
321 /**
322  * @}
323  */
324 
325 /**
326  * @defgroup PJSIP_SIP_URI SIP URI Scheme and Name address
327  * @ingroup PJSIP_URI
328  * @brief SIP URL structure ("sip:" and "sips:")
329  * @{
330  */
331 
332 
333 /**
334  * SIP and SIPS URL scheme.
335  */
336 typedef struct pjsip_sip_uri
337 {
338     pjsip_uri_vptr *vptr;		/**< Pointer to virtual function table.*/
339     pj_str_t	    user;		/**< Optional user part. */
340     pj_str_t	    passwd;		/**< Optional password part. */
341     pj_str_t	    host;		/**< Host part, always exists. */
342     int		    port;		/**< Optional port number, or zero. */
343     pj_str_t	    user_param;		/**< Optional user parameter */
344     pj_str_t	    method_param;	/**< Optional method parameter. */
345     pj_str_t	    transport_param;	/**< Optional transport parameter. */
346     int		    ttl_param;		/**< Optional TTL param, or -1. */
347     int		    lr_param;		/**< Optional loose routing param, or zero */
348     pj_str_t	    maddr_param;	/**< Optional maddr param */
349     pjsip_param	    other_param;	/**< Other parameters grouped together. */
350     pjsip_param	    header_param;	/**< Optional header parameter. */
351 } pjsip_sip_uri;
352 
353 
354 /**
355  * SIP name-addr, which typically appear in From, To, and Contact header.
356  * The SIP name-addr contains a generic URI and a display name.
357  */
358 typedef struct pjsip_name_addr
359 {
360     /** Pointer to virtual function table. */
361     pjsip_uri_vptr  *vptr;
362 
363     /** Optional display name. */
364     pj_str_t	     display;
365 
366     /** URI part. */
367     pjsip_uri	    *uri;
368 
369 } pjsip_name_addr;
370 
371 
372 /**
373  * Create new SIP URL and initialize all fields with zero or NULL.
374  * @param pool	    The pool.
375  * @param secure    Flag to indicate whether secure transport should be used.
376  * @return SIP URL.
377  */
378 PJ_DECL(pjsip_sip_uri*) pjsip_sip_uri_create( pj_pool_t *pool,
379 					      pj_bool_t secure );
380 
381 /**
382  * Change the SIP URI scheme to sip or sips based on the secure flag.
383  * This would not change anything except the scheme.
384  * @param uri	    The URI
385  * @param secure    Non-zero if sips is wanted.
386  */
387 PJ_DECL(void) pjsip_sip_uri_set_secure( pjsip_sip_uri *uri,
388 				        pj_bool_t secure );
389 
390 /**
391  * Initialize SIP URL (all fields are set to NULL or zero).
392  * @param url	    The URL.
393  * @param secure    Create sips URI?
394  */
395 PJ_DECL(void)  pjsip_sip_uri_init(pjsip_sip_uri *url, pj_bool_t secure);
396 
397 /**
398  * Perform full assignment to the SIP URL.
399  * @param pool	    The pool.
400  * @param url	    Destination URL.
401  * @param rhs	    The source URL.
402  */
403 PJ_DECL(void)  pjsip_sip_uri_assign(pj_pool_t *pool, pjsip_sip_uri *url,
404 				    const pjsip_sip_uri *rhs);
405 
406 /**
407  * Create new instance of name address and initialize all fields with zero or
408  * NULL.
409  * @param pool	    The pool.
410  * @return	    New SIP name address.
411  */
412 PJ_DECL(pjsip_name_addr*) pjsip_name_addr_create(pj_pool_t *pool);
413 
414 /**
415  * Initialize with default value.
416  * @param name_addr The name address.
417  */
418 PJ_DECL(void) pjsip_name_addr_init(pjsip_name_addr *name_addr);
419 
420 /**
421  * Perform full assignment to the name address.
422  * @param pool	    The pool.
423  * @param addr	    The destination name address.
424  * @param rhs	    The source name address.
425  */
426 PJ_DECL(void)  pjsip_name_addr_assign(pj_pool_t *pool,
427 				      pjsip_name_addr *addr,
428 				      const pjsip_name_addr *rhs);
429 
430 /**
431  * @}
432  */
433 
434 /**
435  * @defgroup PJSIP_OTHER_URI Other URI schemes
436  * @ingroup PJSIP_URI
437  * @brief Container for non SIP/tel URI scheme (e.g. "http:", "mailto:")
438  * @{
439  */
440 
441 /**
442  * Generic URI container for non SIP/tel URI scheme.
443  */
444 typedef struct pjsip_other_uri
445 {
446     pjsip_uri_vptr *vptr;	/**< Pointer to virtual function table.	*/
447     pj_str_t scheme;		/**< The URI scheme (e.g. "mailto")	*/
448     pj_str_t content;		/**< The whole URI content		*/
449 } pjsip_other_uri;
450 
451 
452 /**
453  * Create a generic URI object.
454  *
455  * @param pool	    The pool to allocate memory from.
456  *
457  * @return	    The URI instance.
458  */
459 PJ_DECL(pjsip_other_uri*) pjsip_other_uri_create(pj_pool_t *pool);
460 
461 
462 /**
463  * @}
464  */
465 
466 PJ_END_DECL
467 
468 #endif	/* __PJSIP_URL_H__ */
469 
470