Sat Aug 6 00:39:55 2011

Asterisk developer's documentation


dial.h File Reference

Dialing API. More...

Go to the source code of this file.

Typedefs

typedef void(*) ast_dial_state_callback (struct ast_dial *)

Enumerations

enum  ast_dial_option { AST_DIAL_OPTION_RINGING, AST_DIAL_OPTION_ANSWER_EXEC, AST_DIAL_OPTION_MAX }
 List of options that are applicable either globally or per dialed channel. More...
enum  ast_dial_result {
  AST_DIAL_RESULT_INVALID, AST_DIAL_RESULT_FAILED, AST_DIAL_RESULT_TRYING, AST_DIAL_RESULT_RINGING,
  AST_DIAL_RESULT_PROGRESS, AST_DIAL_RESULT_PROCEEDING, AST_DIAL_RESULT_ANSWERED, AST_DIAL_RESULT_TIMEOUT,
  AST_DIAL_RESULT_HANGUP, AST_DIAL_RESULT_UNANSWERED
}
 List of return codes for dial run API calls. More...

Functions

ast_channelast_dial_answered (struct ast_dial *dial)
 Return channel that answered.
int ast_dial_append (struct ast_dial *dial, const char *tech, const char *device)
 Append a channel.
ast_dialast_dial_create (void)
 New dialing structure.
int ast_dial_destroy (struct ast_dial *dial)
 Destroys a dialing structure.
void ast_dial_hangup (struct ast_dial *dial)
 Hangup channels.
enum ast_dial_result ast_dial_join (struct ast_dial *dial)
 Cancel async thread.
int ast_dial_option_disable (struct ast_dial *dial, int num, enum ast_dial_option option)
 Disables an option per channel.
int ast_dial_option_enable (struct ast_dial *dial, int num, enum ast_dial_option option, void *data)
 Enables an option per channel.
int ast_dial_option_global_disable (struct ast_dial *dial, enum ast_dial_option option)
 Disables an option globally.
int ast_dial_option_global_enable (struct ast_dial *dial, enum ast_dial_option option, void *data)
 Enables an option globally.
enum ast_dial_result ast_dial_run (struct ast_dial *dial, struct ast_channel *chan, int async)
 Execute dialing synchronously or asynchronously.
void ast_dial_set_state_callback (struct ast_dial *dial, ast_dial_state_callback callback)
 Set a callback for state changes.
enum ast_dial_result ast_dial_state (struct ast_dial *dial)
 Return state of dial.


Detailed Description

Dialing API.

Definition in file dial.h.


Typedef Documentation

typedef void(*) ast_dial_state_callback(struct ast_dial *)

Definition at line 36 of file dial.h.


Enumeration Type Documentation

enum ast_dial_option

List of options that are applicable either globally or per dialed channel.

Enumerator:
AST_DIAL_OPTION_RINGING  Always indicate ringing to caller
AST_DIAL_OPTION_ANSWER_EXEC  Execute application upon answer in async mode
AST_DIAL_OPTION_MAX  End terminator -- must always remain last

Definition at line 39 of file dial.h.

00039                      {
00040    AST_DIAL_OPTION_RINGING,     /*!< Always indicate ringing to caller */
00041    AST_DIAL_OPTION_ANSWER_EXEC, /*!< Execute application upon answer in async mode */
00042    AST_DIAL_OPTION_MAX,         /*!< End terminator -- must always remain last */
00043 };

enum ast_dial_result

List of return codes for dial run API calls.

Enumerator:
AST_DIAL_RESULT_INVALID  Invalid options were passed to run function
AST_DIAL_RESULT_FAILED  Attempts to dial failed before reaching critical state
AST_DIAL_RESULT_TRYING  Currently trying to dial
AST_DIAL_RESULT_RINGING  Dial is presently ringing
AST_DIAL_RESULT_PROGRESS  Dial is presently progressing
AST_DIAL_RESULT_PROCEEDING  Dial is presently proceeding
AST_DIAL_RESULT_ANSWERED  A channel was answered
AST_DIAL_RESULT_TIMEOUT  Timeout was tripped, nobody answered
AST_DIAL_RESULT_HANGUP  Caller hung up
AST_DIAL_RESULT_UNANSWERED  Nobody answered

Definition at line 46 of file dial.h.

