4040#include "../../mem/mem.h"
4141#include "../../pt.h"
4242#include "../../db/db.h"
43+ #include "../../mi/mi.h"
4344#include "../tm/tm_load.h"
4445#include "../presence/hash.h"
4546#include "pua.h"
@@ -101,6 +102,28 @@ static void destroy(void);
101102static int update_pua (ua_pres_t * p , unsigned int hash_code , unsigned int final );
102103static void db_update (unsigned int ticks ,void * param );
103104static void hashT_clean (unsigned int ticks ,void * param );
105+ static mi_response_t * mi_list_presentities (const mi_params_t * params ,
106+ struct mi_handler * async_hdl );
107+ static mi_response_t * mi_list_subscription (const mi_params_t * params ,
108+ struct mi_handler * async_hdl );
109+
110+ static const mi_export_t mi_cmds [] = {
111+ { "list_presentities" , 0 ,0 ,0 , {
112+ {mi_list_presentities , {0 }},
113+ {mi_list_presentities , {"pres_uri" , 0 }},
114+ {mi_list_presentities , {"event" , 0 }},
115+ {mi_list_presentities , {"pres_uri" , "event" , 0 }},
116+ {EMPTY_MI_RECIPE }}, {0 }
117+ },
118+ { "list_subscription" , 0 ,0 ,0 , {
119+ {mi_list_subscription , {0 }},
120+ {mi_list_subscription , {"pres_uri" , 0 }},
121+ {mi_list_subscription , {"event" , 0 }},
122+ {mi_list_subscription , {"pres_uri" , "event" , 0 }},
123+ {EMPTY_MI_RECIPE }}, {0 }
124+ },
125+ {EMPTY_MI_EXPORT }
126+ };
104127
105128static const cmd_export_t cmds []= {
106129 {"pua_update_contact" ,(cmd_function )update_contact , {{0 ,0 ,0 }},
@@ -144,7 +167,7 @@ struct module_exports exports= {
144167 0 , /* exported async functions */
145168 params , /* exported parameters */
146169 0 , /* exported statistics */
147- 0 , /* exported MI functions */
170+ mi_cmds , /* exported MI functions */
148171 0 , /* exported pseudo-variables */
149172 0 , /* exported transformations */
150173 0 , /* extra processes */
@@ -156,6 +179,160 @@ struct module_exports exports= {
156179 0 /* reload confirm function */
157180};
158181
182+ static int mi_print_common (mi_item_t * item , ua_pres_t * p )
183+ {
184+ pua_event_t * event ;
185+
186+ event = get_event (p -> event );
187+ if (add_mi_string (item , MI_SSTR ("pres_uri" ),
188+ p -> pres_uri -> s , p -> pres_uri -> len ) < 0 ||
189+ (event ? add_mi_string (item , MI_SSTR ("event" ),
190+ event -> name .s , event -> name .len ) :
191+ add_mi_number (item , MI_SSTR ("event" ), p -> event )) < 0 ||
192+ add_mi_number (item , MI_SSTR ("expires" ), p -> expires ) < 0 ||
193+ add_mi_number (item , MI_SSTR ("desired_expires" ), p -> desired_expires ) < 0 ||
194+ add_mi_number (item , MI_SSTR ("flag" ), p -> flag ) < 0 ||
195+ add_mi_number (item , MI_SSTR ("db_flag" ), p -> db_flag ) < 0 ||
196+ add_mi_number (item , MI_SSTR ("ua_flag" ), p -> ua_flag ) < 0 )
197+ return -1 ;
198+
199+ if (p -> sh_tag .len && add_mi_string (item , MI_SSTR ("sharing_tag" ),
200+ p -> sh_tag .s , p -> sh_tag .len ) < 0 )
201+ return -1 ;
202+ return 0 ;
203+ }
204+
205+ static int mi_print_presentity (mi_item_t * array , ua_pres_t * p )
206+ {
207+ mi_item_t * item , * pending , * publ_item ;
208+ publ_t * publ ;
209+
210+ item = add_mi_object (array , NULL , 0 );
211+ if (!item || mi_print_common (item , p ) < 0 )
212+ return -1 ;
213+
214+ if (add_mi_string (item , MI_SSTR ("tuple_id" ),
215+ p -> tuple_id .s , p -> tuple_id .len ) < 0 ||
216+ add_mi_number (item , MI_SSTR ("waiting_reply" ), p -> waiting_reply ) < 0 )
217+ return -1 ;
218+
219+ if (p -> etag .s && p -> etag .len &&
220+ add_mi_string (item , MI_SSTR ("etag" ), p -> etag .s , p -> etag .len ) < 0 )
221+ return -1 ;
222+
223+ pending = add_mi_array (item , MI_SSTR ("pending_publ" ));
224+ if (!pending )
225+ return -1 ;
226+ for (publ = p -> pending_publ ; publ ; publ = publ -> next ) {
227+ publ_item = add_mi_object (pending , NULL , 0 );
228+ if (!publ_item ||
229+ add_mi_string (publ_item , MI_SSTR ("content_type" ),
230+ publ -> content_type .s , publ -> content_type .len ) < 0 ||
231+ add_mi_string (publ_item , MI_SSTR ("body" ),
232+ publ -> body .s , publ -> body .len ) < 0 ||
233+ add_mi_string (publ_item , MI_SSTR ("extra_headers" ),
234+ publ -> extra_headers .s , publ -> extra_headers .len ) < 0 ||
235+ add_mi_number (publ_item , MI_SSTR ("expires" ), publ -> expires ) < 0 )
236+ return -1 ;
237+ }
238+ return 0 ;
239+ }
240+
241+ static int mi_print_subscription (mi_item_t * array , ua_pres_t * p )
242+ {
243+ mi_item_t * item ;
244+
245+ item = add_mi_object (array , NULL , 0 );
246+ if (!item || mi_print_common (item , p ) < 0 )
247+ return -1 ;
248+
249+ if (add_mi_string (item , MI_SSTR ("to_uri" ), p -> to_uri .s , p -> to_uri .len ) < 0 ||
250+ add_mi_string (item , MI_SSTR ("watcher_uri" ),
251+ p -> watcher_uri -> s , p -> watcher_uri -> len ) < 0 ||
252+ add_mi_string (item , MI_SSTR ("call_id" ), p -> call_id .s , p -> call_id .len ) < 0 ||
253+ add_mi_string (item , MI_SSTR ("to_tag" ), p -> to_tag .s , p -> to_tag .len ) < 0 ||
254+ add_mi_string (item , MI_SSTR ("from_tag" ), p -> from_tag .s , p -> from_tag .len ) < 0 ||
255+ add_mi_number (item , MI_SSTR ("cseq" ), p -> cseq ) < 0 ||
256+ add_mi_number (item , MI_SSTR ("version" ), p -> version ) < 0 ||
257+ add_mi_number (item , MI_SSTR ("watcher_count" ), p -> watcher_count ) < 0 ||
258+ add_mi_string (item , MI_SSTR ("extra_headers" ),
259+ p -> extra_headers .s , p -> extra_headers .len ) < 0 ||
260+ add_mi_string (item , MI_SSTR ("record_route" ),
261+ p -> record_route .s , p -> record_route .len ) < 0 ||
262+ add_mi_string (item , MI_SSTR ("remote_contact" ),
263+ p -> remote_contact .s , p -> remote_contact .len ) < 0 ||
264+ add_mi_string (item , MI_SSTR ("contact" ), p -> contact .s , p -> contact .len ) < 0 )
265+ return -1 ;
266+
267+ if (p -> outbound_proxy && p -> outbound_proxy -> len &&
268+ add_mi_string (item , MI_SSTR ("outbound_proxy" ),
269+ p -> outbound_proxy -> s , p -> outbound_proxy -> len ) < 0 )
270+ return -1 ;
271+ return 0 ;
272+ }
273+
274+ static mi_response_t * mi_list_records (const mi_params_t * params ,
275+ int subscriptions )
276+ {
277+ mi_response_t * resp ;
278+ mi_item_t * array ;
279+ str pres_uri = STR_NULL , event_name = STR_NULL ;
280+ pua_event_t * event = NULL ;
281+ ua_pres_t * p ;
282+ int i , rc , have_pres_uri ;
283+
284+ rc = try_get_mi_string_param (params , "pres_uri" , & pres_uri .s , & pres_uri .len );
285+ if (rc < -1 )
286+ return init_mi_param_error ();
287+ have_pres_uri = (rc == 0 );
288+ rc = try_get_mi_string_param (params , "event" , & event_name .s , & event_name .len );
289+ if (rc < -1 )
290+ return init_mi_param_error ();
291+ if (rc == 0 ) {
292+ event = contains_pua_event (& event_name );
293+ if (!event )
294+ return init_mi_error (400 , MI_SSTR ("Unknown event" ));
295+ }
296+
297+ resp = init_mi_result_array (& array );
298+ if (!resp )
299+ return NULL ;
300+ for (i = 0 ; i < HASH_SIZE ; i ++ ) {
301+ lock_get (& HashT -> p_records [i ].lock );
302+ for (p = HashT -> p_records [i ].entity -> next ; p ; p = p -> next ) {
303+ /* A watcher URI identifies a subscription record. */
304+ if (!!p -> watcher_uri != subscriptions )
305+ continue ;
306+ if (have_pres_uri && (p -> pres_uri -> len != pres_uri .len ||
307+ memcmp (p -> pres_uri -> s , pres_uri .s , pres_uri .len ) != 0 ))
308+ continue ;
309+ if (event && p -> event != event -> ev_flag )
310+ continue ;
311+ if ((subscriptions ? mi_print_subscription (array , p ) :
312+ mi_print_presentity (array , p )) < 0 ) {
313+ lock_release (& HashT -> p_records [i ].lock );
314+ free_mi_response (resp );
315+ LM_ERR ("Unable to create PUA records reply\n" );
316+ return NULL ;
317+ }
318+ }
319+ lock_release (& HashT -> p_records [i ].lock );
320+ }
321+ return resp ;
322+ }
323+
324+ static mi_response_t * mi_list_presentities (const mi_params_t * params ,
325+ struct mi_handler * async_hdl )
326+ {
327+ return mi_list_records (params , 0 );
328+ }
329+
330+ static mi_response_t * mi_list_subscription (const mi_params_t * params ,
331+ struct mi_handler * async_hdl )
332+ {
333+ return mi_list_records (params , 1 );
334+ }
335+
159336/**
160337 * init module function
161338 */
0 commit comments