57 #include "asterisk/stasis_channels.h"
58 #include "asterisk/features_config.h"
64 .to_ami = call_pickup_to_ami);
74 .
type =
"pickup-active",
79 if (!ast_channel_pbx(chan) && !ast_channel_masq(chan) && !ast_test_flag(ast_channel_flags(chan),
AST_FLAG_ZOMBIE)
100 if (chan == target) {
104 ast_channel_lock(target);
107 while (ast_channel_trylock(chan)) {
108 ast_channel_unlock(target);
110 ast_channel_lock(target);
118 if ((ast_channel_pickupgroup(chan) & ast_channel_callgroup(target))
120 ast_channel_named_callgroups(target)))) {
126 ast_channel_unlock(chan);
128 ast_channel_unlock(target);
153 while ((candidate = ao2_iterator_next(&iter))) {
159 if (
ast_tvcmp(ast_channel_creationtime(candidate), ast_channel_creationtime(target)) < 0) {
174 ast_channel_lock(target);
183 ast_channel_unlock(target);
204 const char *pickup_sound;
205 const char *fail_sound;
207 ast_debug(1,
"Pickup attempt by %s\n", ast_channel_name(chan));
208 ast_channel_lock(chan);
209 pickup_cfg = ast_get_chan_features_pickup_config(chan);
211 ast_log(LOG_ERROR,
"Unable to retrieve pickup configuration. Unable to play pickup sounds\n");
213 pickup_sound =
ast_strdupa(pickup_cfg ? pickup_cfg->pickupsound :
"");
214 fail_sound =
ast_strdupa(pickup_cfg ? pickup_cfg->pickupfailsound :
"");
215 ast_channel_unlock(chan);
220 ast_log(LOG_NOTICE,
"Pickup %s attempt by %s\n", ast_channel_name(target), ast_channel_name(chan));
223 ast_channel_unlock(target);
225 if (!ast_strlen_zero(pickup_sound)) {
229 ast_log(LOG_WARNING,
"Pickup %s failed by %s\n", ast_channel_name(target), ast_channel_name(chan));
235 ast_debug(1,
"No call pickup possible... for %s\n", ast_channel_name(chan));
236 if (!ast_strlen_zero(fail_sound)) {
258 ast_assert(chan != NULL && target != NULL);
305 const char *chan_name;
306 const char *target_name;
312 target_name =
ast_strdupa(ast_channel_name(target));
313 ast_debug(1,
"Call pickup on '%s' by '%s'\n", target_name, ast_channel_name(chan));
316 ds_pickup = ast_datastore_alloc(&pickup_active, NULL);
319 "Unable to create channel datastore on '%s' for call pickup\n", target_name);
326 ast_channel_unlock(target);
336 ast_channel_lock(chan);
339 ast_channel_unlock(chan);
343 ast_log(LOG_WARNING,
"Unable to answer '%s'\n", chan_name);
348 ast_log(LOG_WARNING,
"Unable to queue answer on '%s'\n", chan_name);
355 ast_channel_hangupcause_set(chan, AST_CAUSE_ANSWERED_ELSEWHERE);
357 ast_channel_lock(chan);
359 ast_channel_unlock(chan);
360 if (!chan_snapshot) {
365 if (!target_snapshot) {
370 ast_log(LOG_WARNING,
"Unable to complete call pickup of '%s' with '%s'\n",
371 chan_name, target_name);
376 send_call_pickup_stasis_message(target, chan_snapshot, target_snapshot);
381 ast_channel_lock(target);
394 static void pickup_shutdown(
void)
Struct containing info for an AMI event to send out.
void ast_party_connected_line_init(struct ast_party_connected_line *init)
Initialize the given connected line structure.
Main Channel structure associated with a channel.
Asterisk main include file. File version handling, generic pbx functions.
int ast_queue_control(struct ast_channel *chan, enum ast_control_frame_type control)
Queue a control frame without payload.
CallerID (and other GR30) management and generation Includes code and algorithms from the Zapata libr...
void ast_party_id_reset(struct ast_party_id *id)
Destroy and initialize the given party id structure.
#define ast_channel_unref(c)
Decrease channel reference count.
struct ast_channel * ast_pickup_find_by_group(struct ast_channel *chan)
Find a pickup channel target by group.
#define STASIS_MESSAGE_TYPE_INIT(name)
Boiler-plate messaging macro for initializing message types.
Stasis Message Bus API. See Stasis Message Bus API for detailed documentation.
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
void ast_channel_update_connected_line(struct ast_channel *chan, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update)
Indicate that the connected line information has changed.
#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn)
Allocate and initialize a list container.
Structure representing a snapshot of channel state.
struct ast_str * ast_manager_build_channel_state_string_prefix(const struct ast_channel_snapshot *snapshot, const char *prefix)
Generate the AMI message body from a channel snapshot.
#define STASIS_MESSAGE_TYPE_CLEANUP(name)
Boiler-plate messaging macro for cleaning up message types.
Structure for a data store type.
ast_channel_state
ast_channel states
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
Structure for a data store object.
void ast_party_connected_line_free(struct ast_party_connected_line *doomed)
Destroy the connected line information contents.
struct ast_datastore * ast_channel_datastore_find(struct ast_channel *chan, const struct ast_datastore_info *info, const char *uid)
Find a datastore on a channel.
int ast_channel_move(struct ast_channel *dest, struct ast_channel *source)
Move a channel from its current location to a new location.
struct ast_manager_event_blob * ast_manager_event_blob_create(int event_flags, const char *manager_event, const char *extra_fields_fmt,...)
Construct a ast_manager_event_blob.
struct ast_channel_snapshot * ast_channel_snapshot_create(struct ast_channel *chan)
Generate a snapshot of the channel state. This is an ao2 object, so ao2_cleanup() to deallocate...
int ast_datastore_free(struct ast_datastore *datastore)
Free a data store object.
struct ast_json * ast_json_null(void)
Get the JSON null value.
static int find_channel_by_group(void *obj, void *arg, void *data, int flags)
void ast_channel_queue_connected_line_update(struct ast_channel *chan, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update)
Queue a connected line update frame on a channel.
General Asterisk PBX channel definitions.
int ast_register_cleanup(void(*func)(void))
Register a function to be executed before Asterisk gracefully exits.
#define ast_strdupa(s)
duplicate a string in memory from the stack
void ast_multi_channel_blob_add_channel(struct ast_multi_channel_blob *obj, const char *role, struct ast_channel_snapshot *snapshot)
Add a ast_channel_snapshot to a ast_multi_channel_blob object.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
#define ast_debug(level,...)
Log a DEBUG message.
struct ast_str * ast_manager_build_channel_state_string(const struct ast_channel_snapshot *snapshot)
Generate the AMI message body from a channel snapshot.
Core PBX routines and definitions.
struct ast_channel * ast_channel_callback(ao2_callback_data_fn *cb_fn, void *arg, void *data, int ao2_flags)
Call a function with every active channel.
struct stasis_topic * ast_channel_topic(struct ast_channel *chan)
A topic which publishes the events for a particular channel.
int ast_pickup_init(void)
Initialize pickup.
#define STASIS_MESSAGE_TYPE_DEFN(name,...)
Boiler-plate messaging macro for defining public message types.
struct stasis_message_type * ast_call_pickup_type(void)
accessor for call pickup message type
int ast_tvcmp(struct timeval _a, struct timeval _b)
Compress two struct timeval instances returning -1, 0, 1 if the first arg is smaller, equal or greater to the second.
Support for dynamic strings.
#define ao2_unlink(container, obj)
Remove an object from a container.
void * stasis_message_data(const struct stasis_message *msg)
Get the data contained in a message.
struct stasis_message * stasis_message_create(struct stasis_message_type *type, void *data)
Create a new message.
int ast_channel_connected_line_sub(struct ast_channel *autoservice_chan, struct ast_channel *sub_chan, const void *connected_info, int frame)
Run a connected line interception subroutine and update a channel's connected line information...
Connected Line/Party information.
void stasis_publish(struct stasis_topic *topic, struct stasis_message *message)
Publish a message to a topic's subscribers.
int ast_can_pickup(struct ast_channel *chan)
Test if a channel can be picked up.
int source
Information about the source of an update.
int ast_stream_and_wait(struct ast_channel *chan, const char *file, const char *digits)
stream file until digit If the file name is non-empty, try to play it.
int ast_do_pickup(struct ast_channel *chan, struct ast_channel *target)
Pickup a call target.
int ast_namedgroups_intersect(struct ast_namedgroups *a, struct ast_namedgroups *b)
Return TRUE if group a and b contain at least one common groupname.
int ast_pickup_call(struct ast_channel *chan)
Pickup a call.
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
static const struct ast_datastore_info pickup_active
void ast_party_connected_line_copy(struct ast_party_connected_line *dest, const struct ast_party_connected_line *src)
Copy the source connected line information to the destination connected line.
struct ast_channel_snapshot * ast_channel_snapshot_get_latest(const char *uniqueid)
Obtain the latest ast_channel_snapshot from the Stasis Message Bus API cache. This is an ao2 object...
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
void ast_connected_line_copy_from_caller(struct ast_party_connected_line *dest, const struct ast_party_caller *src)
Copy the caller information to the connected line information.
struct ast_channel_snapshot * ast_multi_channel_blob_get_channel(struct ast_multi_channel_blob *obj, const char *role)
Retrieve a channel snapshot associated with a specific role from a ast_multi_channel_blob.
A multi channel blob data structure for multi_channel_blob stasis messages.
int ast_answer(struct ast_channel *chan)
Answer a channel.
Internal Asterisk hangup causes.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
Application convenience functions, designed to give consistent look and feel to Asterisk apps...
struct ast_party_id priv
Private connected party ID.
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
int ast_channel_datastore_remove(struct ast_channel *chan, struct ast_datastore *datastore)
Remove a datastore from a channel.
struct ast_multi_channel_blob * ast_multi_channel_blob_create(struct ast_json *blob)
Create a ast_multi_channel_blob suitable for a stasis_message.
Configuration relating to call pickup.
#define ao2_link(container, obj)
Add an object to a container.