Wed Apr 6 11:29:47 2011

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 };
00239 
00240 
00241 
00242 struct analog_subchannel {
00243    struct ast_channel *owner;
00244    struct ast_frame f;     /*!< One frame for each channel.  How did this ever work before? */
00245    unsigned int inthreeway:1;
00246    /* Have we allocated a subchannel yet or not */
00247    unsigned int allocd:1;
00248 };
00249 
00250 struct analog_pvt {
00251    /* Analog signalling type used in this private */
00252    enum analog_sigtype sig;
00253    /* To contain the private structure passed into the channel callbacks */
00254    void *chan_pvt;
00255    /* Callbacks for various functions needed by the analog API */
00256    struct analog_callback *calls;
00257    /* All members after this are giong to be transient, and most will probably change */
00258    struct ast_channel *owner;       /*!< Our current active owner (if applicable) */
00259 
00260    struct analog_subchannel subs[3];      /*!< Sub-channels */
00261    struct analog_dialoperation dop;
00262    int onhooktime;                     /*< Time the interface went on-hook. */
00263    int fxsoffhookstate;             /*< TRUE if the FXS port is off-hook */
00264    /*! \brief -1 = unknown, 0 = no messages, 1 = new messages available */
00265    int msgstate;
00266 
00267    /* XXX: Option Variables - Set by allocator of private structure */
00268    unsigned int answeronpolarityswitch:1;
00269    unsigned int callreturn:1;
00270    unsigned int cancallforward:1;
00271    unsigned int canpark:1;
00272    unsigned int dahditrcallerid:1;        /*!< should we use the callerid from incoming call on dahdi transfer or not */
00273    unsigned int hanguponpolarityswitch:1;
00274    unsigned int immediate:1;
00275    unsigned int permcallwaiting:1;        /*!< TRUE if call waiting is enabled. (Configured option) */
00276    unsigned int permhidecallerid:1;    /*!< Whether to hide our outgoing caller ID or not */
00277    unsigned int pulse:1;
00278    unsigned int threewaycalling:1;
00279    unsigned int transfer:1;
00280    unsigned int transfertobusy:1;         /*!< allow flash-transfers to busy channels */
00281    unsigned int use_callerid:1;        /*!< Whether or not to use caller id on this channel */
00282    unsigned int callwaitingcallerid:1;    /*!< TRUE if send caller ID for Call Waiting */
00283    /*!
00284     * \brief TRUE if SMDI (Simplified Message Desk Interface) is enabled
00285     */
00286    unsigned int use_smdi:1;
00287    /*! \brief The SMDI interface to get SMDI messages from. */
00288    struct ast_smdi_interface *smdi_iface;
00289    const struct ast_channel_tech *chan_tech;
00290 
00291    /* Not used for anything but log messages.  Could be just the TCID */
00292    int channel;               /*!< Channel Number */
00293 
00294    enum analog_sigtype outsigmod;
00295    int echotraining;
00296    int cid_signalling;           /*!< Asterisk callerid type we're using */
00297    int polarityonanswerdelay;
00298    int stripmsd;
00299    enum analog_cid_start cid_start;
00300    char mohsuggest[MAX_MUSICCLASS];
00301    char cid_num[AST_MAX_EXTENSION];
00302    char cid_name[AST_MAX_EXTENSION];
00303 
00304 
00305    /* XXX: All variables after this are internal */
00306    unsigned int callwaiting:1;      /*!< TRUE if call waiting is enabled. (Active option) */
00307    unsigned int dialednone:1;
00308    unsigned int dialing:1;       /*!< TRUE if in the process of dialing digits or sending something */
00309    unsigned int dnd:1;           /*!< TRUE if Do-Not-Disturb is enabled. */
00310    unsigned int echobreak:1;
00311    unsigned int hidecallerid:1;
00312    unsigned int outgoing:1;
00313    unsigned int inalarm:1;
00314    /*!
00315     * \brief TRUE if Call Waiting (CW) CPE Alert Signal (CAS) is being sent.
00316     * \note
00317     * After CAS is sent, the call waiting caller id will be sent if the phone
00318     * gives a positive reply.
00319     */
00320    unsigned int callwaitcas:1;
00321 
00322    char callwait_num[AST_MAX_EXTENSION];
00323    char callwait_name[AST_MAX_EXTENSION];
00324    char lastcid_num[AST_MAX_EXTENSION];
00325    char lastcid_name[AST_MAX_EXTENSION];
00326    struct ast_party_caller caller;
00327    int cidrings;              /*!< Which ring to deliver CID on */
00328    char echorest[20];
00329    int polarity;
00330    struct timeval polaritydelaytv;
00331    char dialdest[256];
00332    time_t guardtime;          /*!< Must wait this much time before using for new call */
00333    struct timeval flashtime;        /*!< Last flash-hook time */
00334    int whichwink;             /*!< SIG_FEATDMF_TA Which wink are we on? */
00335    char finaldial[64];
00336    char *origcid_num;            /*!< malloced original callerid */
00337    char *origcid_name;           /*!< malloced original callerid */
00338    char call_forward[AST_MAX_EXTENSION];
00339 
00340    /* Ast channel to pass to __ss_analog_thread */
00341    struct ast_channel *ss_astchan;
00342 
00343    /* All variables after this are definitely going to be audited */
00344    int ringt;
00345    int ringt_base;
00346 };
00347 
00348 struct analog_pvt *analog_new(enum analog_sigtype signallingtype, struct analog_callback *c, void *private_data);
00349 void analog_delete(struct analog_pvt *doomed);
00350 
00351 void analog_free(struct analog_pvt *p);
00352 
00353 int analog_call(struct analog_pvt *p, struct ast_channel *ast, char *rdest, int timeout);
00354 
00355 int analog_hangup(struct analog_pvt *p, struct ast_channel *ast);
00356 
00357 int analog_answer(struct analog_pvt *p, struct ast_channel *ast);
00358 
00359 struct ast_frame *analog_exception(struct analog_pvt *p, struct ast_channel *ast);
00360 
00361 struct ast_channel * analog_request(struct analog_pvt *p, int *callwait, const struct ast_channel *requestor);
00362 
00363 int analog_available(struct analog_pvt *p);
00364 
00365 void *analog_handle_init_event(struct analog_pvt *i, int event);
00366 
00367 int analog_config_complete(struct analog_pvt *p);
00368 
00369 void analog_handle_dtmf(struct analog_pvt *p, struct ast_channel *ast, enum analog_sub index, struct ast_frame **dest);
00370 
00371 enum analog_cid_start analog_str_to_cidstart(const char *value);
00372 
00373 const char *analog_cidstart_to_str(enum analog_cid_start cid_start);
00374 
00375 enum analog_sigtype analog_str_to_sigtype(const char *name);
00376 
00377 const char *analog_sigtype_to_str(enum analog_sigtype sigtype);
00378 
00379 unsigned int analog_str_to_cidtype(const char *name);
00380 
00381 const char *analog_cidtype_to_str(unsigned int cid_type);
00382 
00383 int analog_ss_thread_start(struct analog_pvt *p, struct ast_channel *ast);
00384 
00385 int analog_fixup(struct ast_channel *oldchan, struct ast_channel *newchan, void *newp);
00386 
00387 int analog_dnd(struct analog_pvt *p, int flag);
00388 
00389 #endif /* _SIG_ANSLOG_H */

Generated on Wed Apr 6 11:29:47 2011 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7