Sat Mar 10 01:54:26 2012

Asterisk developer's documentation


sig_analog.h

Go to the documentation of this file.
00001 #ifndef _SIG_ANALOG_H
00002 #define _SIG_ANALOG_H
00003 /*
00004  * Asterisk -- An open source telephony toolkit.
00005  *
00006  * Copyright (C) 1999 - 2009, Digium, Inc.
00007  *
00008  * Mark Spencer <markster@digium.com>
00009  *
00010  * See http://www.asterisk.org for more information about
00011  * the Asterisk project. Please do not directly contact
00012  * any of the maintainers of this project for assistance;
00013  * the project provides a web site, mailing lists and IRC
00014  * channels for your use.
00015  *
00016  * This program is free software, distributed under the terms of
00017  * the GNU General Public License Version 2. See the LICENSE file
00018  * at the top of the source tree.
00019  */
00020 
00021 /*! \file
00022  *
00023  * \brief Interface header for analog signaling module
00024  *
00025  * \author Matthew Fredrickson <creslin@digium.com>
00026  */
00027 
00028 #include "asterisk/channel.h"
00029 #include "asterisk/frame.h"
00030 #include "asterisk/smdi.h"
00031 
00032 #define ANALOG_SMDI_MD_WAIT_TIMEOUT 1500 /* 1.5 seconds */
00033 #define ANALOG_MAX_CID 300
00034 #define READ_SIZE 160
00035 #define RING_PATTERNS 3
00036 
00037 /* Signalling types supported */
00038 enum analog_sigtype {
00039    ANALOG_SIG_NONE = -1,
00040    ANALOG_SIG_FXOLS = 1,
00041    ANALOG_SIG_FXOKS,
00042    ANALOG_SIG_FXOGS,
00043    ANALOG_SIG_FXSLS,
00044    ANALOG_SIG_FXSKS,
00045    ANALOG_SIG_FXSGS,
00046    ANALOG_SIG_EMWINK,
00047    ANALOG_SIG_EM,
00048    ANALOG_SIG_EM_E1,
00049    ANALOG_SIG_FEATD,
00050    ANALOG_SIG_FEATDMF,
00051    ANALOG_SIG_E911,
00052    ANALOG_SIG_FGC_CAMA,
00053    ANALOG_SIG_FGC_CAMAMF,
00054    ANALOG_SIG_FEATB,
00055    ANALOG_SIG_SFWINK,
00056    ANALOG_SIG_SF,
00057    ANALOG_SIG_SF_FEATD,
00058    ANALOG_SIG_SF_FEATDMF,
00059    ANALOG_SIG_FEATDMF_TA,
00060    ANALOG_SIG_SF_FEATB,
00061 };
00062 
00063 enum analog_tone {
00064    ANALOG_TONE_RINGTONE = 0,
00065    ANALOG_TONE_STUTTER,
00066    ANALOG_TONE_CONGESTION,
00067    ANALOG_TONE_DIALTONE,
00068    ANALOG_TONE_DIALRECALL,
00069    ANALOG_TONE_INFO,
00070 };
00071 
00072 enum analog_event {
00073    ANALOG_EVENT_NONE = 0,
00074    ANALOG_EVENT_ONHOOK,
00075    ANALOG_EVENT_RINGOFFHOOK,
00076    ANALOG_EVENT_WINKFLASH,
00077    ANALOG_EVENT_ALARM,
00078    ANALOG_EVENT_NOALARM,
00079    ANALOG_EVENT_DIALCOMPLETE,
00080    ANALOG_EVENT_RINGERON,
00081    ANALOG_EVENT_RINGEROFF,
00082    ANALOG_EVENT_HOOKCOMPLETE,
00083    ANALOG_EVENT_PULSE_START,
00084    ANALOG_EVENT_POLARITY,
00085    ANALOG_EVENT_RINGBEGIN,
00086    ANALOG_EVENT_EC_DISABLED,
00087    ANALOG_EVENT_REMOVED,
00088    ANALOG_EVENT_NEONMWI_ACTIVE,
00089    ANALOG_EVENT_NEONMWI_INACTIVE,
00090    ANALOG_EVENT_TX_CED_DETECTED,
00091    ANALOG_EVENT_RX_CED_DETECTED,
00092    ANALOG_EVENT_EC_NLP_DISABLED,
00093    ANALOG_EVENT_EC_NLP_ENABLED,
00094    ANALOG_EVENT_ERROR, /* not a DAHDI event */
00095    ANALOG_EVENT_DTMFCID, /* not a DAHDI event */
00096    ANALOG_EVENT_PULSEDIGIT = (1 << 16), 
00097    ANALOG_EVENT_DTMFDOWN = (1 << 17),
00098    ANALOG_EVENT_DTMFUP = (1 << 18),
00099 };
00100 
00101 enum analog_sub {
00102    ANALOG_SUB_REAL = 0,       /*!< Active call */
00103    ANALOG_SUB_CALLWAIT,       /*!< Call-Waiting call on hold */
00104    ANALOG_SUB_THREEWAY,       /*!< Three-way call */
00105 };
00106 
00107 enum analog_dsp_digitmode {
00108    ANALOG_DIGITMODE_DTMF = 1,
00109    ANALOG_DIGITMODE_MF,
00110 };
00111 
00112 enum analog_cid_start {
00113    ANALOG_CID_START_POLARITY = 1,
00114    ANALOG_CID_START_POLARITY_IN,
00115    ANALOG_CID_START_RING,
00116    ANALOG_CID_START_DTMF_NOALERT,
00117 };
00118 
00119 enum dialop {
00120    ANALOG_DIAL_OP_REPLACE = 2,
00121 };
00122 
00123 
00124 struct analog_dialoperation {
00125    enum dialop op;
00126    char dialstr[256];
00127 };
00128 
00129 struct analog_callback {
00130    /* Unlock the private in the signalling private structure.  This is used for three way calling madness. */
00131    void (* const unlock_private)(void *pvt);
00132    /* Lock the private in the signalling private structure.  ... */
00133    void (* const lock_private)(void *pvt);
00134    /* Do deadlock avoidance for the private signaling structure lock.  */
00135    void (* const deadlock_avoidance_private)(void *pvt);
00136 
00137    /* Function which is called back to handle any other DTMF events that are received.  Called by analog_handle_event.  Why is this
00138     * important to use, instead of just directly using events received before they are passed into the library?  Because sometimes,
00139     * (CWCID) the library absorbs DTMF events received. */
00140    void (* const handle_dtmf)(void *pvt, struct ast_channel *ast, enum analog_sub analog_index, struct ast_frame **dest);
00141 
00142    int (* const get_event)(void *pvt);
00143    int (* const wait_event)(void *pvt);
00144    int (* const is_off_hook)(void *pvt);
00145    int (* const is_dialing)(void *pvt, enum analog_sub sub);
00146    /* Start a trunk type signalling protocol (everything except phone ports basically */
00147    int (* const start)(void *pvt);
00148    int (* const ring)(void *pvt);
00149    int (* const flash)(void *pvt);
00150    /*! \brief Set channel on hook */
00151    int (* const on_hook)(void *pvt);
00152    /*! \brief Set channel off hook */
00153    int (* const off_hook)(void *pvt);
00154    void (* const set_needringing)(void *pvt, int value);
00155    /*! \brief Set FXS line polarity to 0=IDLE NZ=REVERSED */
00156    void (* const set_polarity)(void *pvt, int value);
00157    /*! \brief Reset FXS line polarity to IDLE, based on answeronpolarityswitch and hanguponpolarityswitch */
00158    void (* const start_polarityswitch)(void *pvt);
00159    /*! \brief Switch FXS line polarity, based on answeronpolarityswitch=yes */
00160    void (* const answer_polarityswitch)(void *pvt);
00161    /*! \brief Switch FXS line polarity, based on answeronpolarityswitch and hanguponpolarityswitch */
00162    void (* const hangup_polarityswitch)(void *pvt);
00163    /* We're assuming that we're going to only wink on ANALOG_SUB_REAL - even though in the code there's an argument to the index
00164     * function */
00165    int (* const wink)(void *pvt, enum analog_sub sub);
00166    int (* const dial_digits)(void *pvt, enum analog_sub sub, struct analog_dialoperation *dop);
00167    int (* const send_fsk)(void *pvt, struct ast_channel *ast, char *fsk);
00168    int (* const play_tone)(void *pvt, enum analog_sub sub, enum analog_tone tone);
00169 
00170    int (* const set_echocanceller)(void *pvt, int enable);
00171    int (* const train_echocanceller)(void *pvt);
00172    int (* const dsp_set_digitmode)(void *pvt, enum analog_dsp_digitmode mode);
00173    int (* const dsp_reset_and_flush_digits)(void *pvt);
00174    int (* const send_callerid)(void *pvt, int cwcid, struct ast_party_caller *caller);
00175    /* Returns 0 if CID received.  Returns 1 if event received, and -1 if error.  name and num are size ANALOG_MAX_CID */
00176    int (* const get_callerid)(void *pvt, char *name, char *num, enum analog_event *ev, size_t timeout);
00177    /* Start CID detection */
00178    int (* const start_cid_detect)(void *pvt, int cid_signalling);
00179    /* Stop CID detection */
00180    int (* const stop_cid_detect)(void *pvt);
00181 
00182    /* Play the CAS callwait tone on the REAL sub, then repeat after 10 seconds, and then stop */
00183    int (* const callwait)(void *pvt);
00184    /* Stop playing any CAS call waiting announcement tones that might be running on the REAL sub */
00185    int (* const stop_callwait)(void *pvt);
00186 
00187    /* Bearer control related (non signalling) callbacks */
00188    int (* const allocate_sub)(void *pvt, enum analog_sub sub);
00189    int (* const unallocate_sub)(void *pvt, enum analog_sub sub);
00190    /*! This function is for swapping of the owners with the underlying subs.  Typically it means you need to change the fds
00191     * of the new owner to be the fds of the sub specified, for each of the two subs given */
00192    void (* const swap_subs)(void *pvt, enum analog_sub a, struct ast_channel *new_a_owner, enum analog_sub b, struct ast_channel *new_b_owner);
00193    struct ast_channel * (* const new_ast_channel)(void *pvt, int state, int startpbx, enum analog_sub sub, const struct ast_channel *requestor);
00194 
00195    /* Add the given sub to a conference */
00196    int (* const conf_add)(void *pvt, enum analog_sub sub);
00197    /* Delete the given sub from any conference that might be running on the channels */
00198    int (* const conf_del)(void *pvt, enum analog_sub sub);
00199 
00200    /* If you would like to do any optimizations after the conference members have been added and removed,
00201     * you can do so here */
00202    int (* const complete_conference_update)(void *pvt, int needconf);
00203 
00204    /* This is called when there are no more subchannels on the given private that are left up,
00205     * for any cleanup or whatever else you would like to do.  Called from analog_hangup() */
00206    void (* const all_subchannels_hungup)(void *pvt);
00207 
00208    int (* const has_voicemail)(void *pvt);
00209    int (* const check_for_conference)(void *pvt);
00210    void (* const handle_notify_message)(struct ast_channel *chan, void *pvt, int cid_flags, int neon_mwievent);
00211 
00212    /* callbacks for increasing and decreasing ss_thread_count, will handle locking and condition signal */
00213    void (* const increase_ss_count)(void);
00214    void (* const decrease_ss_count)(void);
00215 
00216    int (* const distinctive_ring)(struct ast_channel *chan, void *pvt, int idx, int *ringdata);
00217    /* Sets the specified sub-channel in and out of signed linear mode, returns the value that was overwritten */
00218    int (* const set_linear_mode)(void *pvt, enum analog_sub sub, int linear_mode);
00219    void (* const set_inthreeway)(void *pvt, enum analog_sub sub, int inthreeway);
00220    void (* const get_and_handle_alarms)(void *pvt);
00221    void * (* const get_sigpvt_bridged_channel)(struct ast_channel *chan);
00222    int (* const get_sub_fd)(void *pvt, enum analog_sub sub);
00223    void (* const set_cadence)(void *pvt, int *cidrings, struct ast_channel *chan);
00224    void (* const set_alarm)(void *pvt, int in_alarm);
00225    void (* const set_dialing)(void *pvt, int is_dialing);
00226    void (* const set_ringtimeout)(void *pvt, int ringt);
00227    void (* const set_waitingfordt)(void *pvt, struct ast_channel *ast);
00228    int (* const check_waitingfordt)(void *pvt);
00229    void (* const set_confirmanswer)(void *pvt, int flag);
00230    int (* const check_confirmanswer)(void *pvt);
00231    void (* const set_callwaiting)(void *pvt, int callwaiting_enable);
00232    void (* const cancel_cidspill)(void *pvt);
00233    int (* const confmute)(void *pvt, int mute); 
00234    void (* const set_pulsedial)(void *pvt, int flag);
00235    void (* const set_new_owner)(void *pvt, struct ast_channel *new_owner);
00236 
00237    const char *(* const get_orig_dialstring)(void *pvt);
00238    int (* const have_progressdetect)(void *pvt);
00239 };
00240 
00241 
00242 
00243 struct analog_subchannel {
00244    struct ast_channel *owner;
00245    struct ast_frame f;     /*!< One frame for each channel.  How did this ever work before? */
00246    unsigned int inthreeway:1;
00247    /* Have we allocated a subchannel yet or not */
00248    unsigned int allocd:1;
00249 };
00250 
00251 struct analog_pvt {
00252    /* Analog signalling type used in this private */
00253    enum analog_sigtype sig;
00254    /* To contain the private structure passed into the channel callbacks */
00255    void *chan_pvt;
00256    /* Callbacks for various functions needed by the analog API */
00257    struct analog_callback *calls;
00258    /* All members after this are giong to be transient, and most will probably change */
00259    struct ast_channel *owner;       /*!< Our current active owner (if applicable) */
00260 
00261    struct analog_subchannel subs[3];      /*!< Sub-channels */
00262    struct analog_dialoperation dop;
00263    int onhooktime;                     /*< Time the interface went on-hook. */
00264    int fxsoffhookstate;             /*< TRUE if the FXS port is off-hook */
00265    /*! \brief -1 = unknown, 0 = no messages, 1 = new messages available */
00266    int msgstate;
00267 
00268    /* XXX: Option Variables - Set by allocator of private structure */
00269    unsigned int answeronpolarityswitch:1;
00270    unsigned int callreturn:1;
00271    unsigned int cancallforward:1;
00272    unsigned int canpark:1;
00273    unsigned int dahditrcallerid:1;        /*!< should we use the callerid from incoming call on dahdi transfer or not */
00274    unsigned int hanguponpolarityswitch:1;
00275    unsigned int immediate:1;
00276    unsigned int permcallwaiting:1;        /*!< TRUE if call waiting is enabled. (Configured option) */
00277    unsigned int permhidecallerid:1;    /*!< Whether to hide our outgoing caller ID or not */
00278    unsigned int pulse:1;
00279    unsigned int threewaycalling:1;
00280    unsigned int transfer:1;
00281    unsigned int transfertobusy:1;         /*!< allow flash-transfers to busy channels */
00282    unsigned int use_callerid:1;        /*!< Whether or not to use caller id on this channel */
00283    unsigned int callwaitingcallerid:1;    /*!< TRUE if send caller ID for Call Waiting */
00284    /*!
00285     * \brief TRUE if SMDI (Simplified Message Desk Interface) is enabled
00286     */
00287    unsigned int use_smdi:1;
00288    /*! \brief The SMDI interface to get SMDI messages from. */
00289    struct ast_smdi_interface *smdi_iface;
00290    const struct ast_channel_tech *chan_tech;
00291 
00292    /* Not used for anything but log messages.  Could be just the TCID */
00293    int channel;               /*!< Channel Number */
00294 
00295    enum analog_sigtype outsigmod;
00296    int echotraining;
00297    int cid_signalling;           /*!< Asterisk callerid type we're using */
00298    int polarityonanswerdelay;
00299    int stripmsd;
00300    enum analog_cid_start cid_start;
00301    char mohsuggest[MAX_MUSICCLASS];
00302    char cid_num[AST_MAX_EXTENSION];
00303    char cid_name[AST_MAX_EXTENSION];
00304 
00305 
00306    /* XXX: All variables after this are internal */
00307    unsigned int callwaiting:1;      /*!< TRUE if call waiting is enabled. (Active option) */
00308    unsigned int dialednone:1;
00309    unsigned int dialing:1;       /*!< TRUE if in the process of dialing digits or sending something */
00310    unsigned int dnd:1;           /*!< TRUE if Do-Not-Disturb is enabled. */
00311    unsigned int echobreak:1;
00312    unsigned int hidecallerid:1;
00313    unsigned int outgoing:1;
00314    unsigned int inalarm:1;
00315    /*!
00316     * \brief TRUE if Call Waiting (CW) CPE Alert Signal (CAS) is being sent.
00317     * \note
00318     * After CAS is sent, the call waiting caller id will be sent if the phone
00319     * gives a positive reply.
00320     */
00321    unsigned int callwaitcas:1;
00322 
00323    char callwait_num[AST_MAX_EXTENSION];
00324    char callwait_name[AST_MAX_EXTENSION];
00325    char lastcid_num[AST_MAX_EXTENSION];
00326    char lastcid_name[AST_MAX_EXTENSION];
00327    struct ast_party_caller caller;
00328    int cidrings;              /*!< Which ring to deliver CID on */
00329    char echorest[20];
00330    int polarity;
00331    struct timeval polaritydelaytv;
00332    char dialdest[256];
00333    time_t guardtime;          /*!< Must wait this much time before using for new call */
00334    struct timeval flashtime;        /*!< Last flash-hook time */
00335    int whichwink;             /*!< SIG_FEATDMF_TA Which wink are we on? */
00336    char finaldial[64];
00337    char *origcid_num;            /*!< malloced original callerid */
00338    char *origcid_name;           /*!< malloced original callerid */
00339    char call_forward[AST_MAX_EXTENSION];
00340 
00341    /* Ast channel to pass to __ss_analog_thread */
00342    struct ast_channel *ss_astchan;
00343 
00344    /* All variables after this are definitely going to be audited */
00345    int ringt;
00346    int ringt_base;
00347 };
00348 
00349 struct analog_pvt *analog_new(enum analog_sigtype signallingtype, struct analog_callback *c, void *private_data);
00350 void analog_delete(struct analog_pvt *doomed);
00351 
00352 void analog_free(struct analog_pvt *p);
00353 
00354 int analog_call(struct analog_pvt *p, struct ast_channel *ast, char *rdest, int timeout);
00355 
00356 int analog_hangup(struct analog_pvt *p, struct ast_channel *ast);
00357 
00358 int analog_answer(struct analog_pvt *p, struct ast_channel *ast);
00359 
00360 struct ast_frame *analog_exception(struct analog_pvt *p, struct ast_channel *ast);
00361 
00362 struct ast_channel * analog_request(struct analog_pvt *p, int *callwait, const struct ast_channel *requestor);
00363 
00364 int analog_available(struct analog_pvt *p);
00365 
00366 void *analog_handle_init_event(struct analog_pvt *i, int event);
00367 
00368 int analog_config_complete(struct analog_pvt *p);
00369 
00370 void analog_handle_dtmf(struct analog_pvt *p, struct ast_channel *ast, enum analog_sub index, struct ast_frame **dest);
00371 
00372 enum analog_cid_start analog_str_to_cidstart(const char *value);
00373 
00374 const char *analog_cidstart_to_str(enum analog_cid_start cid_start);
00375 
00376 enum analog_sigtype analog_str_to_sigtype(const char *name);
00377 
00378 const char *analog_sigtype_to_str(enum analog_sigtype sigtype);
00379 
00380 unsigned int analog_str_to_cidtype(const char *name);
00381 
00382 const char *analog_cidtype_to_str(unsigned int cid_type);
00383 
00384 int analog_ss_thread_start(struct analog_pvt *p, struct ast_channel *ast);
00385 
00386 int analog_fixup(struct ast_channel *oldchan, struct ast_channel *newchan, void *newp);
00387 
00388 int analog_dnd(struct analog_pvt *p, int flag);
00389 
00390 #endif /* _SIG_ANSLOG_H */

Generated on Sat Mar 10 01:54:26 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7