diff options
Diffstat (limited to 'res/res_features.c')
-rw-r--r-- | res/res_features.c | 251 |
1 files changed, 228 insertions, 23 deletions
diff --git a/res/res_features.c b/res/res_features.c index df08bb971..1083948a5 100644 --- a/res/res_features.c +++ b/res/res_features.c @@ -197,7 +197,10 @@ struct ast_bridge_thread_obj -/*! \brief store context, priority and extension */ +/*! + * \brief store context, extension and priority + * \param chan, context, ext, pri +*/ static void set_c_e_p(struct ast_channel *chan, const char *context, const char *ext, int pri) { ast_copy_string(chan->context, context, sizeof(chan->context)); @@ -205,6 +208,13 @@ static void set_c_e_p(struct ast_channel *chan, const char *context, const char chan->priority = pri; } +/*! + * \brief Check goto on transfer + * \param chan + * Check if channel has 'GOTO_ON_BLINDXFR' set, if not exit. + * When found make sure the types are compatible. Check if channel is valid + * if so start the new channel else hangup the call. +*/ static void check_goto_on_transfer(struct ast_channel *chan) { struct ast_channel *xferchan; @@ -243,7 +253,13 @@ static void check_goto_on_transfer(struct ast_channel *chan) static struct ast_channel *ast_feature_request_and_dial(struct ast_channel *caller, struct ast_channel *transferee, const char *type, int format, void *data, int timeout, int *outstate, const char *cid_num, const char *cid_name, int igncallerstate); - +/*! + * \brief bridge the call + * \param data thread bridge + * Set Last Data for respective channels, reset cdr for channels + * bridge call, check if we're going back to dialplan + * if not hangup both legs of the call +*/ static void *ast_bridge_call_thread(void *data) { struct ast_bridge_thread_obj *tobj = data; @@ -290,6 +306,11 @@ static void *ast_bridge_call_thread(void *data) return NULL; } +/*! + * \brief create thread for the parked call + * \param data + * Create thread and attributes, call ast_bridge_call_thread +*/ static void ast_bridge_call_thread_launch(void *data) { pthread_t thread; @@ -304,6 +325,14 @@ static void ast_bridge_call_thread_launch(void *data) pthread_setschedparam(thread, SCHED_RR, &sched); } +/*! + * \brief Announce call parking by ADSI + * \param chan + * \param parkingexten + * Create message to show for ADSI, display message. + * \retval 0 on success. + * \retval -1 on failure. +*/ static int adsi_announce_park(struct ast_channel *chan, char *parkingexten) { int res; @@ -349,9 +378,7 @@ static enum ast_device_state metermaidstate(const char *data) return AST_DEVICE_INUSE; } -/*! \brief Park a call - \note We put the user in the parking list, then wake up the parking thread to be sure it looks - after these channels too */ +/* Park a call */ int ast_park_call(struct ast_channel *chan, struct ast_channel *peer, int timeout, int *extout) { struct parkeduser *pu, *cur; @@ -479,6 +506,7 @@ int ast_park_call(struct ast_channel *chan, struct ast_channel *peer, int timeou return 0; } +/* Park call via masquraded channel */ int ast_masq_park_call(struct ast_channel *rchan, struct ast_channel *peer, int timeout, int *extout) { struct ast_channel *chan; @@ -519,9 +547,11 @@ int ast_masq_park_call(struct ast_channel *rchan, struct ast_channel *peer, int #define FEATURE_SENSE_CHAN (1 << 0) #define FEATURE_SENSE_PEER (1 << 1) -/*! \brief - * set caller and callee according to the direction - */ +/*! + * \brief set caller and callee according to the direction + * \param caller, callee, peer, chan, sense + * Detect who triggered feature and set callee/caller variables accordingly +*/ static void set_peers(struct ast_channel **caller, struct ast_channel **callee, struct ast_channel *peer, struct ast_channel *chan, int sense) { @@ -534,7 +564,16 @@ static void set_peers(struct ast_channel **caller, struct ast_channel **callee, } } -/*! \brief support routing for one touch call parking */ +/*! + * \brief support routing for one touch call parking + * \param chan channel parking call + * \param peer channel to be parked + * \param config unsed + * \param code unused + * \param sense feature options + * Setup channel, set return exten,priority to 's,1' + * answer chan, sleep chan, park call +*/ static int builtin_parkcall(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense) { struct ast_channel *parker; @@ -568,6 +607,18 @@ static int builtin_parkcall(struct ast_channel *chan, struct ast_channel *peer, } +/*! + * \brief Monitor a channel by DTMF + * \param chan channel requesting monitor + * \param peer channel to be monitored + * \param config + * \param code + * \param sense + * Check monitor app enabled, setup channels, both caller/callee chans not null + * get TOUCH_MONITOR variable for filename if exists, exec monitor app. + * \retval FEATURE_RETURN_SUCCESS on success. + * \retval -1 on error. +*/ static int builtin_automonitor(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense) { char *caller_chan_id = NULL, *callee_chan_id = NULL, *args = NULL, *touch_filename = NULL; @@ -663,7 +714,13 @@ static int finishup(struct ast_channel *chan) return ast_autoservice_stop(chan); } -/*! \brief Find the context for the transfer */ +/*! + * \brief Find the context for the transfer + * \param transferer + * \param transferee + * Grab the TRANSFER_CONTEXT, if fails try grabbing macrocontext. + * \return a context string +*/ static const char *real_ctx(struct ast_channel *transferer, struct ast_channel *transferee) { const char *s = pbx_builtin_getvar_helper(transferer, "TRANSFER_CONTEXT"); @@ -676,6 +733,18 @@ static const char *real_ctx(struct ast_channel *transferer, struct ast_channel * return s; } +/*! + * \brief Blind transfer user to another extension + * \param chan channel initiated blind transfer + * \param peer channel to be transfered + * \param config + * \param code + * \param sense + * Place peer on hold, check if tranfered to parkinglot extension, + * otherwise check extension exists and transfer caller. + * \retval FEATURE_RETURN_SUCCESS. + * \retval -1 on failure. +*/ static int builtin_blindtransfer(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense) { struct ast_channel *transferer; @@ -763,6 +832,13 @@ static int builtin_blindtransfer(struct ast_channel *chan, struct ast_channel *p return FEATURE_RETURN_SUCCESS; } +/*! + * \brief make channels compatible + * \param c + * \param newchan + * \retval 0 on success. + * \retval -1 on failure. +*/ static int check_compat(struct ast_channel *c, struct ast_channel *newchan) { if (ast_channel_make_compatible(c, newchan) < 0) { @@ -774,6 +850,18 @@ static int check_compat(struct ast_channel *c, struct ast_channel *newchan) return 0; } +/*! + * \brief Attended transfer + * \param chan + * \param peer + * \param config + * \param code + * \param sense + * Get extension to transfer to, if you cannot generate channel (or find extension) + * return to host channel. After called channel answered wait for hangup of transferer, + * bridge call between transfer peer (taking them off hold) to attended transfer channel. + * \return -1 means what failure/success both? +*/ static int builtin_atxfer(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense) { struct ast_channel *transferer; @@ -1034,7 +1122,12 @@ void ast_register_feature(struct ast_call_feature *feature) ast_verb(2, "Registered Feature '%s'\n",feature->sname); } -/*! \brief This function must be called while feature_groups is locked... */ +/*! + * \brief Add new feature group + * \param fgname feature group name + * Add new feature group to the feature group list insert at head of list. + * \note This function MUST be called while feature_groups is locked. +*/ static struct feature_group* register_group(const char *fgname) { struct feature_group *fg; @@ -1061,8 +1154,14 @@ static struct feature_group* register_group(const char *fgname) return fg; } -/*! \brief This function must be called while feature_groups is locked... */ - +/*! + * \brief Add feature to group + * \param fg feature group + * \param exten + * \param feature feature to add + * Check fg and feature specified, add feature to list + * \note This function MUST be called while feature_groups is locked. +*/ static void register_group_feature(struct feature_group *fg, const char *exten, struct ast_call_feature *feature) { struct feature_group_exten *fge; @@ -1095,7 +1194,6 @@ static void register_group_feature(struct feature_group *fg, const char *exten, feature->sname, fg->gname, exten); } -/*! \brief unregister feature from feature_list */ void ast_unregister_feature(struct ast_call_feature *feature) { if (!feature) @@ -1131,7 +1229,7 @@ static struct ast_call_feature *find_dynamic_feature(const char *name) return tmp; } -/*! \brief Remove all groups in the list */ +/*! \brief Remove all feature groups in the list */ static void ast_unregister_groups(void) { struct feature_group *fg; @@ -1150,7 +1248,12 @@ static void ast_unregister_groups(void) AST_RWLIST_UNLOCK(&feature_groups); } -/*! \brief Find a group by name */ +/*! + * \brief Find a group by name + * \param name feature name + * \retval feature group on success. + * \retval NULL on failure. +*/ static struct feature_group *find_group(const char *name) { struct feature_group *fg = NULL; @@ -1162,6 +1265,12 @@ static struct feature_group *find_group(const char *name) { return fg; } +/*! + * \brief Find a feature extension + * \param fg, code + * \retval feature group extension on success. + * \retval NULL on failure. +*/ static struct feature_group_exten *find_group_exten(struct feature_group *fg, const char *code) { struct feature_group_exten *fge = NULL; @@ -1183,7 +1292,6 @@ void ast_unlock_call_features(void) ast_rwlock_unlock(&features_lock); } -/*! \brief find a call feature by name */ struct ast_call_feature *ast_find_call_feature(const char *name) { int x; @@ -1194,7 +1302,14 @@ struct ast_call_feature *ast_find_call_feature(const char *name) return NULL; } -/*! \brief exec an app by feature */ +/*! + * \brief exec an app by feature + * \param chan,peer,config,code,sense + * Find a feature, determine which channel activated + * \retval FEATURE_RETURN_PBX_KEEPALIVE,FEATURE_RETURN_NO_HANGUP_PEER + * \retval -1 error. + * \retval -2 when an application cannot be found. +*/ static int feature_exec_app(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense) { struct ast_app *app; @@ -1291,6 +1406,13 @@ static int remap_feature(const char *name, const char *value) return res; } +/*! + * \brief Check the dynamic features + * \param chan,peer,config,code,sense + * Lock features list, browse for code, unlock list + * \retval res on success. + * \retval -1 on failure. +*/ static int ast_feature_interpret(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense) { int x; @@ -1405,7 +1527,15 @@ static void set_config_flags(struct ast_channel *chan, struct ast_channel *peer, } } -/*! \todo XXX Check - this is very similar to the code in channel.c */ +/*! + * \brief + * \param caller,transferee,type,format,data,timeout,outstate,cid_num,cid_name,igncallerstate + * Request channel, set channel variables, initiate call,check if they want to disconnect + * go into loop, check if timeout has elapsed, check if person to be transfered hung up, + * check for answer break loop, set cdr return channel. + * \todo XXX Check - this is very similar to the code in channel.c + * \return always a channel +*/ static struct ast_channel *ast_feature_request_and_dial(struct ast_channel *caller, struct ast_channel *transferee, const char *type, int format, void *data, int timeout, int *outstate, const char *cid_num, const char *cid_name, int igncallerstate) { int state = 0; @@ -1587,6 +1717,14 @@ static struct ast_channel *ast_feature_request_and_dial(struct ast_channel *call return chan; } +/*! + * \brief bridge the call and set CDR + * \param chan,peer,config + * Set start time, check for two channels,check if monitor on + * check for feature activation, create new CDR + * \retval res on success. + * \retval -1 on failure to bridge. +*/ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast_bridge_config *config) { /* Copy voice back and forth between the two channels. Give the peer @@ -1878,7 +2016,13 @@ static void post_manager_event(const char *s, struct parkeduser *pu) ); } -/*! \brief Take care of parked calls and unpark them if needed */ +/*! + * \brief Take care of parked calls and unpark them if needed + * \param ignore unused var + * Start inf loop, lock parking lot, check if any parked channels have gone above timeout + * if so, remove channel from parking lot and return it to the extension that parked it. + * Check if parked channel decided to hangup, wait until next FD via select(). +*/ static void *do_parking_thread(void *ignore) { char parkingslot[AST_MAX_EXTENSION]; @@ -2240,6 +2384,13 @@ static char mandescr_bridge[] = " Tone: (Yes|No) Play courtesy tone to Channel 2\n" "\n"; +/*! + * \brief Actual bridge + * \param chan + * \param tmpchan + * Stop hold music, lock both channels, masq channels, + * after bridge return channel to next priority. +*/ static void do_bridge_masquerade(struct ast_channel *chan, struct ast_channel *tmpchan) { ast_moh_stop(chan); @@ -2256,6 +2407,18 @@ static void do_bridge_masquerade(struct ast_channel *chan, struct ast_channel *t ast_mutex_unlock(&chan->lock); } +/*! + * \brief Bridge channels together + * \param s + * \param m + * Make sure valid channels were specified, + * send errors if any of the channels could not be found/locked, answer channels if needed, + * create the placeholder channels and grab the other channels + * make the channels compatible, send error if we fail doing so + * setup the bridge thread object and start the bridge. + * \retval 0 on success or on incorrect use. + * \retval 1 on failure to bridge channels. +*/ static int action_bridge(struct mansession *s, const struct message *m) { const char *channela = astman_get_header(m, "Channel1"); @@ -2355,6 +2518,16 @@ static char showfeatures_help[] = "Usage: feature list\n" " Lists currently configured features.\n"; +/*! + * \brief CLI command to list parked calls + * \param e + * \param cmd + * \param a + * Check right usage, lock parking lot, display parked calls, unlock parking lot list. + * \retval CLI_SUCCESS on success. + * \retval CLI_SHOWUSAGE on incorrect number of arguements. + * \retval NULL when tab completion is used. +*/ static char *handle_parkedcalls(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { struct parkeduser *cur; @@ -2410,7 +2583,13 @@ static struct ast_cli_entry cli_features[] = { NEW_CLI(handle_parkedcalls, "List currently parked calls", .deprecate_cmd = &cli_show_parkedcalls_deprecated), }; -/*! \brief Dump lot status */ +/*! + * \brief Dump parking lot status + * \param s + * \param m + * Lock parking lot, iterate list and append parked calls status, unlock parking lot. + * \return Always RESULT_SUCCESS +*/ static int manager_parking_status(struct mansession *s, const struct message *m) { struct parkeduser *cur; @@ -2458,6 +2637,13 @@ static char mandescr_park[] = " *Channel2: Channel to announce park info to (and return to if timeout)\n" " Timeout: Number of milliseconds to wait before callback.\n"; +/*! + * \brief Create manager event for parked calls + * \param s + * \param m + * Get channels involved in park, create event. + * \return Always 0 +*/ static int manager_park(struct mansession *s, const struct message *m) { const char *channel = astman_get_header(m, "Channel"); @@ -2512,7 +2698,13 @@ static int manager_park(struct mansession *s, const struct message *m) return 0; } - +/*! + * \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 *cur = NULL; @@ -2546,7 +2738,12 @@ int ast_pickup_call(struct ast_channel *chan) return res; } -/*! \brief Add parking hints for all defined parking lots */ +/*! + * \brief Add parking hints for all defined parking lots + * \param context + * \param start starting parkinglot number + * \param stop ending parkinglot number +*/ static void park_add_hints(char *context, int start, int stop) { int numext; @@ -2868,6 +3065,14 @@ AST_APP_OPTIONS(bridge_exec_options, BEGIN_OPTIONS AST_APP_OPTION('p', BRIDGE_OPT_PLAYTONE) END_OPTIONS ); +/*! + * \brief Bridge channels + * \param chan + * \param data channel to bridge with + * Split data, check we aren't bridging with ourself, check valid channel, + * answer call if not already, check compatible channels, setup bridge config + * now bridge call, if transfered party hangs up return to PBX extension. +*/ static int bridge_exec(struct ast_channel *chan, void *data) { struct ast_module_user *u; |