@@ -106,6 +106,8 @@ str* b2bl_init_extern(struct b2b_params *init_params,
106106 b2bl_init_params_t * scen_params , str * e1_id , str * e2_id ,
107107 b2bl_cback_f cbf , void * cb_param , unsigned int cb_mask );
108108
109+ static int pv_get_b2bl_peer (struct sip_msg * msg , pv_param_t * param , pv_value_t * tv );
110+ static int pv_parse_b2bl_peer (pv_spec_p sp , const str * in );
109111int pv_get_b2bl_key (struct sip_msg * msg , pv_param_t * param , pv_value_t * res );
110112int pv_get_scenario (struct sip_msg * msg , pv_param_t * param , pv_value_t * res );
111113int pv_parse_entity_name (pv_spec_p sp , const str * in );
@@ -311,6 +313,8 @@ static const pv_export_t mod_items[] = {
311313 0 , pv_parse_entity_name , pv_parse_entity_index , 0 , 0 },
312314 {str_const_init ("b2b_logic.ctx" ), 1000 , pv_get_ctx ,
313315 pv_set_ctx , pv_parse_ctx_name , 0 , 0 , 0 },
316+ {str_const_init ("b2b_logic.peer" ), 1000 , pv_get_b2bl_peer ,
317+ NULL , pv_parse_b2bl_peer , 0 , 0 , 0 },
314318 { {0 , 0 }, 0 , 0 , 0 , 0 , 0 , 0 , 0 }
315319};
316320
@@ -2374,3 +2378,124 @@ int b2bl_restore_upper_info(str* b2bl_key, b2bl_cback_f cbf, void* param,
23742378
23752379 return 0 ;
23762380}
2381+
2382+ static int pv_parse_b2bl_peer (pv_spec_p sp , const str * in )
2383+ {
2384+ char * p ;
2385+ char * s ;
2386+ pv_spec_p nsp = 0 ;
2387+
2388+ if (in == NULL || in -> s == NULL || sp == NULL )
2389+ return -1 ;
2390+ p = in -> s ;
2391+ if (* p == PV_MARKER )
2392+ {
2393+ nsp = (pv_spec_p )pkg_malloc (sizeof (pv_spec_t ));
2394+ if (nsp == NULL )
2395+ {
2396+ LM_ERR ("no more memory\n" );
2397+ return -1 ;
2398+ }
2399+ s = pv_parse_spec (in , nsp );
2400+ if (s == NULL )
2401+ {
2402+ LM_ERR ("invalid name [%.*s]\n" , in -> len , in -> s );
2403+ pv_spec_free (nsp );
2404+ return -1 ;
2405+ }
2406+ sp -> pvp .pvn .type = PV_NAME_PVAR ;
2407+ sp -> pvp .pvn .u .dname = (void * )nsp ;
2408+ return 0 ;
2409+ }
2410+ /* remember it was a string, so we can retrieve it later */
2411+ sp -> pvp .pvn .u .isname .name .s = * in ;
2412+ sp -> pvp .pvn .u .isname .type = AVP_NAME_STR ;
2413+ return 0 ;
2414+
2415+ }
2416+
2417+ static int pv_get_b2bl_peer (struct sip_msg * msg , pv_param_t * param , pv_value_t * res )
2418+ {
2419+ #define B2BL_PEER_BUF_SIZE 2048
2420+ int ret ;
2421+ char _buf [B2BL_PEER_BUF_SIZE ], * p = _buf ;
2422+ pv_value_t tv ;
2423+ b2bl_tuple_t * tuple ;
2424+ unsigned int hash_index , local_index ;
2425+ b2bl_entity_id_t * entity ;
2426+ int entity_no ;
2427+ str entity_str ;
2428+
2429+ if (msg == NULL || res == NULL || param == NULL )
2430+ return -1 ;
2431+
2432+ if (param -> pvn .type == PV_NAME_PVAR )
2433+ {
2434+ if (pv_get_spec_name (msg , param , & tv )!= 0 || (!(tv .flags & PV_VAL_STR )))
2435+ {
2436+ LM_ERR ("invalid name\n" );
2437+ return -1 ;
2438+ }
2439+ } else {
2440+ tv .rs = param -> pvn .u .isname .name .s ;
2441+ }
2442+ ret = b2bl_get_tuple_key (& tv .rs , & hash_index , & local_index , & entity_str );
2443+ if (ret < 0 )
2444+ {
2445+ if (ret == -1 )
2446+ LM_ERR ("Failed to parse key or find an entity [%.*s]\n" ,
2447+ tv .rs .len , tv .rs .s );
2448+ else
2449+ LM_ERR ("Could not find entity [%.*s]\n" ,
2450+ tv .rs .len , tv .rs .s );
2451+ return -1 ;
2452+ }
2453+ B2BL_LOCK_GET (hash_index );
2454+
2455+ ret = -1 ;
2456+ tuple = b2bl_search_tuple_safe (hash_index , local_index );
2457+ if (tuple == NULL )
2458+ {
2459+ LM_ERR ("No tuple found for %.*s\n" , tv .rs .len , tv .rs .s );
2460+ goto end ;
2461+ }
2462+ entity_no = b2bl_search_other_entity (tuple , & entity_str );
2463+ if (entity_no < 0 ) {
2464+ LM_ERR ("Can not determine entity [%.*s]\n" ,
2465+ entity_str .len , entity_str .s );
2466+ goto end ;
2467+ }
2468+ entity = tuple -> bridge_entities [entity_no ];
2469+ if (!entity ) {
2470+ LM_ERR ("Can not find entity [%.*s]\n" ,
2471+ tv .rs .len , tv .rs .s );
2472+ goto end ;
2473+ }
2474+ if (!entity -> dlginfo ) {
2475+ LM_ERR ("no dialog for entity [%.*s]\n" ,
2476+ tv .rs .len , tv .rs .s );
2477+ goto end ;
2478+ }
2479+ if (entity -> dlginfo -> callid .len + entity -> dlginfo -> fromtag .len +
2480+ entity -> dlginfo -> totag .len + 2 /* two ';' */ >= B2BL_PEER_BUF_SIZE ) {
2481+ LM_ERR ("buffer too small (%d) for dialog info entity[%.*s]\n" ,
2482+ B2BL_PEER_BUF_SIZE , tv .rs .len , tv .rs .s );
2483+ goto end ;
2484+ }
2485+ memcpy (p , entity -> dlginfo -> callid .s , entity -> dlginfo -> callid .len );
2486+ p += entity -> dlginfo -> callid .len ;
2487+ * p ++ = ';' ;
2488+ memcpy (p , entity -> dlginfo -> fromtag .s , entity -> dlginfo -> fromtag .len );
2489+ p += entity -> dlginfo -> fromtag .len ;
2490+ * p ++ = ';' ;
2491+ memcpy (p , entity -> dlginfo -> totag .s , entity -> dlginfo -> totag .len );
2492+ p += entity -> dlginfo -> totag .len ;
2493+ #undef B2BL_PEER_BUF_SIZE
2494+ res -> flags = PV_VAL_STR ;
2495+ res -> rs .s = _buf ;
2496+ res -> rs .len = p - _buf ;
2497+ ret = 0 ;
2498+ end :
2499+ B2BL_LOCK_RELEASE (hash_index );
2500+ return (ret < 0 ?pv_get_null (msg , param , res ):ret );
2501+ }
0 commit comments