@ -151,8 +151,6 @@ struct local_pvt {
struct ast_jb_conf jb_conf ; /*!< jitterbuffer configuration for this local channel */
struct ast_channel * owner ; /*!< Master Channel - Bridging happens here */
struct ast_channel * chan ; /*!< Outbound channel - PBX is run here */
struct ast_module_user * u_owner ; /*!< reference to keep the module loaded while in use */
struct ast_module_user * u_chan ; /*!< reference to keep the module loaded while in use */
} ;
# define LOCAL_ALREADY_MASQED (1 << 0) /*!< Already masqueraded */
@ -578,6 +576,7 @@ static void check_bridge(struct ast_channel *ast, struct local_pvt *p)
}
if ( p - > chan - > audiohooks ) {
struct ast_audiohook_list * audiohooks_swapper ;
audiohooks_swapper = p - > chan - > audiohooks ;
p - > chan - > audiohooks = p - > owner - > audiohooks ;
p - > owner - > audiohooks = audiohooks_swapper ;
@ -679,7 +678,7 @@ static int local_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
ao2_lock ( p ) ;
if ( ( p - > owner ! = oldchan ) & & ( p - > chan ! = oldchan ) ) {
ast_log ( LOG_WARNING , " Old channel wasn't %p but was %p/ %p\n " , oldchan , p - > owner , p - > chan ) ;
ast_log ( LOG_WARNING , " Old channel %p wasn't %p or %p\n " , oldchan , p - > owner , p - > chan ) ;
ao2_unlock ( p ) ;
return - 1 ;
}
@ -1047,16 +1046,15 @@ static int local_hangup(struct ast_channel *ast)
if ( isoutbound ) {
const char * status = pbx_builtin_getvar_helper ( p - > chan , " DIALSTATUS " ) ;
if ( ( status ) & & ( p - > owner ) ) {
if ( status & & p - > owner ) {
p - > owner - > hangupcause = p - > chan - > hangupcause ;
pbx_builtin_setvar_helper ( p - > owner , " CHANLOCALSTATUS " , status ) ;
}
ast_clear_flag ( p , LOCAL_LAUNCHED_PBX ) ;
ast_module_user_remove ( p - > u_chan ) ;
p - > chan = NULL ;
} else {
ast_module_user_remove ( p - > u_owner ) ;
if ( p - > chan ) {
ast_queue_hangup ( p - > chan ) ;
}
@ -1067,6 +1065,7 @@ static int local_hangup(struct ast_channel *ast)
if ( ! p - > owner & & ! p - > chan ) {
ao2_unlock ( p ) ;
/* Remove from list */
ao2_unlink ( locals , p ) ;
ao2_ref ( p , - 1 ) ;
@ -1086,6 +1085,10 @@ local_hangup_cleanup:
ao2_unlock ( p ) ;
ao2_ref ( p , - 1 ) ;
}
if ( owner ) {
ast_channel_unlock ( owner ) ;
owner = ast_channel_unref ( owner ) ;
}
if ( chan ) {
ast_channel_unlock ( chan ) ;
if ( hangup_chan ) {
@ -1093,26 +1096,37 @@ local_hangup_cleanup:
}
chan = ast_channel_unref ( chan ) ;
}
if ( owner ) {
ast_channel_unlock ( owner ) ;
owner = ast_channel_unref ( owner ) ;
}
/* leave with the same stupid channel locked that came in */
ast_channel_lock ( ast ) ;
return res ;
}
/*!
* \ internal
* \ brief struct local_pvt destructor .
*
* \ param vdoomed Void local_pvt to destroy .
*
* \ return Nothing
*/
static void local_pvt_destructor ( void * vdoomed )
{
ast_module_unref ( ast_module_info - > self ) ;
}
/*! \brief Create a call structure */
static struct local_pvt * local_alloc ( const char * data , format_t format )
{
struct local_pvt * tmp = NULL ;
char * c = NULL , * opts = NULL ;
if ( ! ( tmp = ao2_alloc ( sizeof ( * tmp ) , NULL ) ) ) {
if ( ! ( tmp = ao2_alloc ( sizeof ( * tmp ) , local_pvt_destructor ) ) ) {
return NULL ;
}
ast_module_ref ( ast_module_info - > self ) ;
/* Initialize private structure information */
ast_copy_string ( tmp - > exten , data , sizeof ( tmp - > exten ) ) ;
@ -1217,8 +1231,6 @@ static struct ast_channel *local_new(struct local_pvt *p, int state, const char
p - > owner = tmp ;
p - > chan = tmp2 ;
p - > u_owner = ast_module_user_add ( p - > owner ) ;
p - > u_chan = ast_module_user_add ( p - > chan ) ;
ast_copy_string ( tmp - > context , p - > context , sizeof ( tmp - > context ) ) ;
ast_copy_string ( tmp2 - > context , p - > context , sizeof ( tmp2 - > context ) ) ;
@ -1248,9 +1260,7 @@ static struct ast_channel *local_request(const char *type, format_t format, cons
} else if ( ast_channel_cc_params_init ( chan , requestor ? ast_channel_get_cc_config_params ( ( struct ast_channel * ) requestor ) : NULL ) ) {
ao2_unlink ( locals , p ) ;
p - > owner = ast_channel_release ( p - > owner ) ;
ast_module_user_remove ( p - > u_owner ) ;
p - > chan = ast_channel_release ( p - > chan ) ;
ast_module_user_remove ( p - > u_chan ) ;
chan = NULL ;
}
ao2_ref ( p , - 1 ) ; /* kill the ref from the alloc */