00046                      {
00047    AST_DIAL_RESULT_INVALID,     /*!< Invalid options were passed to run function */
00048    AST_DIAL_RESULT_FAILED,      /*!< Attempts to dial failed before reaching critical state */
00049    AST_DIAL_RESULT_TRYING,      /*!< Currently trying to dial */
00050    AST_DIAL_RESULT_RINGING,     /*!< Dial is presently ringing */
00051    AST_DIAL_RESULT_PROGRESS,    /*!< Dial is presently progressing */
00052    AST_DIAL_RESULT_PROCEEDING,  /*!< Dial is presently proceeding */
00053    AST_DIAL_RESULT_ANSWERED,    /*!< A channel was answered */
00054    AST_DIAL_RESULT_TIMEOUT,     /*!< Timeout was tripped, nobody answered */
00055    AST_DIAL_RESULT_HANGUP,      /*!< Caller hung up */
00056    AST_DIAL_RESULT_UNANSWERED,  /*!< Nobody answered */
00057 };


Function Documentation

struct ast_channel* ast_dial_answered ( struct ast_dial dial  ) 

Return channel that answered.

Note:
Returns the Asterisk channel that answered
Parameters:
dial Dialing structure

Definition at line 619 of file dial.c.

References AST_DIAL_RESULT_ANSWERED, AST_LIST_FIRST, ast_dial::channels, and ast_dial::state.

Referenced by dial_trunk(), and sla_handle_dial_state_event().

00620 {
00621    if (!dial)
00622       return NULL;
00623 
00624    return ((dial->state == AST_DIAL_RESULT_ANSWERED) ? AST_LIST_FIRST(&dial->channels)->owner : NULL);
00625 }

int ast_dial_append ( struct ast_dial dial,
const char *  tech,
const char *  device 
)

Append a channel.

Note:
Appends a channel to a dialing structure
Returns:
Returns channel reference number on success, -1 on failure

Definition at line 207 of file dial.c.

References ast_atomic_fetchadd_int(), ast_calloc, AST_LIST_INSERT_TAIL, ast_dial::channels, ast_dial_channel::list, and ast_dial::num.

Referenced by dial_trunk(), page_exec(), and sla_ring_station().

00208 {
00209    struct ast_dial_channel *channel = NULL;
00210 
00211    /* Make sure we have required arguments */
00212    if (!dial || !tech || !device)
00213       return -1;
00214 
00215    /* Allocate new memory for dialed channel structure */
00216    if (!(channel = ast_calloc(1, sizeof(*channel))))
00217       return -1;
00218 
00219    /* Record technology and device for when we actually dial */
00220    channel->tech = tech;
00221    channel->device = device;
00222 
00223    /* Grab reference number from dial structure */
00224    channel->num = ast_atomic_fetchadd_int(&dial->num, +1);
00225 
00226    /* Insert into channels list */
00227    AST_LIST_INSERT_TAIL(&dial->channels, channel, list);
00228 
00229    return channel->num;
00230 }

struct ast_dial* ast_dial_create ( void   ) 

New dialing structure.

Note:
Create a dialing structure
Returns:
Returns a calloc'd ast_dial structure, NULL on failure

Definition at line 183 of file dial.c.

References ast_calloc, AST_LIST_HEAD_INIT, ast_mutex_init(), and AST_PTHREADT_NULL.

Referenced by dial_trunk(), page_exec(), and sla_ring_station().

00184 {
00185    struct ast_dial *dial = NULL;
00186 
00187    /* Allocate new memory for structure */
00188    if (!(dial = ast_calloc(1, sizeof(*dial))))
00189       return NULL;
00190 
00191    /* Initialize list of channels */
00192    AST_LIST_HEAD_INIT(&dial->channels);
00193 
00194    /* Initialize thread to NULL */
00195    dial->thread = AST_PTHREADT_NULL;
00196 
00197    /* Can't forget about the lock */
00198    ast_mutex_init(&dial->lock);
00199 
00200    return dial;
00201 }

int ast_dial_destroy ( struct ast_dial dial  ) 

Destroys a dialing structure.

