/* Attempt to pick up specified extension with context */ static int pickup_by_exten(struct ast_channel *chan, const char *exten, const char *context) { struct ast_channel *target = NULL;/*!< Potential pickup target */ struct ast_channel_iterator *iter; int res = -1; if (!(iter = ast_channel_iterator_by_exten_new(exten, context))) { return -1; } while ((target = ast_channel_iterator_next(iter))) { ast_channel_lock(target); if ((chan != target) && ast_can_pickup(target)) { ast_log(LOG_NOTICE, "%s pickup by %s\n", ast_channel_name(target), ast_channel_name(chan)); break; } ast_channel_unlock(target); target = ast_channel_unref(target); } ast_channel_iterator_destroy(iter); if (target) { res = ast_do_pickup(chan, target); ast_channel_unlock(target); target = ast_channel_unref(target); } return res; }
/* Attempt to pick up specified by partial channel name */ static int pickup_by_part(struct ast_channel *chan, const char *part) { struct ast_channel *target;/*!< Potential pickup target */ int res = -1; /* The found channel is already locked. */ target = ast_channel_callback(find_by_part, NULL, (char *) part, 0); if (target) { res = ast_do_pickup(chan, target); ast_channel_unlock(target); target = ast_channel_unref(target); } return res; }
/*! \brief Attempt to pick up named channel. */ static int pickup_by_channel(struct ast_channel *chan, const char *name) { int res = -1; struct ast_channel *target;/*!< Potential pickup target */ /* The found channel is already locked. */ target = find_by_channel(chan, name); if (target) { res = ast_do_pickup(chan, target); ast_channel_unlock(target); target = ast_channel_unref(target); } return res; }
static int pickup_by_group(struct ast_channel *chan) { struct ast_channel *target;/*!< Potential pickup target */ int res = -1; /* The found channel is already locked. */ target = ast_pickup_find_by_group(chan); if (target) { ast_log(LOG_NOTICE, "pickup %s attempt by %s\n", ast_channel_name(target), ast_channel_name(chan)); res = ast_do_pickup(chan, target); ast_channel_unlock(target); target = ast_channel_unref(target); } return res; }
/*! \brief Attempt to pick up named channel, does not use context */ static int pickup_by_channel(struct ast_channel *chan, char *pickup) { int res = -1; struct ast_channel *target;/*!< Potential pickup target */ target = my_ast_get_channel_by_name_locked(pickup); if (target) { /* Just check that we are not picking up the SAME as target. (i.e. ourself) */ if (chan != target) { res = ast_do_pickup(chan, target); } ast_channel_unlock(target); target = ast_channel_unref(target); } return res; }
/*! * \brief Pickup a call * \param chan channel that initiated pickup. * * Walk list of channels, checking it is not itself, channel is pbx one, * check that the callgroup for both channels are the same and the channel is ringing. * Answer calling channel, flag channel as answered on queue, masq channels together. */ int ast_pickup_call(struct ast_channel *chan) { struct ast_channel *target;/*!< Potential pickup target */ int res = -1; RAII_VAR(struct ast_features_pickup_config *, pickup_cfg, NULL, ao2_cleanup); const char *pickup_sound; const char *fail_sound; ast_debug(1, "Pickup attempt by %s\n", ast_channel_name(chan)); ast_channel_lock(chan); pickup_cfg = ast_get_chan_features_pickup_config(chan); if (!pickup_cfg) { ast_log(LOG_ERROR, "Unable to retrieve pickup configuration. Unable to play pickup sounds\n"); } pickup_sound = ast_strdupa(pickup_cfg ? pickup_cfg->pickupsound : ""); fail_sound = ast_strdupa(pickup_cfg ? pickup_cfg->pickupfailsound : ""); ast_channel_unlock(chan); /* The found channel is already locked. */ target = ast_pickup_find_by_group(chan); if (target) { ast_log(LOG_NOTICE, "Pickup %s attempt by %s\n", ast_channel_name(target), ast_channel_name(chan)); res = ast_do_pickup(chan, target); ast_channel_unlock(target); if (!res) { if (!ast_strlen_zero(pickup_sound)) { pbx_builtin_setvar_helper(target, "BRIDGE_PLAY_SOUND", pickup_sound); } } else { ast_log(LOG_WARNING, "Pickup %s failed by %s\n", ast_channel_name(target), ast_channel_name(chan)); } target = ast_channel_unref(target); } if (res < 0) { ast_debug(1, "No call pickup possible... for %s\n", ast_channel_name(chan)); if (!ast_strlen_zero(fail_sound)) { ast_answer(chan); ast_stream_and_wait(chan, fail_sound, ""); } } return res; }