Note:
Destroys (free's) the given ast_dial structure
Parameters:
dial Dialing structure to free
Returns:
Returns 0 on success, -1 on failure

Definition at line 712 of file dial.c.

References AST_DIAL_OPTION_MAX, ast_hangup(), AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, ast_dial::channels, free, ast_dial_channel::list, option_types, ast_dial_channel::options, and ast_dial_channel::owner.

Referenced by dial_trunk(), page_exec(), run_station(), sla_hangup_stations(), sla_ring_station(), and sla_stop_ringing_station().

00713 {
00714    int i = 0;
00715    struct ast_dial_channel *channel = NULL;
00716 
00717    if (!dial)
00718       return -1;
00719    
00720    /* Hangup and deallocate all the dialed channels */
00721    AST_LIST_LOCK(&dial->channels);
00722    AST_LIST_TRAVERSE_SAFE_BEGIN(&dial->channels, channel, list) {
00723       /* Disable any enabled options */
00724       for (i = 0; i < AST_DIAL_OPTION_MAX; i++) {
00725          if (!channel->options[i])
00726             continue;
00727          if (option_types[i].disable)
00728             option_types[i].disable(channel->options[i]);
00729          channel->options[i] = NULL;
00730       }
00731       /* Hang up channel if need be */
00732       if (channel->owner) {
00733          ast_hangup(channel->owner);
00734          channel->owner = NULL;
00735       }
00736       /* Free structure */
00737       AST_LIST_REMOVE_CURRENT(&dial->channels, list);
00738       free(channel);
00739    }
00740    AST_LIST_TRAVERSE_SAFE_END;
00741    AST_LIST_UNLOCK(&dial->channels);
00742        
00743    /* Disable any enabled options globally */
00744    for (i = 0; i < AST_DIAL_OPTION_MAX; i++) {
00745       if (!dial->options[i])
00746          continue;
00747       if (option_types[i].disable)
00748          option_types[i].disable(dial->options[i]);
00749       dial->options[i] = NULL;
00750    }
00751 
00752    /* Lock be gone! */
00753    ast_mutex_destroy(&dial->lock);
00754 
00755    /* Free structure */
00756    free(dial);
00757 
00758    return 0;
00759 }

void ast_dial_hangup ( struct ast_dial dial  ) 

Hangup channels.

Note:
Hangup all active channels
Parameters:
dial Dialing structure

Definition at line 688 of file dial.c.

References ast_hangup(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_dial::channels, ast_dial_channel::list, and ast_dial_channel::owner.

Referenced by ast_dial_run(), and page_exec().

00689 {
00690    struct ast_dial_channel *channel = NULL;
00691 
00692    if (!dial)
00693       return;
00694    
00695    AST_LIST_LOCK(&dial->channels);
00696    AST_LIST_TRAVERSE(&dial->channels, channel, list) {
00697       if (channel->owner) {
00698          ast_hangup(channel->owner);
00699          channel->owner = NULL;
00700       }
00701    }
00702    AST_LIST_UNLOCK(&dial->channels);
00703 
00704    return;
00705 }

enum ast_dial_result ast_dial_join ( struct ast_dial dial  ) 

Cancel async thread.

Note:
Cancel a running async thread
Parameters:
dial Dialing structure

Definition at line 640 of file dial.c.

References ast_channel_lock, ast_channel_unlock, AST_DIAL_RESULT_FAILED, AST_LIST_FIRST, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_mutex_lock(), ast_mutex_unlock(), AST_PTHREADT_NULL, AST_PTHREADT_STOP, ast_softhangup(), AST_SOFTHANGUP_EXPLICIT, ast_dial::channels, ast_dial::lock, ast_dial::state, and ast_dial::thread.

Referenced by dial_trunk(), page_exec(), run_station(), sla_hangup_stations(), sla_ring_station(), and sla_stop_ringing_station().

00641 {
00642    pthread_t thread;
00643 
00644    /* If the dial structure is not running in async, return failed */
00645    if (dial->thread == AST_PTHREADT_NULL)
00646       return AST_DIAL_RESULT_FAILED;
00647 
00648    /* Record thread */
00649    thread = dial->thread;
00650 
00651    /* Boom, commence locking */
00652    ast_mutex_lock(&dial->lock);
00653 
00654    /* Stop the thread */
00655    dial->thread = AST_PTHREADT_STOP;
00656 
00657    /* If the answered channel is running an application we have to soft hangup it, can't just poke the thread */
00658    AST_LIST_LOCK(&dial->channels);
00659    if (AST_LIST_FIRST(&dial->channels)->is_running_app) {
00660       struct ast_channel *chan = AST_LIST_FIRST(&dial->channels)->owner;
00661       if (chan) {
00662          ast_channel_lock(chan);
00663          ast_softhangup(chan, AST_SOFTHANGUP_EXPLICIT);
00664          ast_channel_unlock(chan);
00665       }
00666    } else {
00667       /* Now we signal it with SIGURG so it will break out of it's waitfor */
00668       pthread_kill(thread, SIGURG);
00669    }
00670    AST_LIST_UNLOCK(&dial->channels);
00671 
00672    /* Yay done with it */
00673    ast_mutex_unlock(&dial->lock);
00674 
00675    /* Finally wait for the thread to exit */
00676    pthread_join(thread, NULL);
00677 
00678    /* Yay thread is all gone */
00679    dial->thread = AST_PTHREADT_NULL;
00680 
00681    return dial->state;
00682 }

int ast_dial_option_disable ( struct ast_dial dial,
int  num,
enum ast_dial_option  option 
)

Disables an option per channel.

Parameters:
dial Dial structure
num Channel number to disable option on
option Option to disable
Returns:
Returns 0 on success, -1 on failure

Definition at line 853 of file dial.c.

References AST_LIST_EMPTY, AST_LIST_LAST, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_dial::channels, ast_option_types::disable, ast_dial_channel::list, ast_dial_channel::num, option_types, and ast_dial_channel::options.

00854 {
00855    struct ast_dial_channel *channel = NULL;
00856 
00857    /* Ensure we have required arguments */
00858    if (!dial || AST_LIST_EMPTY(&dial->channels))
00859       return -1;
00860 
00861    /* Look for channel, we can sort of cheat and predict things - the last channel in the list will probably be what they want */
00862    AST_LIST_LOCK(&dial->channels);
00863    if (AST_LIST_LAST(&dial->channels)->num != num) {
00864       AST_LIST_TRAVERSE(&dial->channels, channel, list) {
00865          if (channel->num == num)
00866             break;
00867       }
00868    } else {
00869       channel = AST_LIST_LAST(&dial->channels);
00870    }
00871    AST_LIST_UNLOCK(&dial->channels);
00872 
00873    /* If none found, return failure */
00874    if (!channel)
00875       return -1;
00876 
00877    /* If the option is not enabled, return failure */
00878    if (!channel->options[option])
00879       return -1;
00880 
00881    /* Execute callback of option to disable it if it exists */
00882    if (option_types[option].disable)
00883       option_types[option].disable(channel->options[option]);
00884 
00885    /* Finally disable the option on the structure */
00886    channel->options[option] = NULL;
00887 
00888    return 0;
00889 }

int ast_dial_option_enable ( struct ast_dial dial,
int  num,
enum ast_dial_option  option,
void *  data 
)

Enables an option per channel.

Parameters:
dial Dial structure
num Channel number to enable option on
option Option to enable
data Data to pass to this option (not always needed)
Returns:
Returns 0 on success, -1 on failure

Definition at line 789 of file dial.c.

References AST_LIST_EMPTY, AST_LIST_LAST, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_dial::channels, ast_option_types::enable, ast_dial_channel::list, ast_dial_channel::num, option_types, and ast_dial_channel::options.

00790 {
00791    struct ast_dial_channel *channel = NULL;
00792 
00793    /* Ensure we have required arguments */
00794    if (!dial || AST_LIST_EMPTY(&dial->channels))
00795       return -1;
00796    
00797    /* Look for channel, we can sort of cheat and predict things - the last channel in the list will probably be what they want */
00798    AST_LIST_LOCK(&dial->channels);
00799    if (AST_LIST_LAST(&dial->channels)->num != num) {
00800       AST_LIST_TRAVERSE(&dial->channels, channel, list) {
00801          if (channel->num == num)
00802             break;
00803       }
00804    } else {
00805       channel = AST_LIST_LAST(&dial->channels);
00806    }
00807    AST_LIST_UNLOCK(&dial->channels);
00808 
00809    /* If none found, return failure */
00810    if (!channel)
00811       return -1;
00812 
00813    /* If the option is already enabled, return failure */
00814    if (channel->options[option])
00815       return -1;
00816 
00817         /* Execute enable callback if it exists, if not simply make sure the value is set */
00818    if (option_types[option].enable)
00819       channel->options[option] = option_types[option].enable(data);
00820    else
00821       channel->options[option] = (void*)1;
00822 
00823    return 0;
00824 }

int ast_dial_option_global_disable ( struct ast_dial dial,
enum ast_dial_option  option 
)

Disables an option globally.

Parameters:
dial Dial structure to disable option on
option Option to disable
Returns:
Returns 0 on success, -1 on failure

Definition at line 831 of file dial.c.

References ast_option_types::disable, option_types, and ast_dial::options.

00832 {
00833         /* If the option is not enabled, return failure */
00834         if (!dial->options[option])
00835                 return -1;
00836 
00837    /* Execute callback of option to disable if it exists */
00838    if (option_types[option].disable)
00839       option_types[option].disable(dial->options[option]);
00840 
00841    /* Finally disable option on the structure */
00842    dial->options[option] = NULL;
00843 
00844         return 0;
00845 }

int ast_dial_option_global_enable ( struct ast_dial dial,
enum ast_dial_option  option,
void *  data 
)

Enables an option globally.

Parameters:
dial Dial structure to enable option on
option Option to enable
data Data to pass to this option (not always needed)
Returns:
Returns 0 on success, -1 on failure

Definition at line 767 of file dial.c.

References ast_option_types::enable, option_types, and ast_dial::options.

Referenced by page_exec().

00768 {
00769    /* If the option is already enabled, return failure */
00770    if (dial->options[option])
00771       return -1;
00772 
00773    /* Execute enable callback if it exists, if not simply make sure the value is set */
00774    if (option_types[option].enable)
00775       dial->options[option] = option_types[option].enable(data);
00776    else
00777       dial->options[option] = (void*)1;
00778 
00779    return 0;
00780 }

enum ast_dial_result ast_dial_run ( struct ast_dial dial,
struct ast_channel chan,
int  async 
)

Execute dialing synchronously or asynchronously.

Note:
Dials channels in a dial structure.
Returns:
Returns dial result code. (TRYING/INVALID/FAILED/ANSWERED/TIMEOUT/UNANSWERED).

Definition at line 579 of file dial.c.

References ast_dial_hangup(), AST_DIAL_RESULT_FAILED, AST_DIAL_RESULT_INVALID, AST_DIAL_RESULT_TRYING, AST_LIST_EMPTY, ast_log(), ast_pthread_create, async_dial(), begin_dial(), ast_dial::channels, LOG_DEBUG, monitor_dial(), ast_dial::state, and ast_dial::thread.

Referenced by dial_trunk(), page_exec(), and sla_ring_station().

00580 {
00581    enum ast_dial_result res = AST_DIAL_RESULT_TRYING;
00582 
00583    /* Ensure required arguments are passed */
00584    if (!dial || (!chan && !async)) {
00585       ast_log(LOG_DEBUG, "invalid #1\n");
00586       return AST_DIAL_RESULT_INVALID;
00587    }
00588 
00589    /* If there are no channels to dial we can't very well try to dial them */
00590    if (AST_LIST_EMPTY(&dial->channels)) {
00591       ast_log(LOG_DEBUG, "invalid #2\n");
00592       return AST_DIAL_RESULT_INVALID;
00593    }
00594 
00595    /* Dial each requested channel */
00596    if (!begin_dial(dial, chan))
00597       return AST_DIAL_RESULT_FAILED;
00598 
00599    /* If we are running async spawn a thread and send it away... otherwise block here */
00600    if (async) {
00601       dial->state = AST_DIAL_RESULT_TRYING;
00602       /* Try to create a thread */
00603       if (ast_pthread_create(&dial->thread, NULL, async_dial, dial)) {
00604          /* Failed to create the thread - hangup all dialed channels and return failed */
00605          ast_dial_hangup(dial);
00606          res = AST_DIAL_RESULT_FAILED;
00607       }
00608    } else {
00609       res = monitor_dial(dial, chan);
00610    }
00611 
00612    return res;
00613 }

void ast_dial_set_state_callback ( struct ast_dial dial,
ast_dial_state_callback  callback 
)

Set a callback for state changes.

Parameters:
dial The dial structure to watch for state changes
callback the callback
Returns:
nothing

Definition at line 891 of file dial.c.

References ast_dial::state_callback.

Referenced by sla_ring_station().

00892 {
00893    dial->state_callback = callback;
00894 }

enum ast_dial_result ast_dial_state ( struct ast_dial dial  ) 

Return state of dial.

Note:
Returns the state of the dial attempt
Parameters:
dial Dialing structure

Definition at line 631 of file dial.c.

References ast_dial::state.

Referenced by dial_trunk(), and sla_handle_dial_state_event().

00632 {
00633    return dial->state;
00634 }


Generated on Sat Aug 6 00:39:55 2011 for Asterisk - the Open Source PBX by  doxygen 1.4.7