Thu Oct 11 06:42:03 2012

Asterisk developer's documentation


chan_misdn.c

Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  * 
00004  * Copyright (C) 2004 - 2006, Christian Richter
00005  *
00006  * Christian Richter <crich@beronet.com>
00007  *
00008  * See http://www.asterisk.org for more information about
00009  * the Asterisk project. Please do not directly contact
00010  * any of the maintainers of this project for assistance;
00011  * the project provides a web site, mailing lists and IRC
00012  * channels for your use.
00013  *
00014  * This program is free software, distributed under the terms of
00015  * the GNU General Public License Version 2. See the LICENSE file
00016  * at the top of the source tree.
00017  *
00018  */
00019 
00020 /*!
00021  * \file
00022  *
00023  * \brief the chan_misdn channel driver for Asterisk
00024  *
00025  * \author Christian Richter <crich@beronet.com>
00026  *
00027  * \extref MISDN http://www.misdn.org/
00028  *
00029  * \ingroup channel_drivers
00030  */
00031 
00032 /*** MODULEINFO
00033    <depend>isdnnet</depend>
00034    <depend>misdn</depend>
00035    <depend>suppserv</depend>
00036  ***/
00037 #include "asterisk.h"
00038 
00039 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 284478 $")
00040 
00041 #include <stdio.h>
00042 #include <pthread.h>
00043 #include <string.h>
00044 #include <sys/socket.h>
00045 #include <sys/time.h>
00046 #include <errno.h>
00047 #include <unistd.h>
00048 #include <stdlib.h>
00049 #include <arpa/inet.h>
00050 #include <fcntl.h>
00051 #include <sys/ioctl.h>
00052 #include <signal.h>
00053 #include <sys/file.h>
00054 #include <semaphore.h>
00055 
00056 #include "asterisk/channel.h"
00057 #include "asterisk/config.h"
00058 #include "asterisk/logger.h"
00059 #include "asterisk/module.h"
00060 #include "asterisk/pbx.h"
00061 #include "asterisk/options.h"
00062 #include "asterisk/io.h"
00063 #include "asterisk/frame.h"
00064 #include "asterisk/translate.h"
00065 #include "asterisk/cli.h"
00066 #include "asterisk/musiconhold.h"
00067 #include "asterisk/dsp.h"
00068 #include "asterisk/translate.h"
00069 #include "asterisk/config.h"
00070 #include "asterisk/file.h"
00071 #include "asterisk/callerid.h"
00072 #include "asterisk/indications.h"
00073 #include "asterisk/app.h"
00074 #include "asterisk/features.h"
00075 #include "asterisk/term.h"
00076 #include "asterisk/sched.h"
00077 #include "asterisk/stringfields.h"
00078 #include "asterisk/causes.h"
00079 
00080 #include "chan_misdn_config.h"
00081 #include "isdn_lib.h"
00082 
00083 char global_tracefile[BUFFERSIZE + 1];
00084 
00085 static int g_config_initialized = 0;
00086 
00087 struct misdn_jb{
00088    int size;
00089    int upper_threshold;
00090    char *samples, *ok;
00091    int wp,rp;
00092    int state_empty;
00093    int state_full;
00094    int state_buffer;
00095    int bytes_wrote;
00096    ast_mutex_t mutexjb;
00097 };
00098 
00099 
00100 
00101 /*! \brief allocates the jb-structure and initialize the elements */
00102 struct misdn_jb *misdn_jb_init(int size, int upper_threshold);
00103 
00104 /*! \brief frees the data and destroys the given jitterbuffer struct */
00105 void misdn_jb_destroy(struct misdn_jb *jb);
00106 
00107 /*! \brief fills the jitterbuffer with len data returns < 0 if there was an
00108 error (buffer overrun). */
00109 int misdn_jb_fill(struct misdn_jb *jb, const char *data, int len);
00110 
00111 /*! \brief gets len bytes out of the jitterbuffer if available, else only the
00112 available data is returned and the return value indicates the number
00113 of data. */
00114 int misdn_jb_empty(struct misdn_jb *jb, char *data, int len);
00115 
00116 
00117 /* BEGIN: chan_misdn.h */
00118 
00119 ast_mutex_t release_lock;
00120 
00121 enum misdn_chan_state {
00122    MISDN_NOTHING=0,  /*!< at beginning */
00123    MISDN_WAITING4DIGS, /*!<  when waiting for infos */
00124    MISDN_EXTCANTMATCH, /*!<  when asterisk couldn't match our ext */
00125    MISDN_INCOMING_SETUP, /*!<  for incoming setups*/
00126    MISDN_DIALING, /*!<  when pbx_start */
00127    MISDN_PROGRESS, /*!<  we got a progress */
00128    MISDN_PROCEEDING, /*!<  we got a progress */
00129    MISDN_CALLING, /*!<  when misdn_call is called */
00130    MISDN_CALLING_ACKNOWLEDGE, /*!<  when we get SETUP_ACK */
00131    MISDN_ALERTING, /*!<  when Alerting */
00132    MISDN_BUSY, /*!<  when BUSY */
00133    MISDN_CONNECTED, /*!<  when connected */
00134    MISDN_DISCONNECTED, /*!<  when connected */
00135    MISDN_CLEANING, /*!< when hangup from * but we were connected before */
00136 };
00137 
00138 #define ORG_AST 1
00139 #define ORG_MISDN 2
00140 
00141 enum misdn_hold_state {
00142    MISDN_HOLD_IDLE,     /*!< HOLD not active */
00143    MISDN_HOLD_ACTIVE,      /*!< Call is held */
00144    MISDN_HOLD_TRANSFER, /*!< Held call is being transferred */
00145    MISDN_HOLD_DISCONNECT,  /*!< Held call is being disconnected */
00146 };
00147 struct hold_info {
00148    /*!
00149     * \brief Call HOLD state.
00150     */
00151    enum misdn_hold_state state;
00152    /*!
00153     * \brief Logical port the channel call record is HELD on
00154     * because the B channel is no longer associated.
00155     */
00156    int port;
00157 
00158    /*!
00159     * \brief Original B channel number the HELD call was using.
00160     * \note Used only for debug display messages.
00161     */
00162    int channel;
00163 };
00164 
00165 /*!
00166  * \brief Channel call record structure
00167  */
00168 struct chan_list {
00169    /*! 
00170     * \brief The "allowed_bearers" string read in from /etc/asterisk/misdn.conf
00171     */
00172    char allowed_bearers[BUFFERSIZE + 1];
00173    
00174    /*! 
00175     * \brief State of the channel
00176     */
00177    enum misdn_chan_state state;
00178 
00179    /*! 
00180     * \brief TRUE if a hangup needs to be queued 
00181     * \note This is a debug flag only used to catch calls to hangup_chan() that are already hungup.
00182     */
00183    int need_queue_hangup;
00184 
00185    /*!
00186     * \brief TRUE if a channel can be hung up by calling asterisk directly when done.
00187     */
00188    int need_hangup;
00189 
00190    /*!
00191     * \brief TRUE if we could send an AST_CONTROL_BUSY if needed.
00192     */
00193    int need_busy;
00194    
00195    /*!
00196     * \brief Who originally created this channel. ORG_AST or ORG_MISDN
00197     */
00198    int originator;
00199 
00200    /*! 
00201     * \brief TRUE of we are not to respond immediately to a SETUP message.  Check the dialplan first.
00202     * \note The "noautorespond_on_setup" boolean read in from /etc/asterisk/misdn.conf
00203     */
00204    int noautorespond_on_setup;
00205    
00206    int norxtone;  /* Boolean assigned values but the value is not used. */
00207 
00208    /*!
00209     * \brief TRUE if we are not to generate tones (Playtones)
00210     */
00211    int notxtone; 
00212 
00213    /*!
00214     * \brief TRUE if echo canceller is enabled.  Value is toggled.
00215     */
00216    int toggle_ec;
00217    
00218    /*!
00219     * \brief TRUE if you want to send Tone Indications to an incoming
00220     * ISDN channel on a TE Port.
00221     * \note The "incoming_early_audio" boolean read in from /etc/asterisk/misdn.conf
00222     */
00223    int incoming_early_audio;
00224 
00225    /*!
00226     * \brief TRUE if DTMF digits are to be passed inband only.
00227     * \note It is settable by the misdn_set_opt() application.
00228     */
00229    int ignore_dtmf;
00230 
00231    /*!
00232     * \brief Pipe file descriptor handles array. 
00233     * Read from pipe[0], write to pipe[1] 
00234     */
00235    int pipe[2];
00236 
00237    /*!
00238     * \brief Read buffer for inbound audio from pipe[0]
00239     */
00240    char ast_rd_buf[4096];
00241 
00242    /*!
00243     * \brief Inbound audio frame returned by misdn_read().
00244     */
00245    struct ast_frame frame;
00246 
00247    /*!
00248     * \brief Fax detection option. (0:no 1:yes 2:yes+nojump)
00249     * \note The "faxdetect" option string read in from /etc/asterisk/misdn.conf
00250     * \note It is settable by the misdn_set_opt() application.
00251     */
00252    int faxdetect;
00253 
00254    /*!
00255     * \brief Number of seconds to detect a Fax machine when detection enabled.
00256     * \note 0 disables the timeout.
00257     * \note The "faxdetect_timeout" value read in from /etc/asterisk/misdn.conf
00258     */
00259    int faxdetect_timeout;
00260 
00261    /*!
00262     * \brief Starting time of fax detection with timeout when nonzero.
00263     */
00264    struct timeval faxdetect_tv;
00265 
00266    /*!
00267     * \brief TRUE if a fax has been detected.
00268     */
00269    int faxhandled;
00270 
00271    /*!
00272     * \brief TRUE if we will use the Asterisk DSP to detect DTMF/Fax
00273     * \note The "astdtmf" boolean read in from /etc/asterisk/misdn.conf
00274     */
00275    int ast_dsp;
00276 
00277    /*!
00278     * \brief Jitterbuffer length
00279     * \note The "jitterbuffer" value read in from /etc/asterisk/misdn.conf
00280     */
00281    int jb_len;
00282 
00283    /*!
00284     * \brief Jitterbuffer upper threshold
00285     * \note The "jitterbuffer_upper_threshold" value read in from /etc/asterisk/misdn.conf
00286     */
00287    int jb_upper_threshold;
00288 
00289    /*!
00290     * \brief Allocated jitterbuffer controller
00291     * \note misdn_jb_init() creates the jitterbuffer.
00292     * \note Must use misdn_jb_destroy() to clean up. 
00293     */
00294    struct misdn_jb *jb;
00295    
00296    /*!
00297     * \brief Allocated DSP controller
00298     * \note ast_dsp_new() creates the DSP controller.
00299     * \note Must use ast_dsp_free() to clean up. 
00300     */
00301    struct ast_dsp *dsp;
00302 
00303    /*!
00304     * \brief Associated Asterisk channel structure.
00305     */
00306    struct ast_channel * ast;
00307 
00308    //int dummy;   /* Not used */
00309   
00310    /*!
00311     * \brief Associated B channel structure.
00312     */
00313    struct misdn_bchannel *bc;
00314 
00315    /*!
00316     * \brief HELD channel call information
00317     */
00318    struct hold_info hold;
00319 
00320    /*!
00321     * \brief From associated B channel: Layer 3 process ID
00322     * \note Used to find the HELD channel call record when retrieving a call.
00323     */
00324    unsigned int l3id;
00325 
00326    /*! 
00327     * \brief From associated B channel: B Channel mISDN driver layer ID from mISDN_get_layerid()
00328     * \note Used only for debug display messages.
00329     */
00330    int addr;
00331 
00332    /*!
00333     * \brief Incoming call dialplan context identifier.
00334     * \note The "context" string read in from /etc/asterisk/misdn.conf
00335     */
00336    char context[AST_MAX_CONTEXT];
00337 
00338    /*!
00339     * \brief The configured music-on-hold class to use for this call.
00340     * \note The "musicclass" string read in from /etc/asterisk/misdn.conf
00341     */
00342    char mohinterpret[MAX_MUSICCLASS];
00343 
00344    //int zero_read_cnt; /* Not used */
00345 
00346    /*!
00347     * \brief Number of outgoing audio frames dropped since last debug gripe message.
00348     */
00349    int dropped_frame_cnt;
00350 
00351    /*!
00352     * \brief TRUE if we must do the ringback tones.
00353     * \note The "far_alerting" boolean read in from /etc/asterisk/misdn.conf
00354     */
00355    int far_alerting;
00356 
00357    /*!
00358     * \brief TRUE if NT should disconnect an overlap dialing call when a timeout occurs.
00359     * \note The "nttimeout" boolean read in from /etc/asterisk/misdn.conf
00360     */
00361    int nttimeout;
00362 
00363    /*!
00364     * \brief Other channel call record PID 
00365     * \note Value imported from Asterisk environment variable MISDN_PID 
00366     */
00367    int other_pid;
00368 
00369    /*!
00370     * \brief Bridged other channel call record
00371     * \note Pointer set when other_pid imported from Asterisk environment 
00372     * variable MISDN_PID by either side.
00373     */
00374    struct chan_list *other_ch;
00375 
00376    /*!
00377     * \brief Tone zone sound used for dialtone generation.
00378     * \note Used as a boolean.  Non-NULL to prod generation if enabled. 
00379     */
00380    const struct tone_zone_sound *ts;
00381    
00382    /*!
00383     * \brief Enables overlap dialing for the set amount of seconds.  (0 = Disabled)
00384     * \note The "overlapdial" value read in from /etc/asterisk/misdn.conf
00385     */
00386    int overlap_dial;
00387 
00388    /*!
00389     * \brief Overlap dialing timeout Task ID.  -1 if not running.
00390     */
00391    int overlap_dial_task;
00392 
00393    /*!
00394     * \brief overlap_tv access lock.
00395     */
00396    ast_mutex_t overlap_tv_lock;
00397 
00398    /*!
00399     * \brief Overlap timer start time.  Timer restarted for every digit received.
00400     */
00401    struct timeval overlap_tv;
00402   
00403    //struct chan_list *peer;  /* Not used */
00404 
00405    /*!
00406     * \brief Next channel call record in the list.
00407     */
00408    struct chan_list *next;
00409    //struct chan_list *prev;     /* Not used */
00410    //struct chan_list *first; /* Not used */
00411 };
00412 
00413 
00414 
00415 void export_ch(struct ast_channel *chan, struct misdn_bchannel *bc, struct chan_list *ch);
00416 void import_ch(struct ast_channel *chan, struct misdn_bchannel *bc, struct chan_list *ch);
00417 
00418 struct robin_list {
00419    char *group;
00420    int port;
00421    int channel;
00422    struct robin_list *next;
00423    struct robin_list *prev;
00424 };
00425 static struct robin_list *robin = NULL;
00426 
00427 
00428 
00429 static struct ast_frame *process_ast_dsp(struct chan_list *tmp, struct ast_frame *frame);
00430 
00431 
00432 
00433 static void free_robin_list(void)
00434 {
00435    struct robin_list *r;
00436    struct robin_list *next;
00437 
00438    for (r = robin, robin = NULL; r; r = next) {
00439       next = r->next;
00440       free(r->group);
00441       free(r);
00442    }
00443 }
00444 
00445 static struct robin_list* get_robin_position (char *group) 
00446 {
00447    struct robin_list *new;
00448    struct robin_list *iter = robin;
00449    for (; iter; iter = iter->next) {
00450       if (!strcasecmp(iter->group, group)) {
00451          return iter;
00452       }
00453    }
00454    new = calloc(1, sizeof(*new));
00455    if (!new) {
00456       return NULL;
00457    }
00458    new->group = strdup(group);
00459    if (!new->group) {
00460       free(new);
00461       return NULL;
00462    }
00463    new->port = 0;
00464    new->channel = 0;
00465    if (robin) {
00466       new->next = robin;
00467       robin->prev = new;
00468    }
00469    robin = new;
00470    return robin;
00471 }
00472 
00473 
00474 /*! \brief the main schedule context for stuff like l1 watcher, overlap dial, ... */
00475 static struct sched_context *misdn_tasks = NULL;
00476 static pthread_t misdn_tasks_thread;
00477 
00478 static int *misdn_ports;
00479 
00480 static void chan_misdn_log(int level, int port, char *tmpl, ...)
00481    __attribute__((format(printf, 3, 4)));
00482 
00483 static struct ast_channel *misdn_new(struct chan_list *cl, int state,  char *exten, char *callerid, int format, int port, int c);
00484 static void send_digit_to_chan(struct chan_list *cl, char digit );
00485 
00486 static int pbx_start_chan(struct chan_list *ch);
00487 
00488 #define MISDN_ASTERISK_TECH_PVT(ast) ast->tech_pvt
00489 #define MISDN_ASTERISK_PVT(ast) 1
00490 
00491 #include "asterisk/strings.h"
00492 
00493 /* #define MISDN_DEBUG 1 */
00494 
00495 static const char misdn_type[] = "mISDN";
00496 
00497 static int tracing = 0 ;
00498 
00499 /*! \brief Only alaw and mulaw is allowed for now */
00500 static int prefformat =  AST_FORMAT_ALAW ; /*  AST_FORMAT_SLINEAR ;  AST_FORMAT_ULAW | */
00501 
00502 static int *misdn_debug;
00503 static int *misdn_debug_only;
00504 static int max_ports;
00505 
00506 static int *misdn_in_calls;
00507 static int *misdn_out_calls;
00508 
00509 
00510 struct chan_list dummy_cl;
00511 
00512 /*!
00513  * \brief Global channel call record list head.
00514  */
00515 struct chan_list *cl_te=NULL;
00516 ast_mutex_t cl_te_lock;
00517 
00518 static enum event_response_e
00519 cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data);
00520 
00521 static void send_cause2ast(struct ast_channel *ast, struct misdn_bchannel*bc, struct chan_list *ch);
00522 
00523 static void cl_queue_chan(struct chan_list **list, struct chan_list *chan);
00524 static void cl_dequeue_chan(struct chan_list **list, struct chan_list *chan);
00525 static struct chan_list *find_chan_by_bc(struct chan_list *list, struct misdn_bchannel *bc);
00526 static struct chan_list *find_chan_by_pid(struct chan_list *list, int pid);
00527 
00528 
00529 
00530 static int dialtone_indicate(struct chan_list *cl);
00531 static void hanguptone_indicate(struct chan_list *cl);
00532 static int stop_indicate(struct chan_list *cl);
00533 
00534 static int start_bc_tones(struct chan_list *cl);
00535 static int stop_bc_tones(struct chan_list *cl);
00536 static void release_chan_early(struct chan_list *ch);
00537 static void release_chan(struct chan_list *ch, struct misdn_bchannel *bc);
00538 
00539 static int misdn_check_l2l1(struct ast_channel *chan, void *data);
00540 static int misdn_set_opt_exec(struct ast_channel *chan, void *data);
00541 static int misdn_facility_exec(struct ast_channel *chan, void *data);
00542 
00543 int chan_misdn_jb_empty(struct misdn_bchannel *bc, char *buf, int len);
00544 
00545 
00546 void debug_numplan(int port, int numplan, char *type);
00547 
00548 
00549 int add_out_calls(int port);
00550 int add_in_calls(int port);
00551 
00552 
00553 #ifdef MISDN_1_2
00554 static int update_pipeline_config(struct misdn_bchannel *bc);
00555 #else
00556 static int update_ec_config(struct misdn_bchannel *bc);
00557 #endif
00558 
00559 
00560 
00561 /*************** Helpers *****************/
00562 
00563 static struct chan_list * get_chan_by_ast(struct ast_channel *ast)
00564 {
00565    struct chan_list *tmp;
00566   
00567    for (tmp=cl_te; tmp; tmp = tmp->next) {
00568       if ( tmp->ast == ast ) return tmp;
00569    }
00570   
00571    return NULL;
00572 }
00573 
00574 static struct chan_list * get_chan_by_ast_name(char *name)
00575 {
00576    struct chan_list *tmp;
00577   
00578    for (tmp=cl_te; tmp; tmp = tmp->next) {
00579       if ( tmp->ast  && strcmp(tmp->ast->name,name) == 0) return tmp;
00580    }
00581   
00582    return NULL;
00583 }
00584 
00585 
00586 
00587 struct allowed_bearers {
00588    char *name;       /*!< Bearer capability name string used in /etc/misdn.conf allowed_bearers */
00589    char *display;    /*!< Bearer capability displayable name */
00590    int cap;       /*!< SETUP message bearer capability field code value */
00591    int deprecated;      /*!< TRUE if this entry is deprecated. (Misspelled or bad name to use) */
00592 };
00593 
00594 /* *INDENT-OFF* */
00595 static const struct allowed_bearers allowed_bearers_array[]= {
00596    /* Name,                      Displayable Name       Bearer Capability,                    Deprecated */
00597    { "speech",                  "Speech",               INFO_CAPABILITY_SPEECH,               0 },
00598    { "3_1khz",                  "3.1KHz Audio",         INFO_CAPABILITY_AUDIO_3_1K,           0 },
00599    { "digital_unrestricted",    "Unrestricted Digital", INFO_CAPABILITY_DIGITAL_UNRESTRICTED, 0 },
00600    { "digital_restricted",      "Restricted Digital",   INFO_CAPABILITY_DIGITAL_RESTRICTED,   0 },
00601    { "digital_restriced",       "Restricted Digital",   INFO_CAPABILITY_DIGITAL_RESTRICTED,   1 }, /* Allow misspelling for backwards compatibility */
00602    { "video",                   "Video",                INFO_CAPABILITY_VIDEO,                0 }
00603 };
00604 /* *INDENT-ON* */
00605 
00606 static const char *bearer2str(int cap)
00607 {
00608    unsigned index;
00609 
00610    for (index = 0; index < ARRAY_LEN(allowed_bearers_array); ++index) {
00611       if (allowed_bearers_array[index].cap == cap) {
00612          return allowed_bearers_array[index].display;
00613       }
00614    }  /* end for */
00615 
00616    return "Unknown Bearer";
00617 }
00618 
00619 
00620 static void print_facility(struct FacParm *fac, struct misdn_bchannel *bc)
00621 {
00622    switch (fac->Function) {
00623    case Fac_CD:
00624       chan_misdn_log(1,bc->port," --> calldeflect to: %s, presentable: %s\n", fac->u.CDeflection.DeflectedToNumber,
00625          fac->u.CDeflection.PresentationAllowed ? "yes" : "no");
00626       break;
00627    case Fac_AOCDCurrency:
00628       if (fac->u.AOCDcur.chargeNotAvailable)
00629          chan_misdn_log(1,bc->port," --> AOCD currency: charge not available\n");
00630       else if (fac->u.AOCDcur.freeOfCharge)
00631          chan_misdn_log(1,bc->port," --> AOCD currency: free of charge\n");
00632       else if (fac->u.AOCDchu.billingId >= 0)
00633          chan_misdn_log(1,bc->port," --> AOCD currency: currency:%s amount:%d multiplier:%d typeOfChargingInfo:%s billingId:%d\n",
00634             fac->u.AOCDcur.currency, fac->u.AOCDcur.currencyAmount, fac->u.AOCDcur.multiplier,
00635             (fac->u.AOCDcur.typeOfChargingInfo == 0) ? "subTotal" : "total", fac->u.AOCDcur.billingId);
00636       else
00637          chan_misdn_log(1,bc->port," --> AOCD currency: currency:%s amount:%d multiplier:%d typeOfChargingInfo:%s\n",
00638             fac->u.AOCDcur.currency, fac->u.AOCDcur.currencyAmount, fac->u.AOCDcur.multiplier,
00639             (fac->u.AOCDcur.typeOfChargingInfo == 0) ? "subTotal" : "total");
00640       break;
00641    case Fac_AOCDChargingUnit:
00642       if (fac->u.AOCDchu.chargeNotAvailable)
00643          chan_misdn_log(1,bc->port," --> AOCD charging unit: charge not available\n");
00644       else if (fac->u.AOCDchu.freeOfCharge)
00645          chan_misdn_log(1,bc->port," --> AOCD charging unit: free of charge\n");
00646       else if (fac->u.AOCDchu.billingId >= 0)
00647          chan_misdn_log(1,bc->port," --> AOCD charging unit: recordedUnits:%d typeOfChargingInfo:%s billingId:%d\n",
00648             fac->u.AOCDchu.recordedUnits, (fac->u.AOCDchu.typeOfChargingInfo == 0) ? "subTotal" : "total", fac->u.AOCDchu.billingId);
00649       else
00650          chan_misdn_log(1,bc->port," --> AOCD charging unit: recordedUnits:%d typeOfChargingInfo:%s\n",
00651             fac->u.AOCDchu.recordedUnits, (fac->u.AOCDchu.typeOfChargingInfo == 0) ? "subTotal" : "total");
00652       break;
00653    default:
00654       chan_misdn_log(1,bc->port," --> unknown facility\n");
00655       break;
00656    }
00657 }
00658 
00659 static void print_bearer(struct misdn_bchannel *bc) 
00660 {
00661    
00662    chan_misdn_log(2, bc->port, " --> Bearer: %s\n",bearer2str(bc->capability));
00663    
00664    switch(bc->law) {
00665    case INFO_CODEC_ALAW:
00666       chan_misdn_log(2, bc->port, " --> Codec: Alaw\n");
00667       break;
00668    case INFO_CODEC_ULAW:
00669       chan_misdn_log(2, bc->port, " --> Codec: Ulaw\n");
00670       break;
00671    }
00672 }
00673 
00674 static void export_aoc_vars(int originator, struct ast_channel *ast, struct misdn_bchannel *bc)
00675 {
00676    char buf[128];
00677 
00678    if (!ast)
00679       return;
00680 
00681    if (originator == ORG_AST) {
00682       ast = ast_bridged_channel(ast);
00683       if (!ast)
00684          return;
00685    }
00686 
00687    switch (bc->AOCDtype) {
00688    case Fac_AOCDCurrency:
00689       pbx_builtin_setvar_helper(ast, "AOCD_Type", "currency");
00690       if (bc->AOCD.currency.chargeNotAvailable)
00691          pbx_builtin_setvar_helper(ast, "AOCD_ChargeAvailable", "no");
00692       else {
00693          pbx_builtin_setvar_helper(ast, "AOCD_ChargeAvailable", "yes");
00694          if (bc->AOCD.currency.freeOfCharge)
00695             pbx_builtin_setvar_helper(ast, "AOCD_FreeOfCharge", "yes");
00696          else {
00697             pbx_builtin_setvar_helper(ast, "AOCD_FreeOfCharge", "no");
00698             if (snprintf(buf, sizeof(buf), "%d %s", bc->AOCD.currency.currencyAmount * bc->AOCD.currency.multiplier, bc->AOCD.currency.currency) < sizeof(buf)) {
00699                pbx_builtin_setvar_helper(ast, "AOCD_Amount", buf);
00700                if (bc->AOCD.currency.billingId >= 0 && snprintf(buf, sizeof(buf), "%d", bc->AOCD.currency.billingId) < sizeof(buf))
00701                   pbx_builtin_setvar_helper(ast, "AOCD_BillingId", buf);
00702             }
00703          }
00704       }
00705       break;
00706    case Fac_AOCDChargingUnit:
00707       pbx_builtin_setvar_helper(ast, "AOCD_Type", "charging_unit");
00708       if (bc->AOCD.chargingUnit.chargeNotAvailable)
00709          pbx_builtin_setvar_helper(ast, "AOCD_ChargeAvailable", "no");
00710       else {
00711          pbx_builtin_setvar_helper(ast, "AOCD_ChargeAvailable", "yes");
00712          if (bc->AOCD.chargingUnit.freeOfCharge)
00713             pbx_builtin_setvar_helper(ast, "AOCD_FreeOfCharge", "yes");
00714          else {
00715             pbx_builtin_setvar_helper(ast, "AOCD_FreeOfCharge", "no");
00716             if (snprintf(buf, sizeof(buf), "%d", bc->AOCD.chargingUnit.recordedUnits) < sizeof(buf)) {
00717                pbx_builtin_setvar_helper(ast, "AOCD_RecordedUnits", buf);
00718                if (bc->AOCD.chargingUnit.billingId >= 0 && snprintf(buf, sizeof(buf), "%d", bc->AOCD.chargingUnit.billingId) < sizeof(buf))
00719                   pbx_builtin_setvar_helper(ast, "AOCD_BillingId", buf);
00720             }
00721          }
00722       }
00723       break;
00724    default:
00725       break;
00726    }
00727 }
00728 
00729 /*************** Helpers END *************/
00730 
00731 static void sighandler(int sig)
00732 {}
00733 
00734 static void* misdn_tasks_thread_func (void *data)
00735 {
00736    int wait;
00737    struct sigaction sa;
00738 
00739    sa.sa_handler = sighandler;
00740    sa.sa_flags = SA_NODEFER;
00741    sigemptyset(&sa.sa_mask);
00742    sigaddset(&sa.sa_mask, SIGUSR1);
00743    sigaction(SIGUSR1, &sa, NULL);
00744    
00745    sem_post((sem_t *)data);
00746 
00747    while (1) {
00748       wait = ast_sched_wait(misdn_tasks);
00749       if (wait < 0)
00750          wait = 8000;
00751       if (poll(NULL, 0, wait) < 0)
00752          chan_misdn_log(4, 0, "Waking up misdn_tasks thread\n");
00753       ast_sched_runq(misdn_tasks);
00754    }
00755    return NULL;
00756 }
00757 
00758 static void misdn_tasks_init (void)
00759 {
00760    sem_t blocker;
00761    int i = 5;
00762 
00763    if (sem_init(&blocker, 0, 0)) {
00764       perror("chan_misdn: Failed to initialize semaphore!");
00765       exit(1);
00766    }
00767 
00768    chan_misdn_log(4, 0, "Starting misdn_tasks thread\n");
00769    
00770    misdn_tasks = sched_context_create();
00771    pthread_create(&misdn_tasks_thread, NULL, misdn_tasks_thread_func, &blocker);
00772 
00773    while (sem_wait(&blocker) && --i);
00774    sem_destroy(&blocker);
00775 }
00776 
00777 static void misdn_tasks_destroy (void)
00778 {
00779    if (misdn_tasks) {
00780       chan_misdn_log(4, 0, "Killing misdn_tasks thread\n");
00781       if ( pthread_cancel(misdn_tasks_thread) == 0 ) {
00782          cb_log(4, 0, "Joining misdn_tasks thread\n");
00783          pthread_join(misdn_tasks_thread, NULL);
00784       }
00785       sched_context_destroy(misdn_tasks);
00786    }
00787 }
00788 
00789 static inline void misdn_tasks_wakeup (void)
00790 {
00791    pthread_kill(misdn_tasks_thread, SIGUSR1);
00792 }
00793 
00794 static inline int _misdn_tasks_add_variable (int timeout, ast_sched_cb callback, const void *data, int variable)
00795 {
00796    int task_id;
00797 
00798    if (!misdn_tasks) {
00799       misdn_tasks_init();
00800    }
00801    task_id = ast_sched_add_variable(misdn_tasks, timeout, callback, data, variable);
00802    misdn_tasks_wakeup();
00803 
00804    return task_id;
00805 }
00806 
00807 static int misdn_tasks_add (int timeout, ast_sched_cb callback, const void *data)
00808 {
00809    return _misdn_tasks_add_variable(timeout, callback, data, 0);
00810 }
00811 
00812 static int misdn_tasks_add_variable (int timeout, ast_sched_cb callback, const void *data)
00813 {
00814    return _misdn_tasks_add_variable(timeout, callback, data, 1);
00815 }
00816 
00817 static void misdn_tasks_remove (int task_id)
00818 {
00819    AST_SCHED_DEL(misdn_tasks, task_id);
00820 }
00821 
00822 static int misdn_l1_task (const void *data)
00823 {
00824    misdn_lib_isdn_l1watcher(*(int *)data);
00825    chan_misdn_log(5, *(int *)data, "L1watcher timeout\n");
00826    return 1;
00827 }
00828 
00829 static int misdn_overlap_dial_task (const void *data)
00830 {
00831    struct timeval tv_end, tv_now;
00832    int diff;
00833    struct chan_list *ch = (struct chan_list *)data;
00834 
00835    chan_misdn_log(4, ch->bc->port, "overlap dial task, chan_state: %d\n", ch->state);
00836 
00837    if (ch->state != MISDN_WAITING4DIGS) {
00838       ch->overlap_dial_task = -1;
00839       return 0;
00840    }
00841    
00842    ast_mutex_lock(&ch->overlap_tv_lock);
00843    tv_end = ch->overlap_tv;
00844    ast_mutex_unlock(&ch->overlap_tv_lock);
00845    
00846    tv_end.tv_sec += ch->overlap_dial;
00847    tv_now = ast_tvnow();
00848 
00849    diff = ast_tvdiff_ms(tv_end, tv_now);
00850 
00851    if (diff <= 100) {
00852       char *dad=ch->bc->dad, sexten[]="s";
00853       /* if we are 100ms near the timeout, we are satisfied.. */
00854       stop_indicate(ch);
00855       
00856       if (ast_strlen_zero(ch->bc->dad)) {
00857          dad=sexten;
00858          strcpy(ch->ast->exten, sexten);
00859       }
00860 
00861       if (ast_exists_extension(ch->ast, ch->context, dad, 1, ch->bc->oad)) {
00862          ch->state=MISDN_DIALING;
00863          if (pbx_start_chan(ch) < 0) {
00864             chan_misdn_log(-1, ch->bc->port, "ast_pbx_start returned < 0 in misdn_overlap_dial_task\n");
00865             goto misdn_overlap_dial_task_disconnect;
00866          }
00867       } else {
00868 misdn_overlap_dial_task_disconnect:
00869          hanguptone_indicate(ch);
00870          ch->bc->out_cause = AST_CAUSE_UNALLOCATED;
00871          ch->state=MISDN_CLEANING;
00872          misdn_lib_send_event(ch->bc, EVENT_DISCONNECT);
00873       }
00874       ch->overlap_dial_task = -1;
00875       return 0;
00876    } else
00877       return diff;
00878 }
00879 
00880 static void send_digit_to_chan(struct chan_list *cl, char digit )
00881 {
00882    static const char* dtmf_tones[] = {
00883       "!941+1336/100,!0/100", /* 0 */
00884       "!697+1209/100,!0/100", /* 1 */
00885       "!697+1336/100,!0/100", /* 2 */
00886       "!697+1477/100,!0/100", /* 3 */
00887       "!770+1209/100,!0/100", /* 4 */
00888       "!770+1336/100,!0/100", /* 5 */
00889       "!770+1477/100,!0/100", /* 6 */
00890       "!852+1209/100,!0/100", /* 7 */
00891       "!852+1336/100,!0/100", /* 8 */
00892       "!852+1477/100,!0/100", /* 9 */
00893       "!697+1633/100,!0/100", /* A */
00894       "!770+1633/100,!0/100", /* B */
00895       "!852+1633/100,!0/100", /* C */
00896       "!941+1633/100,!0/100", /* D */
00897       "!941+1209/100,!0/100", /* * */
00898       "!941+1477/100,!0/100" };  /* # */
00899    struct ast_channel *chan=cl->ast; 
00900   
00901    if (digit >= '0' && digit <='9')
00902       ast_playtones_start(chan,0,dtmf_tones[digit-'0'], 0);
00903    else if (digit >= 'A' && digit <= 'D')
00904       ast_playtones_start(chan,0,dtmf_tones[digit-'A'+10], 0);
00905    else if (digit == '*')
00906       ast_playtones_start(chan,0,dtmf_tones[14], 0);
00907    else if (digit == '#')
00908       ast_playtones_start(chan,0,dtmf_tones[15], 0);
00909    else {
00910       /* not handled */
00911       ast_log(LOG_DEBUG, "Unable to handle DTMF tone '%c' for '%s'\n", digit, chan->name);
00912    }
00913 }
00914 
00915 /*** CLI HANDLING ***/
00916 static int misdn_set_debug(int fd, int argc, char *argv[])
00917 {
00918    int level;
00919 
00920    if (argc != 4 && argc != 5 && argc != 6 && argc != 7)
00921       return RESULT_SHOWUSAGE; 
00922 
00923    level = atoi(argv[3]);
00924 
00925    switch (argc) {
00926    case 4:
00927    case 5:
00928       {
00929          int i;
00930          int only = 0;
00931          if (argc == 5) {
00932             if (strncasecmp(argv[4], "only", strlen(argv[4])))
00933                return RESULT_SHOWUSAGE;
00934             else
00935                only = 1;
00936          }
00937    
00938          for (i = 0; i <= max_ports; i++) {
00939             misdn_debug[i] = level;
00940             misdn_debug_only[i] = only;
00941          }
00942          ast_cli(fd, "changing debug level for all ports to %d%s\n",misdn_debug[0], only?" (only)":"");
00943       }
00944       break;
00945    case 6:
00946    case 7:
00947       {
00948          int port;
00949          if (strncasecmp(argv[4], "port", strlen(argv[4])))
00950             return RESULT_SHOWUSAGE;
00951          port = atoi(argv[5]);
00952          if (port <= 0 || port > max_ports) {
00953             switch (max_ports) {
00954             case 0:
00955                ast_cli(fd, "port number not valid! no ports available so you won't get lucky with any number here...\n");
00956                break;
00957             case 1:
00958                ast_cli(fd, "port number not valid! only port 1 is available.\n");
00959                break;
00960             default:
00961                ast_cli(fd, "port number not valid! only ports 1 to %d are available.\n", max_ports);
00962             }
00963             return 0;
00964          }
00965          if (argc == 7) {
00966             if (strncasecmp(argv[6], "only", strlen(argv[6])))
00967                return RESULT_SHOWUSAGE;
00968             else
00969                misdn_debug_only[port] = 1;
00970          } else
00971             misdn_debug_only[port] = 0;
00972          misdn_debug[port] = level;
00973          ast_cli(fd, "changing debug level to %d%s for port %d\n", misdn_debug[port], misdn_debug_only[port]?" (only)":"", port);
00974       }
00975    }
00976    return 0;
00977 }
00978 
00979 static int misdn_set_crypt_debug(int fd, int argc, char *argv[])
00980 {
00981    if (argc != 5) return RESULT_SHOWUSAGE; 
00982 
00983    return 0;
00984 }
00985 
00986 static int misdn_port_block(int fd, int argc, char *argv[])
00987 {
00988    int port;
00989 
00990    if (argc != 4)
00991       return RESULT_SHOWUSAGE;
00992   
00993    port = atoi(argv[3]);
00994 
00995    misdn_lib_port_block(port);
00996 
00997    return 0;
00998 }
00999 
01000 static int misdn_port_unblock(int fd, int argc, char *argv[])
01001 {
01002    int port;
01003   
01004    if (argc != 4)
01005       return RESULT_SHOWUSAGE;
01006   
01007    port = atoi(argv[3]);
01008 
01009    misdn_lib_port_unblock(port);
01010 
01011    return 0;
01012 }
01013 
01014 
01015 static int misdn_restart_port (int fd, int argc, char *argv[])
01016 {
01017    int port;
01018   
01019    if (argc != 4)
01020       return RESULT_SHOWUSAGE;
01021   
01022    port = atoi(argv[3]);
01023 
01024    misdn_lib_port_restart(port);
01025 
01026    return 0;
01027 }
01028 
01029 static int misdn_restart_pid (int fd, int argc, char *argv[])
01030 {
01031    int pid;
01032   
01033    if (argc != 4)
01034       return RESULT_SHOWUSAGE;
01035   
01036    pid = atoi(argv[3]);
01037 
01038    misdn_lib_pid_restart(pid);
01039 
01040    return 0;
01041 }
01042 
01043 static int misdn_port_up (int fd, int argc, char *argv[])
01044 {
01045    int port;
01046    
01047    if (argc != 4)
01048       return RESULT_SHOWUSAGE;
01049    
01050    port = atoi(argv[3]);
01051    
01052    misdn_lib_get_port_up(port);
01053   
01054    return 0;
01055 }
01056 
01057 static int misdn_port_down (int fd, int argc, char *argv[])
01058 {
01059    int port;
01060 
01061    if (argc != 4)
01062       return RESULT_SHOWUSAGE;
01063    
01064    port = atoi(argv[3]);
01065    
01066    misdn_lib_get_port_down(port);
01067   
01068    return 0;
01069 }
01070 
01071 static inline void show_config_description (int fd, enum misdn_cfg_elements elem)
01072 {
01073    char section[BUFFERSIZE];
01074    char name[BUFFERSIZE];
01075    char desc[BUFFERSIZE];
01076    char def[BUFFERSIZE];
01077    char tmp[BUFFERSIZE];
01078 
01079    misdn_cfg_get_name(elem, tmp, sizeof(tmp));
01080    term_color(name, tmp, COLOR_BRWHITE, 0, sizeof(tmp));
01081    misdn_cfg_get_desc(elem, desc, sizeof(desc), def, sizeof(def));
01082 
01083    if (elem < MISDN_CFG_LAST)
01084       term_color(section, "PORTS SECTION", COLOR_YELLOW, 0, sizeof(section));
01085    else
01086       term_color(section, "GENERAL SECTION", COLOR_YELLOW, 0, sizeof(section));
01087 
01088    if (*def)
01089       ast_cli(fd, "[%s] %s   (Default: %s)\n\t%s\n", section, name, def, desc);
01090    else
01091       ast_cli(fd, "[%s] %s\n\t%s\n", section, name, desc);
01092 }
01093 
01094 static int misdn_show_config (int fd, int argc, char *argv[])
01095 {
01096    char buffer[BUFFERSIZE];
01097    enum misdn_cfg_elements elem;
01098    int linebreak;
01099    int onlyport = -1;
01100    int ok = 0;
01101 
01102    if (argc >= 4) {
01103       if (!strcmp(argv[3], "description")) {
01104          if (argc == 5) {
01105             enum misdn_cfg_elements elem = misdn_cfg_get_elem(argv[4]);
01106             if (elem == MISDN_CFG_FIRST)
01107                ast_cli(fd, "Unknown element: %s\n", argv[4]);
01108             else
01109                show_config_description(fd, elem);
01110             return 0;
01111          }
01112          return RESULT_SHOWUSAGE;
01113       }
01114       if (!strcmp(argv[3], "descriptions")) {
01115          if ((argc == 4) || ((argc == 5) && !strcmp(argv[4], "general"))) {
01116             for (elem = MISDN_GEN_FIRST + 1; elem < MISDN_GEN_LAST; ++elem) {
01117                show_config_description(fd, elem);
01118                ast_cli(fd, "\n");
01119             }
01120             ok = 1;
01121          }
01122          if ((argc == 4) || ((argc == 5) && !strcmp(argv[4], "ports"))) {
01123             for (elem = MISDN_CFG_FIRST + 1; elem < MISDN_CFG_LAST - 1 /* the ptp hack, remove the -1 when ptp is gone */; ++elem) {
01124                show_config_description(fd, elem);
01125                ast_cli(fd, "\n");
01126             }
01127             ok = 1;
01128          }
01129          return ok ? 0 : RESULT_SHOWUSAGE;
01130       }
01131       if (!sscanf(argv[3], "%30d", &onlyport) || onlyport < 0) {
01132          ast_cli(fd, "Unknown option: %s\n", argv[3]);
01133          return RESULT_SHOWUSAGE;
01134       }
01135    }
01136    
01137    if (argc == 3 || onlyport == 0) {
01138       ast_cli(fd, "Misdn General-Config:\n");
01139       for (elem = MISDN_GEN_FIRST + 1, linebreak = 1; elem < MISDN_GEN_LAST; elem++, linebreak++) {
01140          misdn_cfg_get_config_string(0, elem, buffer, BUFFERSIZE);
01141          ast_cli(fd, "%-36s%s", buffer, !(linebreak % 2) ? "\n" : "");
01142       }
01143       ast_cli(fd, "\n");
01144    }
01145 
01146    if (onlyport < 0) {
01147       int port = misdn_cfg_get_next_port(0);
01148       for (; port > 0; port = misdn_cfg_get_next_port(port)) {
01149          ast_cli(fd, "\n[PORT %d]\n", port);
01150          for (elem = MISDN_CFG_FIRST + 1, linebreak = 1; elem < MISDN_CFG_LAST; elem++, linebreak++) {
01151             misdn_cfg_get_config_string(port, elem, buffer, BUFFERSIZE);
01152             ast_cli(fd, "%-36s%s", buffer, !(linebreak % 2) ? "\n" : "");
01153          }  
01154          ast_cli(fd, "\n");
01155       }
01156    }
01157    
01158    if (onlyport > 0) {
01159       if (misdn_cfg_is_port_valid(onlyport)) {
01160          ast_cli(fd, "[PORT %d]\n", onlyport);
01161          for (elem = MISDN_CFG_FIRST + 1, linebreak = 1; elem < MISDN_CFG_LAST; elem++, linebreak++) {
01162             misdn_cfg_get_config_string(onlyport, elem, buffer, BUFFERSIZE);
01163             ast_cli(fd, "%-36s%s", buffer, !(linebreak % 2) ? "\n" : "");
01164          }  
01165          ast_cli(fd, "\n");
01166       } else {
01167          ast_cli(fd, "Port %d is not active!\n", onlyport);
01168       }
01169    }
01170 
01171    return 0;
01172 }
01173 
01174 struct state_struct {
01175    enum misdn_chan_state state;
01176    char txt[255];
01177 };
01178 
01179 static struct state_struct state_array[] = {
01180    {MISDN_NOTHING,"NOTHING"}, /* at beginning */
01181    {MISDN_WAITING4DIGS,"WAITING4DIGS"}, /*  when waiting for infos */
01182    {MISDN_EXTCANTMATCH,"EXTCANTMATCH"}, /*  when asterisk couldn't match our ext */
01183    {MISDN_INCOMING_SETUP,"INCOMING SETUP"}, /*  when pbx_start */
01184    {MISDN_DIALING,"DIALING"}, /*  when pbx_start */
01185    {MISDN_PROGRESS,"PROGRESS"}, /*  when pbx_start */
01186    {MISDN_PROCEEDING,"PROCEEDING"}, /*  when pbx_start */
01187    {MISDN_CALLING,"CALLING"}, /*  when misdn_call is called */
01188    {MISDN_CALLING_ACKNOWLEDGE,"CALLING_ACKNOWLEDGE"}, /*  when misdn_call is called */
01189    {MISDN_ALERTING,"ALERTING"}, /*  when Alerting */
01190    {MISDN_BUSY,"BUSY"}, /*  when BUSY */
01191    {MISDN_CONNECTED,"CONNECTED"}, /*  when connected */
01192    {MISDN_DISCONNECTED,"DISCONNECTED"}, /*  when connected */
01193    {MISDN_CLEANING,"CLEANING"}, /* when hangup from * but we were connected before */
01194 };
01195 
01196 static const char *misdn_get_ch_state(struct chan_list *p) 
01197 {
01198    int i;
01199    static char state[8];
01200    
01201    if( !p) return NULL;
01202   
01203    for (i = 0; i < sizeof(state_array) / sizeof(struct state_struct); i++) {
01204       if (state_array[i].state == p->state)
01205          return state_array[i].txt; 
01206    }
01207 
01208    snprintf(state, sizeof(state), "%d", p->state) ;
01209 
01210    return state;
01211 }
01212 
01213 
01214 
01215 static void reload_config(void)
01216 {
01217    int i, cfg_debug;
01218 
01219    if (!g_config_initialized) {
01220       ast_log(LOG_WARNING, "chan_misdn is not initialized properly, still reloading ?\n");
01221       return ;
01222    }
01223    
01224    free_robin_list();
01225    misdn_cfg_reload();
01226    misdn_cfg_update_ptp();
01227    misdn_cfg_get(0, MISDN_GEN_TRACEFILE, global_tracefile, BUFFERSIZE);
01228    misdn_cfg_get(0, MISDN_GEN_DEBUG, &cfg_debug, sizeof(int));
01229 
01230    for (i = 0;  i <= max_ports; i++) {
01231       misdn_debug[i] = cfg_debug;
01232       misdn_debug_only[i] = 0;
01233    }
01234 }
01235 
01236 static int misdn_reload (int fd, int argc, char *argv[])
01237 {
01238    ast_cli(fd, "Reloading mISDN configuration\n");
01239    reload_config();
01240    return 0;
01241 }
01242 
01243 static void print_bc_info (int fd, struct chan_list *help, struct misdn_bchannel *bc)
01244 {
01245    struct ast_channel *ast = help->ast;
01246    ast_cli(fd,
01247       "* Pid:%d Prt:%d Ch:%d Mode:%s Org:%s dad:%s oad:%s rad:%s ctx:%s state:%s\n",
01248 
01249       bc->pid, bc->port, bc->channel,
01250       bc->nt ? "NT" : "TE",
01251       help->originator == ORG_AST ? "*" : "I",
01252       ast ? ast->exten : NULL,
01253       ast ? ast->cid.cid_num : NULL,
01254       bc->rad,
01255       ast ? ast->context : NULL,
01256       misdn_get_ch_state(help)
01257       );
01258    if (misdn_debug[bc->port] > 0)
01259       ast_cli(fd,
01260          "  --> astname: %s\n"
01261          "  --> ch_l3id: %x\n"
01262          "  --> ch_addr: %x\n"
01263          "  --> bc_addr: %x\n"
01264          "  --> bc_l3id: %x\n"
01265          "  --> display: %s\n"
01266          "  --> activated: %d\n"
01267          "  --> state: %s\n"
01268          "  --> capability: %s\n"
01269 #ifdef MISDN_1_2
01270          "  --> pipeline: %s\n"
01271 #else
01272          "  --> echo_cancel: %d\n"
01273 #endif
01274          "  --> notone : rx %d tx:%d\n"
01275          "  --> bc_hold: %d\n",
01276          help->ast->name,
01277          help->l3id,
01278          help->addr,
01279          bc->addr,
01280          bc ? bc->l3_id : -1,
01281          bc->display,
01282          
01283          bc->active,
01284          bc_state2str(bc->bc_state),
01285          bearer2str(bc->capability),
01286 #ifdef MISDN_1_2
01287          bc->pipeline,
01288 #else
01289          bc->ec_enable,
01290 #endif
01291 
01292          help->norxtone, help->notxtone,
01293          bc->holded
01294          );
01295 
01296 }
01297 
01298 static int misdn_show_cls (int fd, int argc, char *argv[])
01299 {
01300    struct chan_list *help;
01301 
01302    help = cl_te;
01303   
01304    ast_cli(fd, "Channel List: %p\n", cl_te);
01305 
01306    for (; help; help = help->next) {
01307       struct misdn_bchannel *bc = help->bc;   
01308       struct ast_channel *ast = help->ast;
01309       if (!ast) {
01310          if (!bc) {
01311             ast_cli(fd, "chan_list obj. with l3id:%x has no bc and no ast Leg\n", help->l3id);
01312             continue;
01313          }
01314          ast_cli(fd, "bc with pid:%d has no Ast Leg\n", bc->pid);
01315          continue;
01316       }
01317 
01318       if (misdn_debug[0] > 2)
01319          ast_cli(fd, "Bc:%p Ast:%p\n", bc, ast);
01320       if (bc) {
01321          print_bc_info(fd, help, bc);
01322       } else {
01323          if (help->hold.state != MISDN_HOLD_IDLE) {
01324             ast_cli(fd, "ITS A HELD CALL BC:\n");
01325             ast_cli(fd, " --> l3_id: %x\n"
01326                   " --> dad:%s oad:%s\n"
01327                   " --> hold_port: %d\n"
01328                   " --> hold_channel: %d\n",
01329                   help->l3id,
01330                   ast->exten,
01331                   ast->cid.cid_num,
01332                   help->hold.port,
01333                   help->hold.channel
01334                   );
01335          } else {
01336             ast_cli(fd, "* Channel in unknown STATE !!! Exten:%s, Callerid:%s\n", ast->exten, ast->cid.cid_num);
01337          }
01338       }
01339    }
01340 
01341    misdn_dump_chanlist();
01342 
01343    return 0;
01344 }
01345 
01346 static int misdn_show_cl (int fd, int argc, char *argv[])
01347 {
01348    struct chan_list *help;
01349 
01350    if (argc != 4)
01351       return RESULT_SHOWUSAGE;
01352 
01353    help = cl_te;
01354 
01355    for (; help; help = help->next) {
01356       struct misdn_bchannel *bc = help->bc;   
01357       struct ast_channel *ast = help->ast;
01358     
01359       if (bc && ast) {
01360          if (!strcasecmp(ast->name,argv[3])) {
01361             print_bc_info(fd, help, bc);
01362             break; 
01363          }
01364       } 
01365    }
01366 
01367    return 0;
01368 }
01369 
01370 ast_mutex_t lock;
01371 int MAXTICS = 8;
01372 
01373 static int misdn_set_tics (int fd, int argc, char *argv[])
01374 {
01375    if (argc != 4)
01376       return RESULT_SHOWUSAGE;
01377 
01378    MAXTICS = atoi(argv[3]);
01379 
01380    return 0;
01381 }
01382 
01383 static int misdn_show_stacks (int fd, int argc, char *argv[])
01384 {
01385    int port;
01386 
01387    ast_cli(fd, "BEGIN STACK_LIST:\n");
01388    for (port = misdn_cfg_get_next_port(0); port > 0;
01389         port = misdn_cfg_get_next_port(port)) {
01390       char buf[128];
01391       get_show_stack_details(port, buf);
01392       ast_cli(fd, "  %s  Debug:%d%s\n", buf, misdn_debug[port], misdn_debug_only[port] ? "(only)" : "");
01393    }
01394 
01395    return 0;
01396 }
01397 
01398 static int misdn_show_ports_stats (int fd, int argc, char *argv[])
01399 {
01400    int port;
01401 
01402    ast_cli(fd, "Port\tin_calls\tout_calls\n");
01403    for (port = misdn_cfg_get_next_port(0); port > 0;
01404         port = misdn_cfg_get_next_port(port)) {
01405       ast_cli(fd, "%d\t%d\t\t%d\n", port, misdn_in_calls[port], misdn_out_calls[port]);
01406    }
01407    ast_cli(fd, "\n");
01408 
01409    return 0;
01410 }
01411 
01412 static int misdn_show_port (int fd, int argc, char *argv[])
01413 {
01414    int port;
01415    char buf[128];
01416 
01417    if (argc != 4)
01418       return RESULT_SHOWUSAGE;
01419 
01420    port = atoi(argv[3]);
01421   
01422    ast_cli(fd, "BEGIN STACK_LIST:\n");
01423    get_show_stack_details(port, buf);
01424    ast_cli(fd, "  %s  Debug:%d%s\n", buf, misdn_debug[port], misdn_debug_only[port] ? "(only)" : "");
01425 
01426    return 0;
01427 }
01428 
01429 static int misdn_send_cd (int fd, int argc, char *argv[])
01430 {
01431    char *channame; 
01432    char *nr;
01433    struct chan_list *tmp;
01434 
01435    if (argc != 5)
01436       return RESULT_SHOWUSAGE;
01437  
01438    
01439    {
01440       channame = argv[3];
01441       nr = argv[4];
01442 
01443       ast_cli(fd, "Sending Calldeflection (%s) to %s\n", nr, channame);
01444       tmp = get_chan_by_ast_name(channame);
01445       if (!tmp) {
01446          ast_cli(fd, "Sending CD with nr %s to %s failed: Channel does not exist.\n",nr, channame);
01447          return 0; 
01448       }
01449 
01450       if (strlen(nr) >= 15) {
01451          ast_cli(fd, "Sending CD with nr %s to %s failed: Number too long (up to 15 digits are allowed).\n",nr, channame);
01452          return 0; 
01453       }
01454       tmp->bc->fac_out.Function = Fac_CD;
01455       ast_copy_string((char *)tmp->bc->fac_out.u.CDeflection.DeflectedToNumber, nr, sizeof(tmp->bc->fac_out.u.CDeflection.DeflectedToNumber));
01456       misdn_lib_send_event(tmp->bc, EVENT_FACILITY);
01457    }
01458 
01459    return 0;
01460 }
01461 
01462 static int misdn_send_restart(int fd, int argc, char *argv[])
01463 {
01464    int port;
01465    int channel;
01466 
01467    if (argc < 4 || argc > 5)
01468       return RESULT_SHOWUSAGE;
01469 
01470    port = atoi(argv[3]);
01471 
01472    if (argc == 5) {
01473       channel = atoi(argv[4]);
01474       misdn_lib_send_restart(port, channel);
01475    } else {
01476       misdn_lib_send_restart(port, -1);
01477    }
01478 
01479    return 0;
01480 }
01481 
01482 static int misdn_send_digit (int fd, int argc, char *argv[])
01483 {
01484    char *channame; 
01485    char *msg; 
01486    struct chan_list *tmp;
01487    int i, msglen;
01488 
01489    if (argc != 5)
01490       return RESULT_SHOWUSAGE;
01491 
01492    channame = argv[3];
01493    msg = argv[4];
01494    msglen = strlen(msg);
01495 
01496    ast_cli(fd, "Sending %s to %s\n", msg, channame);
01497 
01498    tmp = get_chan_by_ast_name(channame);
01499    if (!tmp) {
01500       ast_cli(fd, "Sending %s to %s failed Channel does not exist\n", msg, channame);
01501       return 0; 
01502    }
01503 #if 1
01504    for (i = 0; i < msglen; i++) {
01505       ast_cli(fd, "Sending: %c\n", msg[i]);
01506       send_digit_to_chan(tmp, msg[i]);
01507       /* res = ast_safe_sleep(tmp->ast, 250); */
01508       usleep(250000);
01509       /* res = ast_waitfor(tmp->ast,100); */
01510    }
01511 #else
01512    ast_dtmf_stream(tmp->ast, NULL, msg, 250);
01513 #endif
01514 
01515    return 0;
01516 }
01517 
01518 static int misdn_toggle_echocancel (int fd, int argc, char *argv[])
01519 {
01520    char *channame;
01521    struct chan_list *tmp;
01522 
01523    if (argc != 4)
01524       return RESULT_SHOWUSAGE;
01525 
01526    channame = argv[3];
01527   
01528    ast_cli(fd, "Toggling EchoCancel on %s\n", channame);
01529   
01530    tmp = get_chan_by_ast_name(channame);
01531    if (!tmp) {
01532       ast_cli(fd, "Toggling EchoCancel %s failed Channel does not exist\n", channame);
01533       return 0;
01534    }
01535 
01536    tmp->toggle_ec = tmp->toggle_ec ? 0 : 1;
01537 
01538    if (tmp->toggle_ec) {
01539 #ifdef MISDN_1_2
01540       update_pipeline_config(tmp->bc);
01541 #else
01542       update_ec_config(tmp->bc);
01543 #endif
01544       manager_ec_enable(tmp->bc);
01545    } else {
01546       manager_ec_disable(tmp->bc);
01547    }
01548 
01549    return 0;
01550 }
01551 
01552 static int misdn_send_display (int fd, int argc, char *argv[])
01553 {
01554    char *channame;
01555    char *msg;
01556    struct chan_list *tmp;
01557 
01558    if (argc != 5)
01559       return RESULT_SHOWUSAGE;
01560 
01561    channame = argv[3];
01562    msg = argv[4];
01563 
01564    ast_cli(fd, "Sending %s to %s\n", msg, channame);
01565    tmp = get_chan_by_ast_name(channame);
01566     
01567    if (tmp && tmp->bc) {
01568       ast_copy_string(tmp->bc->display, msg, sizeof(tmp->bc->display));
01569       misdn_lib_send_event(tmp->bc, EVENT_INFORMATION);
01570    } else {
01571       ast_cli(fd, "No such channel %s\n", channame);
01572       return RESULT_FAILURE;
01573    }
01574 
01575    return RESULT_SUCCESS;
01576 }
01577 
01578 static char *complete_ch_helper(const char *line, const char *word, int pos, int state, int rpos)
01579 {
01580    struct ast_channel *c;
01581    int which=0;
01582    char *ret;
01583    if (pos != rpos)
01584       return NULL;
01585    c = ast_channel_walk_locked(NULL);
01586    while(c) {
01587       if (!strncasecmp(word, c->name, strlen(word))) {
01588          if (++which > state)
01589             break;
01590       }
01591       ast_mutex_unlock(&c->lock);
01592       c = ast_channel_walk_locked(c);
01593    }
01594    if (c) {
01595       ret = strdup(c->name);
01596       ast_mutex_unlock(&c->lock);
01597    } else
01598       ret = NULL;
01599    return ret;
01600 }
01601 
01602 static char *complete_ch(const char *line, const char *word, int pos, int state)
01603 {
01604    return complete_ch_helper(line, word, pos, state, 3);
01605 }
01606 
01607 static char *complete_debug_port (const char *line, const char *word, int pos, int state)
01608 {
01609    if (state)
01610       return NULL;
01611 
01612    switch (pos) {
01613    case 4:
01614       if (*word == 'p')
01615          return strdup("port");
01616       else if (*word == 'o')
01617          return strdup("only");
01618       break;
01619    case 6:
01620       if (*word == 'o')
01621          return strdup("only");
01622       break;
01623    }
01624    return NULL;
01625 }
01626 
01627 static char *complete_show_config (const char *line, const char *word, int pos, int state)
01628 {
01629    char buffer[BUFFERSIZE];
01630    enum misdn_cfg_elements elem;
01631    int wordlen = strlen(word);
01632    int which = 0;
01633    int port = 0;
01634 
01635    switch (pos) {
01636    case 3:
01637       if ((!strncmp(word, "description", wordlen)) && (++which > state))
01638          return strdup("description");
01639       if ((!strncmp(word, "descriptions", wordlen)) && (++which > state))
01640          return strdup("descriptions");
01641       if ((!strncmp(word, "0", wordlen)) && (++which > state))
01642          return strdup("0");
01643       while ((port = misdn_cfg_get_next_port(port)) != -1) {
01644          snprintf(buffer, sizeof(buffer), "%d", port);
01645          if ((!strncmp(word, buffer, wordlen)) && (++which > state)) {
01646             return strdup(buffer);
01647          }
01648       }
01649       break;
01650    case 4:
01651       if (strstr(line, "description ")) {
01652          for (elem = MISDN_CFG_FIRST + 1; elem < MISDN_GEN_LAST; ++elem) {
01653             if ((elem == MISDN_CFG_LAST) || (elem == MISDN_GEN_FIRST))
01654                continue;
01655             misdn_cfg_get_name(elem, buffer, BUFFERSIZE);
01656             if (!wordlen || !strncmp(word, buffer, wordlen)) {
01657                if (++which > state)
01658                   return strdup(buffer);
01659             }
01660          }
01661       } else if (strstr(line, "descriptions ")) {
01662          if ((!wordlen || !strncmp(word, "general", wordlen)) && (++which > state))
01663             return strdup("general");
01664          if ((!wordlen || !strncmp(word, "ports", wordlen)) && (++which > state))
01665             return strdup("ports");
01666       }
01667       break;
01668    }
01669    return NULL;
01670 }
01671 
01672 static struct ast_cli_entry chan_misdn_clis[] = {
01673    { {"misdn","send","calldeflect", NULL}, misdn_send_cd, "Sends CallDeflection to mISDN Channel",
01674       "Usage: misdn send calldeflect <channel> \"<nr>\" \n", complete_ch },
01675    { {"misdn","send","digit", NULL}, misdn_send_digit,   "Sends DTMF Digit to mISDN Channel",
01676       "Usage: misdn send digit <channel> \"<msg>\" \n"
01677       "       Send <digit> to <channel> as DTMF Tone\n"
01678       "       when channel is a mISDN channel\n", complete_ch },
01679    { {"misdn","toggle","echocancel", NULL}, misdn_toggle_echocancel, "Toggles EchoCancel on mISDN Channel",
01680       "Usage: misdn toggle echocancel <channel>\n", complete_ch },
01681    { {"misdn","send","display", NULL}, misdn_send_display, "Sends Text to mISDN Channel", 
01682       "Usage: misdn send display <channel> \"<msg>\" \n"
01683       "       Send <msg> to <channel> as Display Message\n"
01684       "       when channel is a mISDN channel\n", complete_ch },
01685    { {"misdn","show","config", NULL}, misdn_show_config, "Shows internal mISDN config, read from cfg-file",
01686       "Usage: misdn show config [<port> | description <config element> | descriptions [general|ports]]\n"
01687       "       Use 0 for <port> to only print the general config.\n", complete_show_config },
01688    { {"misdn","reload", NULL}, misdn_reload, "Reloads internal mISDN config, read from cfg-file",
01689       "Usage: misdn reload\n" },
01690    { {"misdn","set","tics", NULL}, misdn_set_tics, "", 
01691       "\n" },
01692    { {"misdn","show","channels", NULL}, misdn_show_cls, "Shows internal mISDN chan_list",
01693       "Usage: misdn show channels\n" },
01694    { {"misdn","show","channel", NULL}, misdn_show_cl, "Shows internal mISDN chan_list",
01695       "Usage: misdn show channels\n", complete_ch },
01696    { {"misdn","port","block", NULL}, misdn_port_block, "Blocks the given port",
01697       "Usage: misdn port block\n" },
01698    { {"misdn","port","unblock", NULL}, misdn_port_unblock, "Unblocks the given port",
01699       "Usage: misdn port unblock\n" },
01700    { {"misdn","restart","port", NULL}, misdn_restart_port, "Restarts the given port",
01701       "Usage: misdn restart port\n" },
01702    { {"misdn","restart","pid", NULL}, misdn_restart_pid, "Restarts the given pid",
01703       "Usage: misdn restart pid\n" },
01704    { {"misdn","send","restart", NULL},  misdn_send_restart, 
01705      "Sends a restart for every bchannel on the given port", 
01706      "Usage: misdn send restart <port>\n"},
01707    { {"misdn","port","up", NULL}, misdn_port_up, "Tries to establish L1 on the given port",
01708       "Usage: misdn port up <port>\n" },
01709    { {"misdn","port","down", NULL}, misdn_port_down, "Tries to deactivate the L1 on the given port",
01710       "Usage: misdn port down <port>\n" },
01711    { {"misdn","show","stacks", NULL}, misdn_show_stacks, "Shows internal mISDN stack_list",
01712       "Usage: misdn show stacks\n" },
01713    { {"misdn","show","ports","stats", NULL}, misdn_show_ports_stats, "Shows chan_misdns call statistics per port",
01714       "Usage: misdn show port stats\n" },
01715    { {"misdn","show","port", NULL}, misdn_show_port, "Shows detailed information for given port",
01716       "Usage: misdn show port <port>\n" },
01717    { {"misdn","set","debug", NULL}, misdn_set_debug, "Sets Debuglevel of chan_misdn",
01718       "Usage: misdn set debug <level> [only] | [port <port> [only]]\n", complete_debug_port },
01719    { {"misdn","set","crypt","debug", NULL}, misdn_set_crypt_debug, "Sets CryptDebuglevel of chan_misdn, at the moment, level={1,2}",
01720       "Usage: misdn set crypt debug <level>\n" }
01721 };
01722 
01723 /*! \brief Updates caller ID information from config */
01724 static int update_config(struct chan_list *ch, int orig) 
01725 {
01726    struct ast_channel *ast;
01727    struct misdn_bchannel *bc;
01728    int port, hdlc = 0;
01729    int pres, screen;
01730 
01731    if (!ch) {
01732       ast_log(LOG_WARNING, "Cannot configure without chanlist\n");
01733       return -1;
01734    }
01735 
01736    ast = ch->ast;
01737    bc = ch->bc;
01738    if (! ast || ! bc) {
01739       ast_log(LOG_WARNING, "Cannot configure without ast || bc\n");
01740       return -1;
01741    }
01742 
01743    port = bc->port;
01744 
01745    chan_misdn_log(7, port, "update_config: Getting Config\n");
01746 
01747    misdn_cfg_get(port, MISDN_CFG_HDLC, &hdlc, sizeof(int));
01748    
01749    if (hdlc) {
01750       switch (bc->capability) {
01751       case INFO_CAPABILITY_DIGITAL_UNRESTRICTED:
01752       case INFO_CAPABILITY_DIGITAL_RESTRICTED:
01753          chan_misdn_log(1, bc->port, " --> CONF HDLC\n");
01754          bc->hdlc = 1;
01755          break;
01756       }
01757    }
01758 
01759 
01760    misdn_cfg_get(port, MISDN_CFG_PRES, &pres, sizeof(pres));
01761    misdn_cfg_get(port, MISDN_CFG_SCREEN, &screen, sizeof(screen));
01762    chan_misdn_log(2, port, " --> pres: %d screen: %d\n", pres, screen);
01763       
01764    if (pres < 0 || screen < 0) {
01765       chan_misdn_log(2, port, " --> pres: %x\n", ast->cid.cid_pres);
01766          
01767       switch (ast->cid.cid_pres & 0x60) {
01768       case AST_PRES_RESTRICTED:
01769          bc->pres = 1;
01770          chan_misdn_log(2, port, " --> PRES: Restricted (1)\n");
01771          break;
01772       case AST_PRES_UNAVAILABLE:
01773          bc->pres = 2;
01774          chan_misdn_log(2, port, " --> PRES: Unavailable (2)\n");
01775          break;
01776       default:
01777          bc->pres = 0;
01778          chan_misdn_log(2, port, " --> PRES: Allowed (0)\n");
01779          break;
01780       }
01781 
01782       switch (ast->cid.cid_pres & 0x3) {
01783       default:
01784       case AST_PRES_USER_NUMBER_UNSCREENED:
01785          bc->screen = 0;
01786          chan_misdn_log(2, port, " --> SCREEN: Unscreened (0)\n");
01787          break;
01788       case AST_PRES_USER_NUMBER_PASSED_SCREEN:
01789          bc->screen = 1;
01790          chan_misdn_log(2, port, " --> SCREEN: Passed Screen (1)\n");
01791          break;
01792       case AST_PRES_USER_NUMBER_FAILED_SCREEN:
01793          bc->screen = 2;
01794          chan_misdn_log(2, port, " --> SCREEN: Failed Screen (2)\n");
01795          break;
01796       case AST_PRES_NETWORK_NUMBER:
01797          bc->screen = 3;
01798          chan_misdn_log(2, port, " --> SCREEN: Network Nr. (3)\n");
01799          break;
01800       }
01801    } else {
01802       bc->screen = screen;
01803       bc->pres = pres;
01804    }
01805 
01806    return 0;
01807 }
01808 
01809 
01810 static void config_jitterbuffer(struct chan_list *ch)
01811 {
01812    struct misdn_bchannel *bc = ch->bc;
01813    int len = ch->jb_len, threshold = ch->jb_upper_threshold;
01814    
01815    chan_misdn_log(5, bc->port, "config_jb: Called\n");
01816    
01817    if (! len) {
01818       chan_misdn_log(1, bc->port, "config_jb: Deactivating Jitterbuffer\n");
01819       bc->nojitter=1;
01820    } else {
01821       if (len <= 100 || len > 8000) {
01822          chan_misdn_log(0, bc->port, "config_jb: Jitterbuffer out of Bounds, setting to 1000\n");
01823          len = 1000;
01824       }
01825 
01826       if ( threshold > len ) {
01827          chan_misdn_log(0, bc->port, "config_jb: Jitterbuffer Threshold > Jitterbuffer setting to Jitterbuffer -1\n");
01828       }
01829 
01830       if ( ch->jb) {
01831          cb_log(0, bc->port, "config_jb: We've got a Jitterbuffer Already on this port.\n");
01832          misdn_jb_destroy(ch->jb);
01833          ch->jb = NULL;
01834       }
01835 
01836       ch->jb=misdn_jb_init(len, threshold);
01837 
01838       if (!ch->jb ) 
01839          bc->nojitter = 1;
01840    }
01841 }
01842 
01843 
01844 void debug_numplan(int port, int numplan, char *type)
01845 {
01846    switch (numplan) {
01847    case NUMPLAN_INTERNATIONAL:
01848       chan_misdn_log(2, port, " --> %s: International\n", type);
01849       break;
01850    case NUMPLAN_NATIONAL:
01851       chan_misdn_log(2, port, " --> %s: National\n", type);
01852       break;
01853    case NUMPLAN_SUBSCRIBER:
01854       chan_misdn_log(2, port, " --> %s: Subscriber\n", type);
01855       break;
01856    case NUMPLAN_UNKNOWN:
01857       chan_misdn_log(2, port, " --> %s: Unknown\n", type);
01858       break;
01859       /* Maybe we should cut off the prefix if present ? */
01860    default:
01861       chan_misdn_log(0, port, " --> !!!! Wrong dialplan setting, please see the misdn.conf sample file\n ");
01862       break;
01863    }
01864 }
01865 
01866 
01867 #ifdef MISDN_1_2
01868 static int update_pipeline_config(struct misdn_bchannel *bc)
01869 {
01870    int ec;
01871 
01872    misdn_cfg_get(bc->port, MISDN_CFG_PIPELINE, bc->pipeline, sizeof(bc->pipeline));
01873 
01874    if (*bc->pipeline)
01875       return 0;
01876 
01877    misdn_cfg_get(bc->port, MISDN_CFG_ECHOCANCEL, &ec, sizeof(int));
01878    if (ec == 1)
01879       ast_copy_string(bc->pipeline, "mg2ec", sizeof(bc->pipeline));
01880    else if (ec > 1)
01881       snprintf(bc->pipeline, sizeof(bc->pipeline), "mg2ec(deftaps=%d)", ec);
01882 
01883    return 0;
01884 }
01885 #else
01886 static int update_ec_config(struct misdn_bchannel *bc)
01887 {
01888    int ec;
01889    int port = bc->port;
01890 
01891    misdn_cfg_get(port, MISDN_CFG_ECHOCANCEL, &ec, sizeof(int));
01892 
01893    if (ec == 1) {
01894       bc->ec_enable = 1;
01895    } else if (ec > 1) {
01896       bc->ec_enable = 1;
01897       bc->ec_deftaps = ec;
01898    }
01899 
01900    return 0;
01901 }
01902 #endif
01903 
01904 
01905 static int read_config(struct chan_list *ch, int orig)
01906 {
01907    struct ast_channel *ast;
01908    struct misdn_bchannel *bc;
01909    int port;
01910    int hdlc = 0;
01911    char lang[BUFFERSIZE + 1];
01912    char faxdetect[BUFFERSIZE + 1];
01913    char buf[256];
01914    char buf2[256];
01915    ast_group_t pg;
01916    ast_group_t cg;
01917 
01918    if (!ch) {
01919       ast_log(LOG_WARNING, "Cannot configure without chanlist\n");
01920       return -1;
01921    }
01922 
01923    ast = ch->ast;
01924    bc = ch->bc;
01925    if (! ast || ! bc) {
01926       ast_log(LOG_WARNING, "Cannot configure without ast || bc\n");
01927       return -1;
01928    }
01929    
01930    port = bc->port;
01931    chan_misdn_log(1, port, "read_config: Getting Config\n");
01932 
01933    misdn_cfg_get(port, MISDN_CFG_LANGUAGE, lang, BUFFERSIZE);
01934    ast_string_field_set(ast, language, lang);
01935 
01936    misdn_cfg_get(port, MISDN_CFG_MUSICCLASS, ch->mohinterpret, sizeof(ch->mohinterpret));
01937 
01938    misdn_cfg_get(port, MISDN_CFG_TXGAIN, &bc->txgain, sizeof(int));
01939    misdn_cfg_get(port, MISDN_CFG_RXGAIN, &bc->rxgain, sizeof(int));
01940 
01941    misdn_cfg_get(port, MISDN_CFG_INCOMING_EARLY_AUDIO, &ch->incoming_early_audio, sizeof(int));
01942 
01943    misdn_cfg_get(port, MISDN_CFG_SENDDTMF, &bc->send_dtmf, sizeof(int));
01944    
01945    misdn_cfg_get(port, MISDN_CFG_ASTDTMF, &ch->ast_dsp, sizeof(int));
01946 
01947    if (ch->ast_dsp) {
01948       ch->ignore_dtmf = 1;
01949    }
01950 
01951    misdn_cfg_get(port, MISDN_CFG_NEED_MORE_INFOS, &bc->need_more_infos, sizeof(int));
01952    misdn_cfg_get(port, MISDN_CFG_NTTIMEOUT, &ch->nttimeout, sizeof(int));
01953 
01954    misdn_cfg_get(port, MISDN_CFG_NOAUTORESPOND_ON_SETUP, &ch->noautorespond_on_setup, sizeof(int));
01955 
01956    misdn_cfg_get(port, MISDN_CFG_FAR_ALERTING, &ch->far_alerting, sizeof(int));
01957 
01958    misdn_cfg_get(port, MISDN_CFG_ALLOWED_BEARERS, &ch->allowed_bearers, BUFFERSIZE);
01959 
01960    misdn_cfg_get(port, MISDN_CFG_FAXDETECT, faxdetect, BUFFERSIZE);
01961 
01962    misdn_cfg_get(port, MISDN_CFG_HDLC, &hdlc, sizeof(int));
01963 
01964    if (hdlc) {
01965       switch (bc->capability) {
01966       case INFO_CAPABILITY_DIGITAL_UNRESTRICTED:
01967       case INFO_CAPABILITY_DIGITAL_RESTRICTED:
01968          chan_misdn_log(1, bc->port, " --> CONF HDLC\n");
01969          bc->hdlc = 1;
01970          break;
01971       }
01972       
01973    }
01974    /*Initialize new Jitterbuffer*/
01975    misdn_cfg_get(port, MISDN_CFG_JITTERBUFFER, &ch->jb_len, sizeof(int));
01976    misdn_cfg_get(port, MISDN_CFG_JITTERBUFFER_UPPER_THRESHOLD, &ch->jb_upper_threshold, sizeof(int));
01977 
01978    config_jitterbuffer(ch);
01979 
01980    misdn_cfg_get(bc->port, MISDN_CFG_CONTEXT, ch->context, sizeof(ch->context));
01981 
01982    ast_copy_string(ast->context, ch->context, sizeof(ast->context));
01983 
01984 #ifdef MISDN_1_2
01985    update_pipeline_config(bc);
01986 #else
01987    update_ec_config(bc);
01988 #endif
01989 
01990    {
01991       int eb3;
01992       
01993       misdn_cfg_get( bc->port, MISDN_CFG_EARLY_BCONNECT, &eb3, sizeof(int));
01994       bc->early_bconnect=eb3;
01995    }
01996 
01997    misdn_cfg_get(port, MISDN_CFG_PICKUPGROUP, &pg, sizeof(pg));
01998    misdn_cfg_get(port, MISDN_CFG_CALLGROUP, &cg, sizeof(cg));
01999 
02000    chan_misdn_log(5, port, " --> * CallGrp:%s PickupGrp:%s\n", ast_print_group(buf, sizeof(buf), cg), ast_print_group(buf2, sizeof(buf2), pg));
02001    ast->pickupgroup = pg;
02002    ast->callgroup = cg;
02003    
02004    if (orig == ORG_AST) {
02005       char callerid[BUFFERSIZE + 1];
02006 
02007       /* ORIGINATOR Asterisk (outgoing call) */
02008 
02009       misdn_cfg_get(port, MISDN_CFG_TE_CHOOSE_CHANNEL, &(bc->te_choose_channel), sizeof(int));
02010 
02011       if (strstr(faxdetect, "outgoing") || strstr(faxdetect, "both")) {
02012          if (strstr(faxdetect, "nojump"))
02013             ch->faxdetect = 2;
02014          else
02015             ch->faxdetect = 1;
02016       }
02017 
02018       misdn_cfg_get(port, MISDN_CFG_CALLERID, callerid, BUFFERSIZE);
02019       if ( ! ast_strlen_zero(callerid) ) {
02020          chan_misdn_log(1, port, " --> * Setting Cid to %s\n", callerid);
02021          ast_copy_string(bc->oad, callerid, sizeof(bc->oad));
02022       }
02023 
02024       misdn_cfg_get(port, MISDN_CFG_DIALPLAN, &bc->dnumplan, sizeof(int));
02025       misdn_cfg_get(port, MISDN_CFG_LOCALDIALPLAN, &bc->onumplan, sizeof(int));
02026       misdn_cfg_get(port, MISDN_CFG_CPNDIALPLAN, &bc->cpnnumplan, sizeof(int));
02027       debug_numplan(port, bc->dnumplan, "TON");
02028       debug_numplan(port, bc->onumplan, "LTON");
02029       debug_numplan(port, bc->cpnnumplan, "CTON");
02030 
02031       ch->overlap_dial = 0;
02032    } else {
02033       /* ORIGINATOR MISDN (incoming call) */
02034       char prefix[BUFFERSIZE + 1] = "";
02035 
02036       if (strstr(faxdetect, "incoming") || strstr(faxdetect, "both")) {
02037          if (strstr(faxdetect, "nojump"))
02038             ch->faxdetect = 2;
02039          else
02040             ch->faxdetect = 1;
02041       }
02042 
02043       misdn_cfg_get(port, MISDN_CFG_CPNDIALPLAN, &bc->cpnnumplan, sizeof(int));
02044       debug_numplan(port, bc->cpnnumplan, "CTON");
02045 
02046       switch (bc->onumplan) {
02047       case NUMPLAN_INTERNATIONAL:
02048          misdn_cfg_get(bc->port, MISDN_CFG_INTERNATPREFIX, prefix, BUFFERSIZE);
02049          break;
02050 
02051       case NUMPLAN_NATIONAL:
02052          misdn_cfg_get(bc->port, MISDN_CFG_NATPREFIX, prefix, BUFFERSIZE);
02053          break;
02054       default:
02055          break;
02056       }
02057 
02058       ast_copy_string(buf, bc->oad, sizeof(buf));
02059       snprintf(bc->oad, sizeof(bc->oad), "%s%s", prefix, buf);
02060 
02061       if (!ast_strlen_zero(bc->dad)) {
02062          ast_copy_string(bc->orig_dad, bc->dad, sizeof(bc->orig_dad));
02063       }
02064 
02065       if ( ast_strlen_zero(bc->dad) && !ast_strlen_zero(bc->keypad)) {
02066          ast_copy_string(bc->dad, bc->keypad, sizeof(bc->dad));
02067       }
02068 
02069       prefix[0] = 0;
02070 
02071       switch (bc->dnumplan) {
02072       case NUMPLAN_INTERNATIONAL:
02073          misdn_cfg_get(bc->port, MISDN_CFG_INTERNATPREFIX, prefix, BUFFERSIZE);
02074          break;
02075       case NUMPLAN_NATIONAL:
02076          misdn_cfg_get(bc->port, MISDN_CFG_NATPREFIX, prefix, BUFFERSIZE);
02077          break;
02078       default:
02079          break;
02080       }
02081 
02082       ast_copy_string(buf, bc->dad, sizeof(buf));
02083       snprintf(bc->dad, sizeof(bc->dad), "%s%s", prefix, buf);
02084 
02085       if (strcmp(bc->dad, ast->exten)) {
02086          ast_copy_string(ast->exten, bc->dad, sizeof(ast->exten));
02087       }
02088 
02089       ast_set_callerid(ast, bc->oad, NULL, bc->oad);
02090 
02091       if ( !ast_strlen_zero(bc->rad) ) {
02092          if (ast->cid.cid_rdnis)
02093             free(ast->cid.cid_rdnis);
02094          ast->cid.cid_rdnis = strdup(bc->rad);
02095       }
02096    
02097       misdn_cfg_get(bc->port, MISDN_CFG_OVERLAP_DIAL, &ch->overlap_dial, sizeof(ch->overlap_dial));
02098       ast_mutex_init(&ch->overlap_tv_lock);
02099    } /* ORIG MISDN END */
02100 
02101    ch->overlap_dial_task = -1;
02102    
02103    if (ch->faxdetect  || ch->ast_dsp) {
02104       misdn_cfg_get(port, MISDN_CFG_FAXDETECT_TIMEOUT, &ch->faxdetect_timeout, sizeof(ch->faxdetect_timeout));
02105       if (!ch->dsp)
02106          ch->dsp = ast_dsp_new();
02107       if (ch->dsp) {
02108          if (ch->faxdetect) 
02109             ast_dsp_set_features(ch->dsp, DSP_FEATURE_DTMF_DETECT | DSP_FEATURE_FAX_DETECT);
02110          else 
02111             ast_dsp_set_features(ch->dsp, DSP_FEATURE_DTMF_DETECT );
02112       }
02113    }
02114 
02115    /* AOCD initialization */
02116    bc->AOCDtype = Fac_None;
02117 
02118    return 0;
02119 }
02120 
02121 
02122 /*****************************/
02123 /*** AST Indications Start ***/
02124 /*****************************/
02125 
02126 static int misdn_call(struct ast_channel *ast, char *dest, int timeout)
02127 {
02128    int port = 0;
02129    int r;
02130    int exceed;
02131    int bridging;
02132    struct chan_list *ch;
02133    struct misdn_bchannel *newbc;
02134    char *opts, *ext;
02135    char *dest_cp;
02136 
02137    if (!ast) {
02138       ast_log(LOG_WARNING, " --> ! misdn_call called on ast_channel *ast where ast == NULL\n");
02139       return -1;
02140    }
02141 
02142    if (((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) || !dest  ) {
02143       ast_log(LOG_WARNING, " --> ! misdn_call called on %s, neither down nor reserved (or dest==NULL)\n", ast->name);
02144       ast->hangupcause = AST_CAUSE_NORMAL_TEMPORARY_FAILURE;
02145       ast_setstate(ast, AST_STATE_DOWN);
02146       return -1;
02147    }
02148 
02149    ch = MISDN_ASTERISK_TECH_PVT(ast);
02150    if (!ch) {
02151       ast_log(LOG_WARNING, " --> ! misdn_call called on %s, neither down nor reserved (or dest==NULL)\n", ast->name);
02152       ast->hangupcause = AST_CAUSE_NORMAL_TEMPORARY_FAILURE;
02153       ast_setstate(ast, AST_STATE_DOWN);
02154       return -1;
02155    }
02156    
02157    newbc = ch->bc;
02158    if (!newbc) {
02159       ast_log(LOG_WARNING, " --> ! misdn_call called on %s, neither down nor reserved (or dest==NULL)\n", ast->name);
02160       ast->hangupcause = AST_CAUSE_NORMAL_TEMPORARY_FAILURE;
02161       ast_setstate(ast, AST_STATE_DOWN);
02162       return -1;
02163    }
02164    
02165    /*
02166     * dest is ---v
02167     * Dial(mISDN/g:group_name[/extension[/options]])
02168     * Dial(mISDN/port[:preselected_channel][/extension[/options]])
02169     *
02170     * The dial extension could be empty if you are using MISDN_KEYPAD
02171     * to control ISDN provider features.
02172     */
02173    dest_cp = ast_strdupa(dest);
02174    strsep(&dest_cp, "/");/* Discard port/group token */
02175    ext = strsep(&dest_cp, "/");
02176    if (!ext) {
02177       ext = "";
02178    }
02179    opts = dest_cp;
02180    
02181    port = newbc->port;
02182 
02183    if ((exceed = add_out_calls(port))) {
02184       char tmp[16];
02185       snprintf(tmp, sizeof(tmp), "%d", exceed);
02186       pbx_builtin_setvar_helper(ast, "MAX_OVERFLOW", tmp);
02187       return -1;
02188    }
02189    
02190    chan_misdn_log(1, port, "* CALL: %s\n", dest);
02191    
02192    chan_misdn_log(2, port, " --> * dad:%s tech:%s ctx:%s\n", ast->exten, ast->name, ast->context);
02193    
02194    chan_misdn_log(3, port, " --> * adding2newbc ext %s\n", ast->exten);
02195    if (ast->exten) {
02196       ast_copy_string(ast->exten, ext, sizeof(ast->exten));
02197       ast_copy_string(newbc->dad, ext, sizeof(newbc->dad));
02198    }
02199 
02200    ast_copy_string(newbc->rad, S_OR(ast->cid.cid_rdnis, ""), sizeof(newbc->rad));
02201 
02202    chan_misdn_log(3, port, " --> * adding2newbc callerid %s\n", ast->cid.cid_num);
02203    if (ast_strlen_zero(newbc->oad) && !ast_strlen_zero(ast->cid.cid_num)) {
02204       ast_copy_string(newbc->oad, ast->cid.cid_num, sizeof(newbc->oad));
02205    }
02206 
02207    newbc->capability = ast->transfercapability;
02208    pbx_builtin_setvar_helper(ast, "TRANSFERCAPABILITY", ast_transfercapability2str(newbc->capability));
02209    if ( ast->transfercapability == INFO_CAPABILITY_DIGITAL_UNRESTRICTED) {
02210       chan_misdn_log(2, port, " --> * Call with flag Digital\n");
02211    }
02212 
02213    /* update screening and presentation */ 
02214    update_config(ch, ORG_AST);
02215       
02216    /* fill in some ies from channel vary*/
02217    import_ch(ast, newbc, ch);
02218 
02219    /* Finally The Options Override Everything */
02220    if (opts)
02221       misdn_set_opt_exec(ast, opts);
02222    else
02223       chan_misdn_log(2, port, "NO OPTS GIVEN\n");
02224 
02225    /*check for bridging*/
02226    misdn_cfg_get(0, MISDN_GEN_BRIDGING, &bridging, sizeof(bridging));
02227    if (bridging && ch->other_ch) {
02228 #ifdef MISDN_1_2
02229       chan_misdn_log(1, port, "Disabling EC (aka Pipeline) on both Sides\n");
02230       *ch->bc->pipeline = 0;
02231       *ch->other_ch->bc->pipeline = 0;
02232 #else
02233       chan_misdn_log(1, port, "Disabling EC on both Sides\n");
02234       ch->bc->ec_enable = 0;
02235       ch->other_ch->bc->ec_enable = 0;
02236 #endif
02237    }
02238 
02239    r = misdn_lib_send_event( newbc, EVENT_SETUP );
02240 
02241    /** we should have l3id after sending setup **/
02242    ch->l3id = newbc->l3_id;
02243 
02244    if ( r == -ENOCHAN  ) {
02245       chan_misdn_log(0, port, " --> * Theres no Channel at the moment .. !\n");
02246       chan_misdn_log(1, port, " --> * SEND: State Down pid:%d\n", newbc ? newbc->pid : -1);
02247       ast->hangupcause = AST_CAUSE_NORMAL_CIRCUIT_CONGESTION;
02248       ast_setstate(ast, AST_STATE_DOWN);
02249       return -1;
02250    }
02251    
02252    chan_misdn_log(2, port, " --> * SEND: State Dialing pid:%d\n", newbc ? newbc->pid : 1);
02253 
02254    ast_setstate(ast, AST_STATE_DIALING);
02255    ast->hangupcause = AST_CAUSE_NORMAL_CLEARING;
02256    
02257    if (newbc->nt)
02258       stop_bc_tones(ch);
02259 
02260    ch->state = MISDN_CALLING;
02261    
02262    return 0; 
02263 }
02264 
02265 
02266 static int misdn_answer(struct ast_channel *ast)
02267 {
02268    struct chan_list *p;
02269    const char *tmp;
02270 
02271    if (!ast || !(p = MISDN_ASTERISK_TECH_PVT(ast))) return -1;
02272    
02273    chan_misdn_log(1, p ? (p->bc ? p->bc->port : 0) : 0, "* ANSWER:\n");
02274    
02275    if (!p) {
02276       ast_log(LOG_WARNING, " --> Channel not connected ??\n");
02277       ast_queue_hangup(ast);
02278    }
02279 
02280    if (!p->bc) {
02281       chan_misdn_log(1, 0, " --> Got Answer, but there is no bc obj ??\n");
02282 
02283       ast_queue_hangup(ast);
02284    }
02285 
02286    tmp = pbx_builtin_getvar_helper(p->ast, "CRYPT_KEY");
02287    if (!ast_strlen_zero(tmp)) {
02288       chan_misdn_log(1, p->bc->port, " --> Connection will be BF crypted\n");
02289       ast_copy_string(p->bc->crypt_key, tmp, sizeof(p->bc->crypt_key));
02290    } else {
02291       chan_misdn_log(3, p->bc->port, " --> Connection is without BF encryption\n");
02292    }
02293 
02294    tmp = pbx_builtin_getvar_helper(ast, "MISDN_DIGITAL_TRANS");
02295    if (!ast_strlen_zero(tmp) && ast_true(tmp)) {
02296       chan_misdn_log(1, p->bc->port, " --> Connection is transparent digital\n");
02297       p->bc->nodsp = 1;
02298       p->bc->hdlc = 0;
02299       p->bc->nojitter = 1;
02300    }
02301 
02302    p->state = MISDN_CONNECTED;
02303    stop_indicate(p);
02304 
02305    if ( ast_strlen_zero(p->bc->cad) ) {
02306       chan_misdn_log(2,p->bc->port," --> empty cad using dad\n");
02307       ast_copy_string(p->bc->cad, p->bc->dad, sizeof(p->bc->cad));
02308    }
02309 
02310    misdn_lib_send_event( p->bc, EVENT_CONNECT);
02311    start_bc_tones(p);
02312 
02313    return 0;
02314 }
02315 
02316 static int misdn_digit_begin(struct ast_channel *chan, char digit)
02317 {
02318    /* XXX Modify this callback to support Asterisk controlling the length of DTMF */
02319    return 0;
02320 }
02321 
02322 static int misdn_digit_end(struct ast_channel *ast, char digit, unsigned int duration)
02323 {
02324    struct chan_list *p;
02325    struct misdn_bchannel *bc;
02326 
02327    if (!ast || !(p = MISDN_ASTERISK_TECH_PVT(ast))) return -1;
02328 
02329    bc = p->bc;
02330    chan_misdn_log(1, bc ? bc->port : 0, "* IND : Digit %c\n", digit);
02331    
02332    if (!bc) {
02333       ast_log(LOG_WARNING, " --> !! Got Digit Event without having bchannel Object\n");
02334       return -1;
02335    }
02336    
02337    switch (p->state ) {
02338    case MISDN_CALLING:
02339       {
02340          int l;      
02341          char buf[8];
02342          buf[0]=digit;
02343          buf[1]=0;
02344          
02345          l = sizeof(bc->infos_pending);
02346          strncat(bc->infos_pending, buf, l - strlen(bc->infos_pending) - 1);
02347       }
02348       break;
02349    case MISDN_CALLING_ACKNOWLEDGE:
02350       {
02351          bc->info_dad[0]=digit;
02352          bc->info_dad[1]=0;
02353          
02354          {
02355             int l = sizeof(bc->dad);
02356             strncat(bc->dad, bc->info_dad, l - strlen(bc->dad) - 1);
02357          }
02358          {
02359             int l = sizeof(p->ast->exten);
02360             strncpy(p->ast->exten, bc->dad, l);
02361             p->ast->exten[l-1] = 0;
02362          }
02363          
02364          misdn_lib_send_event( bc, EVENT_INFORMATION);
02365       }
02366       break;
02367    default: 
02368          if ( bc->send_dtmf ) 
02369             send_digit_to_chan(p,digit);
02370       break;
02371    }
02372 
02373    return 0;
02374 }
02375 
02376 
02377 static int misdn_fixup(struct ast_channel *oldast, struct ast_channel *ast)
02378 {
02379    struct chan_list *p;
02380 
02381    if (!ast || ! (p=MISDN_ASTERISK_TECH_PVT(ast) )) return -1;
02382 
02383    chan_misdn_log(1, p->bc ? p->bc->port : 0, "* IND: Got Fixup State:%s L3id:%x\n", misdn_get_ch_state(p), p->l3id);
02384 
02385    p->ast = ast;
02386 
02387    return 0;
02388 }
02389 
02390 
02391 
02392 static int misdn_indication(struct ast_channel *ast, int cond, const void *data, size_t datalen)
02393 {
02394    struct chan_list *p;
02395 
02396    if (!ast || ! (p=MISDN_ASTERISK_TECH_PVT(ast))) {
02397       ast_log(LOG_WARNING, "Returned -1 in misdn_indication\n");
02398       return -1;
02399    }
02400    
02401    if (!p->bc) {
02402       if (p->hold.state == MISDN_HOLD_IDLE) {
02403          chan_misdn_log(1, 0, "* IND : Indication [%d] ignored on %s\n", cond,
02404             ast->name);
02405          ast_log(LOG_WARNING, "Private Pointer but no bc ?\n");
02406       } else {
02407          chan_misdn_log(1, 0, "* IND : Indication [%d] ignored on hold %s\n",
02408             cond, ast->name);
02409       }
02410       return -1;
02411    }
02412    
02413    chan_misdn_log(5, p->bc->port, "* IND : Indication [%d] on %s\n\n", cond, ast->name);
02414    
02415    switch (cond) {
02416    case AST_CONTROL_BUSY:
02417       chan_misdn_log(1, p->bc->port, "* IND :\tbusy pid:%d\n", p->bc ? p->bc->pid : -1);
02418       ast_setstate(ast, AST_STATE_BUSY);
02419 
02420       p->bc->out_cause = AST_CAUSE_USER_BUSY;
02421       if (p->state != MISDN_CONNECTED) {
02422          start_bc_tones(p);
02423          misdn_lib_send_event( p->bc, EVENT_DISCONNECT);
02424       }
02425       return -1;
02426    case AST_CONTROL_RING:
02427       chan_misdn_log(1, p->bc->port, "* IND :\tring pid:%d\n", p->bc ? p->bc->pid : -1);
02428       return -1;
02429    case AST_CONTROL_RINGING:
02430       chan_misdn_log(1, p->bc->port, "* IND :\tringing pid:%d\n", p->bc ? p->bc->pid : -1);
02431       switch (p->state) {
02432       case MISDN_ALERTING:
02433          chan_misdn_log(2, p->bc->port, " --> * IND :\tringing pid:%d but I was Ringing before, so ignoring it\n", p->bc ? p->bc->pid : -1);
02434          break;
02435       case MISDN_CONNECTED:
02436          chan_misdn_log(2, p->bc->port, " --> * IND :\tringing pid:%d but Connected, so just send TONE_ALERTING without state changes \n", p->bc ? p->bc->pid : -1);
02437          return -1;
02438       default:
02439          p->state = MISDN_ALERTING;
02440          chan_misdn_log(2, p->bc->port, " --> * IND :\tringing pid:%d\n", p->bc ? p->bc->pid : -1);
02441          misdn_lib_send_event( p->bc, EVENT_ALERTING);
02442 
02443          if (p->other_ch && p->other_ch->bc) {
02444             if (misdn_inband_avail(p->other_ch->bc)) {
02445                chan_misdn_log(2, p->bc->port, " --> other End is mISDN and has inband info available\n");
02446                break;
02447             }
02448 
02449             if (!p->other_ch->bc->nt) {
02450                chan_misdn_log(2, p->bc->port, " --> other End is mISDN TE so it has inband info for sure (?)\n");
02451                break;
02452             }
02453          }
02454 
02455          chan_misdn_log(3, p->bc->port, " --> * SEND: State Ring pid:%d\n", p->bc ? p->bc->pid : -1);
02456          ast_setstate(ast, AST_STATE_RING);
02457 
02458          if (!p->bc->nt && (p->originator == ORG_MISDN) && !p->incoming_early_audio)
02459             chan_misdn_log(2, p->bc->port, " --> incoming_early_audio off\n");
02460          else 
02461             return -1;
02462       }
02463       break;
02464    case AST_CONTROL_ANSWER:
02465       chan_misdn_log(1, p->bc->port, " --> * IND :\tanswer pid:%d\n", p->bc ? p->bc->pid : -1);
02466       start_bc_tones(p);
02467       break;
02468    case AST_CONTROL_TAKEOFFHOOK:
02469       chan_misdn_log(1, p->bc->port, " --> *\ttakeoffhook pid:%d\n", p->bc ? p->bc->pid : -1);
02470       return -1;
02471    case AST_CONTROL_OFFHOOK:
02472       chan_misdn_log(1, p->bc->port, " --> *\toffhook pid:%d\n", p->bc ? p->bc->pid : -1);
02473       return -1;
02474    case AST_CONTROL_FLASH:
02475       chan_misdn_log(1, p->bc->port, " --> *\tflash pid:%d\n", p->bc ? p->bc->pid : -1);
02476       break;
02477    case AST_CONTROL_PROGRESS:
02478       chan_misdn_log(1, p->bc->port, " --> * IND :\tprogress pid:%d\n", p->bc ? p->bc->pid : -1);
02479       misdn_lib_send_event( p->bc, EVENT_PROGRESS);
02480       break;
02481    case AST_CONTROL_PROCEEDING:
02482       chan_misdn_log(1, p->bc->port, " --> * IND :\tproceeding pid:%d\n", p->bc ? p->bc->pid : -1);
02483       misdn_lib_send_event( p->bc, EVENT_PROCEEDING);
02484       break;
02485    case AST_CONTROL_CONGESTION:
02486       chan_misdn_log(1, p->bc->port, " --> * IND :\tcongestion pid:%d\n", p->bc ? p->bc->pid : -1);
02487 
02488       p->bc->out_cause = AST_CAUSE_SWITCH_CONGESTION;
02489       start_bc_tones(p);
02490       misdn_lib_send_event( p->bc, EVENT_DISCONNECT);
02491 
02492       if (p->bc->nt) {
02493          hanguptone_indicate(p);
02494       }
02495       break;
02496    case -1 :
02497       chan_misdn_log(1, p->bc->port, " --> * IND :\t-1! (stop indication) pid:%d\n", p->bc ? p->bc->pid : -1);
02498 
02499       stop_indicate(p);
02500 
02501       if (p->state == MISDN_CONNECTED) 
02502          start_bc_tones(p);
02503       break;
02504    case AST_CONTROL_HOLD:
02505       ast_moh_start(ast, data, p->mohinterpret); 
02506       chan_misdn_log(1, p->bc->port, " --> *\tHOLD pid:%d\n", p->bc ? p->bc->pid : -1);
02507       break;
02508    case AST_CONTROL_UNHOLD:
02509       ast_moh_stop(ast);
02510       chan_misdn_log(1, p->bc->port, " --> *\tUNHOLD pid:%d\n", p->bc ? p->bc->pid : -1);
02511       break;
02512    default:
02513       chan_misdn_log(1, p->bc->port, " --> * Unknown Indication:%d pid:%d\n", cond, p->bc ? p->bc->pid : -1);
02514       return -1;
02515    }
02516   
02517    return 0;
02518 }
02519 
02520 static int misdn_hangup(struct ast_channel *ast)
02521 {
02522    struct chan_list *p;
02523    struct misdn_bchannel *bc;
02524    const char *var;
02525 
02526    if (!ast || !(p = MISDN_ASTERISK_TECH_PVT(ast))) {
02527       return -1;
02528    }
02529    MISDN_ASTERISK_TECH_PVT(ast) = NULL;
02530 
02531    ast_log(LOG_DEBUG, "misdn_hangup(%s)\n", ast->name);
02532 
02533    if (p->hold.state == MISDN_HOLD_IDLE) {
02534       bc = p->bc;
02535    } else {
02536       p->hold.state = MISDN_HOLD_DISCONNECT;
02537       bc = misdn_lib_find_held_bc(p->hold.port, p->l3id);
02538       if (!bc) {
02539          chan_misdn_log(4, p->hold.port,
02540             "misdn_hangup: Could not find held bc for (%s)\n", ast->name);
02541          release_chan_early(p);
02542          return 0;
02543       }
02544    }
02545 
02546    if (ast->_state == AST_STATE_RESERVED || p->state == MISDN_NOTHING) {
02547       /* between request and call */
02548       ast_log(LOG_DEBUG, "State Reserved (or nothing) => chanIsAvail\n");
02549       release_chan_early(p);
02550       if (bc) {
02551          misdn_lib_release(bc);
02552       }
02553       return 0;
02554    }
02555    if (!bc) {
02556       ast_log(LOG_WARNING, "Hangup with private but no bc ? state:%s l3id:%x\n",
02557          misdn_get_ch_state(p), p->l3id);
02558       release_chan_early(p);
02559       return 0;
02560    }
02561 
02562    p->ast = NULL;
02563    p->need_hangup = 0;
02564    p->need_queue_hangup = 0;
02565    p->need_busy = 0;
02566 
02567    if (!bc->nt) {
02568       stop_bc_tones(p);
02569    }
02570 
02571    bc->out_cause = ast->hangupcause ? ast->hangupcause : AST_CAUSE_NORMAL_CLEARING;
02572 
02573    var = pbx_builtin_getvar_helper(ast, "HANGUPCAUSE");
02574    if (!var) {
02575       var = pbx_builtin_getvar_helper(ast, "PRI_CAUSE");
02576    }
02577    if (var) {
02578       int tmpcause;
02579 
02580       tmpcause = atoi(var);
02581       bc->out_cause = tmpcause ? tmpcause : AST_CAUSE_NORMAL_CLEARING;
02582    }
02583 
02584    var = pbx_builtin_getvar_helper(ast, "MISDN_USERUSER");
02585    if (var) {
02586       ast_log(LOG_NOTICE, "MISDN_USERUSER: %s\n", var);
02587       ast_copy_string(bc->uu, var, sizeof(bc->uu));
02588       bc->uulen = strlen(bc->uu);
02589    }
02590 
02591    chan_misdn_log(1, bc->port,
02592       "* IND : HANGUP\tpid:%d ctx:%s dad:%s oad:%s State:%s\n",
02593       bc->pid,
02594       ast->context,
02595       ast->exten,
02596       ast->cid.cid_num,
02597       misdn_get_ch_state(p));
02598    chan_misdn_log(3, bc->port, " --> l3id:%x\n", p->l3id);
02599    chan_misdn_log(3, bc->port, " --> cause:%d\n", bc->cause);
02600    chan_misdn_log(2, bc->port, " --> out_cause:%d\n", bc->out_cause);
02601 
02602    switch (p->state) {
02603    case MISDN_INCOMING_SETUP:
02604       /*
02605        * This is the only place in misdn_hangup, where we
02606        * can call release_chan, else it might create a lot of trouble.
02607        */
02608       ast_log(LOG_NOTICE, "release channel, in INCOMING_SETUP state.. no other events happened\n");
02609       release_chan(p, bc);
02610 
02611       if (bc->need_release_complete) {
02612          misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE);
02613       }
02614       return 0;
02615    case MISDN_DIALING:
02616       if (p->hold.state == MISDN_HOLD_IDLE) {
02617          start_bc_tones(p);
02618          hanguptone_indicate(p);
02619       }
02620 
02621       if (bc->need_disconnect) {
02622          misdn_lib_send_event(bc, EVENT_DISCONNECT);
02623       }
02624       break;
02625    case MISDN_CALLING_ACKNOWLEDGE:
02626       if (p->hold.state == MISDN_HOLD_IDLE) {
02627          start_bc_tones(p);
02628          hanguptone_indicate(p);
02629       }
02630 
02631       if (bc->need_disconnect) {
02632          misdn_lib_send_event(bc, EVENT_DISCONNECT);
02633       }
02634       break;
02635 
02636    case MISDN_CALLING:
02637    case MISDN_ALERTING:
02638    case MISDN_PROGRESS:
02639    case MISDN_PROCEEDING:
02640       if (p->originator != ORG_AST && p->hold.state == MISDN_HOLD_IDLE) {
02641          hanguptone_indicate(p);
02642       }
02643 
02644       if (bc->need_disconnect) {
02645          misdn_lib_send_event(bc, EVENT_DISCONNECT);
02646       }
02647       break;
02648    case MISDN_CONNECTED:
02649       /*  Alerting or Disconnect */
02650       if (bc->nt && p->hold.state == MISDN_HOLD_IDLE) {
02651          start_bc_tones(p);
02652          hanguptone_indicate(p);
02653          bc->progress_indicator = INFO_PI_INBAND_AVAILABLE;
02654       }
02655       if (bc->need_disconnect) {
02656          misdn_lib_send_event(bc, EVENT_DISCONNECT);
02657       }
02658       break;
02659    case MISDN_DISCONNECTED:
02660       if (bc->need_release) {
02661          misdn_lib_send_event(bc, EVENT_RELEASE);
02662       }
02663       break;
02664 
02665    case MISDN_CLEANING:
02666       return 0;
02667 
02668    case MISDN_BUSY:
02669       break;
02670    default:
02671       if (bc->nt) {
02672          bc->out_cause = -1;
02673          if (bc->need_release) {
02674             misdn_lib_send_event(bc, EVENT_RELEASE);
02675          }
02676       } else {
02677          if (bc->need_disconnect) {
02678             misdn_lib_send_event(bc, EVENT_DISCONNECT);
02679          }
02680       }
02681       break;
02682    }
02683 
02684    p->state = MISDN_CLEANING;
02685    chan_misdn_log(3, bc->port, " --> Channel: %s hungup new state:%s\n", ast->name,
02686       misdn_get_ch_state(p));
02687 
02688    return 0;
02689 }
02690 
02691 
02692 static struct ast_frame *process_ast_dsp(struct chan_list *tmp, struct ast_frame *frame)
02693 {
02694    struct ast_frame *f;
02695  
02696    if (tmp->dsp) {
02697       f = ast_dsp_process(tmp->ast, tmp->dsp, frame);
02698    } else {
02699       chan_misdn_log(0, tmp->bc->port, "No DSP-Path found\n");
02700       return NULL;
02701    }
02702 
02703    if (!f || (f->frametype != AST_FRAME_DTMF)) {
02704       return f;
02705    }
02706  
02707    ast_log(LOG_DEBUG, "Detected inband DTMF digit: %c\n", f->subclass);
02708  
02709    if (tmp->faxdetect && (f->subclass == 'f')) {
02710       /* Fax tone -- Handle and return NULL */
02711       if (!tmp->faxhandled) {
02712          struct ast_channel *ast = tmp->ast;
02713          tmp->faxhandled++;
02714          chan_misdn_log(0, tmp->bc->port, "Fax detected, preparing %s for fax transfer.\n", ast->name);
02715          tmp->bc->rxgain = 0;
02716          isdn_lib_update_rxgain(tmp->bc);
02717          tmp->bc->txgain = 0;
02718          isdn_lib_update_txgain(tmp->bc);
02719 #ifdef MISDN_1_2
02720          *tmp->bc->pipeline = 0;
02721 #else
02722          tmp->bc->ec_enable = 0;
02723 #endif
02724          isdn_lib_update_ec(tmp->bc);
02725          isdn_lib_stop_dtmf(tmp->bc);
02726          switch (tmp->faxdetect) {
02727          case 1:
02728             if (strcmp(ast->exten, "fax")) {
02729                char *context;
02730                char context_tmp[BUFFERSIZE];
02731                misdn_cfg_get(tmp->bc->port, MISDN_CFG_FAXDETECT_CONTEXT, &context_tmp, sizeof(context_tmp));
02732                context = ast_strlen_zero(context_tmp) ? (ast_strlen_zero(ast->macrocontext) ? ast->context : ast->macrocontext) : context_tmp;
02733                if (ast_exists_extension(ast, context, "fax", 1, ast->cid.cid_num)) {
02734                   if (option_verbose > 2)
02735                      ast_verbose(VERBOSE_PREFIX_3 "Redirecting %s to fax extension (context:%s)\n", ast->name, context);
02736                   /* Save the DID/DNIS when we transfer the fax call to a "fax" extension */
02737                   pbx_builtin_setvar_helper(ast,"FAXEXTEN",ast->exten);
02738                   if (ast_async_goto(ast, context, "fax", 1))
02739                      ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast->name, context);
02740                } else
02741                   ast_log(LOG_NOTICE, "Fax detected, but no fax extension ctx:%s exten:%s\n", context, ast->exten);
02742             } else {
02743                ast_log(LOG_DEBUG, "Already in a fax extension, not redirecting\n");
02744             }
02745             break;
02746          case 2:
02747             ast_verbose(VERBOSE_PREFIX_3 "Not redirecting %s to fax extension, nojump is set.\n", ast->name);
02748             break;
02749          }
02750       } else {
02751          ast_log(LOG_DEBUG, "Fax already handled\n");
02752       }
02753    }
02754    
02755    if (tmp->ast_dsp && (f->subclass != 'f')) {
02756       chan_misdn_log(2, tmp->bc->port, " --> * SEND: DTMF (AST_DSP) :%c\n", f->subclass);
02757    }
02758 
02759    return f;
02760 }
02761 
02762 
02763 static struct ast_frame *misdn_read(struct ast_channel *ast)
02764 {
02765    struct chan_list *tmp;
02766    int len, t;
02767    struct pollfd pfd = { .fd = -1, .events = POLLIN };
02768 
02769    if (!ast) {
02770       chan_misdn_log(1, 0, "misdn_read called without ast\n");
02771       return NULL;
02772    }
02773    if (!(tmp = MISDN_ASTERISK_TECH_PVT(ast))) {
02774       chan_misdn_log(1, 0, "misdn_read called without ast->pvt\n");
02775       return NULL;
02776    }
02777 
02778    if (!tmp->bc && tmp->hold.state == MISDN_HOLD_IDLE) {
02779       chan_misdn_log(1, 0, "misdn_read called without bc\n");
02780       return NULL;
02781    }
02782 
02783    pfd.fd = tmp->pipe[0];
02784    t = ast_poll(&pfd, 1, 20);
02785 
02786    if (t < 0) {
02787       chan_misdn_log(-1, tmp->bc->port, "poll() error (err=%s)\n", strerror(errno));
02788       return NULL;
02789    }
02790 
02791    if (!t) {
02792       chan_misdn_log(3, tmp->bc->port, "poll() timed out\n");
02793       len = 160;
02794    } else if (pfd.revents & POLLIN) {
02795       len = read(tmp->pipe[0], tmp->ast_rd_buf, sizeof(tmp->ast_rd_buf));
02796 
02797       if (len <= 0) {
02798          /* we hangup here, since our pipe is closed */
02799          chan_misdn_log(2, tmp->bc->port, "misdn_read: Pipe closed, hanging up\n");
02800          return NULL;
02801       }
02802 
02803    } else {
02804       return NULL;
02805    }
02806 
02807    tmp->frame.frametype = AST_FRAME_VOICE;
02808    tmp->frame.subclass = AST_FORMAT_ALAW;
02809    tmp->frame.datalen = len;
02810    tmp->frame.samples = len;
02811    tmp->frame.mallocd = 0;
02812    tmp->frame.offset = 0;
02813    tmp->frame.delivery = ast_tv(0,0);
02814    tmp->frame.src = NULL;
02815    tmp->frame.data = tmp->ast_rd_buf;
02816 
02817    if (tmp->faxdetect && !tmp->faxhandled) {
02818       if (tmp->faxdetect_timeout) {
02819          if (ast_tvzero(tmp->faxdetect_tv)) {
02820             tmp->faxdetect_tv = ast_tvnow();
02821             chan_misdn_log(2, tmp->bc->port, "faxdetect: starting detection with timeout: %ds ...\n", tmp->faxdetect_timeout);
02822             return process_ast_dsp(tmp, &tmp->frame);
02823          } else {
02824             struct timeval tv_now = ast_tvnow();
02825             int diff = ast_tvdiff_ms(tv_now, tmp->faxdetect_tv);
02826             if (diff <= (tmp->faxdetect_timeout * 1000)) {
02827                chan_misdn_log(5, tmp->bc->port, "faxdetect: detecting ...\n");
02828                return process_ast_dsp(tmp, &tmp->frame);
02829             } else {
02830                chan_misdn_log(2, tmp->bc->port, "faxdetect: stopping detection (time ran out) ...\n");
02831                tmp->faxdetect = 0;
02832                return &tmp->frame;
02833             }
02834          }
02835       } else {
02836          chan_misdn_log(5, tmp->bc->port, "faxdetect: detecting ... (no timeout)\n");
02837          return process_ast_dsp(tmp, &tmp->frame);
02838       }
02839    } else {
02840       if (tmp->ast_dsp)
02841          return process_ast_dsp(tmp, &tmp->frame);
02842       else
02843          return &tmp->frame;
02844    }
02845 }
02846 
02847 
02848 static int misdn_write(struct ast_channel *ast, struct ast_frame *frame)
02849 {
02850    struct chan_list *ch;
02851    int i  = 0;
02852    
02853    if (!ast || ! (ch = MISDN_ASTERISK_TECH_PVT(ast)) ) return -1;
02854 
02855    if (ch->hold.state != MISDN_HOLD_IDLE) {
02856       chan_misdn_log(7, 0, "misdn_write: Returning because hold active\n");
02857       return 0;
02858    }
02859    
02860    if (!ch->bc ) {
02861       ast_log(LOG_WARNING, "private but no bc\n");
02862       return -1;
02863    }
02864    
02865    if (ch->notxtone) {
02866       chan_misdn_log(7, ch->bc->port, "misdn_write: Returning because notxtone\n");
02867       return 0;
02868    }
02869 
02870 
02871    if (!frame->subclass) {
02872       chan_misdn_log(4, ch->bc->port, "misdn_write: * prods us\n");
02873       return 0;
02874    }
02875    
02876    if (!(frame->subclass & prefformat)) {
02877       
02878       chan_misdn_log(-1, ch->bc->port, "Got Unsupported Frame with Format:%d\n", frame->subclass);
02879       return 0;
02880    }
02881    
02882 
02883    if (!frame->samples ) {
02884       chan_misdn_log(4, ch->bc->port, "misdn_write: zero write\n");
02885       
02886       if (!strcmp(frame->src,"ast_prod")) {
02887          chan_misdn_log(1, ch->bc->port, "misdn_write: state (%s) prodded.\n", misdn_get_ch_state(ch));
02888 
02889          if (ch->ts) {
02890             chan_misdn_log(4, ch->bc->port, "Starting Playtones\n");
02891             misdn_lib_tone_generator_start(ch->bc);
02892          }
02893          return 0;
02894       }
02895 
02896       return -1;
02897    }
02898 
02899    if ( ! ch->bc->addr ) {
02900       chan_misdn_log(8, ch->bc->port, "misdn_write: no addr for bc dropping:%d\n", frame->samples);
02901       return 0;
02902    }
02903    
02904 #ifdef MISDN_DEBUG
02905    {
02906       int i, max = 5 > frame->samples ? frame->samples : 5;
02907 
02908       printf("write2mISDN %p %d bytes: ", p, frame->samples);
02909 
02910       for (i = 0; i < max; i++)
02911          printf("%2.2x ", ((char*) frame->data)[i]);
02912       printf ("\n");
02913    }
02914 #endif
02915 
02916    switch (ch->bc->bc_state) {
02917    case BCHAN_ACTIVATED:
02918    case BCHAN_BRIDGED:
02919       break;
02920    default:
02921       if (!ch->dropped_frame_cnt)
02922          chan_misdn_log(5, ch->bc->port, "BC not active (nor bridged) dropping: %d frames addr:%x exten:%s cid:%s ch->state:%s bc_state:%d l3id:%x\n", frame->samples, ch->bc->addr, ast->exten, ast->cid.cid_num, misdn_get_ch_state( ch), ch->bc->bc_state, ch->bc->l3_id);
02923       
02924       ch->dropped_frame_cnt++;
02925       if (ch->dropped_frame_cnt > 100) {
02926          ch->dropped_frame_cnt = 0;
02927          chan_misdn_log(5, ch->bc->port, "BC not active (nor bridged) dropping: %d frames addr:%x  dropped > 100 frames!\n", frame->samples, ch->bc->addr);
02928       }
02929 
02930       return 0;
02931    }
02932 
02933    chan_misdn_log(9, ch->bc->port, "Sending :%d bytes to MISDN\n", frame->samples);
02934    if ( !ch->bc->nojitter && misdn_cap_is_speech(ch->bc->capability) ) {
02935       /* Buffered Transmit (triggered by read from isdn side)*/
02936       if (misdn_jb_fill(ch->jb, frame->data, frame->samples) < 0) {
02937          if (ch->bc->active)
02938             cb_log(0, ch->bc->port, "Misdn Jitterbuffer Overflow.\n");
02939       }
02940       
02941    } else {
02942       /*transmit without jitterbuffer*/
02943       i = misdn_lib_tx2misdn_frm(ch->bc, frame->data, frame->samples);
02944    }
02945 
02946    return 0;
02947 }
02948 
02949 
02950 
02951 
02952 static enum ast_bridge_result  misdn_bridge (struct ast_channel *c0,
02953                   struct ast_channel *c1, int flags,
02954                   struct ast_frame **fo,
02955                   struct ast_channel **rc,
02956                   int timeoutms)
02957 
02958 {
02959    struct chan_list *ch1, *ch2;
02960    struct ast_channel *carr[2], *who;
02961    int to = -1;
02962    struct ast_frame *f;
02963    int p1_b, p2_b;
02964    int bridging;
02965   
02966    ch1 = get_chan_by_ast(c0);
02967    ch2 = get_chan_by_ast(c1);
02968 
02969    carr[0] = c0;
02970    carr[1] = c1;
02971   
02972    if (!(ch1 && ch2))
02973       return -1;
02974 
02975    misdn_cfg_get(ch1->bc->port, MISDN_CFG_BRIDGING, &p1_b, sizeof(int));
02976    misdn_cfg_get(ch2->bc->port, MISDN_CFG_BRIDGING, &p2_b, sizeof(int));
02977 
02978    if (! p1_b || ! p2_b) {
02979       ast_log(LOG_NOTICE, "Falling back to Asterisk bridging\n");
02980       return AST_BRIDGE_FAILED;
02981    }
02982 
02983    misdn_cfg_get(0, MISDN_GEN_BRIDGING, &bridging, sizeof(int));
02984    if (bridging) {
02985       /* trying to make a mISDN_dsp conference */
02986       chan_misdn_log(1, ch1->bc->port, "I SEND: Making conference with Number:%d\n", ch1->bc->pid + 1);
02987       misdn_lib_bridge(ch1->bc, ch2->bc);
02988    }
02989 
02990    if (option_verbose > 2) 
02991       ast_verbose(VERBOSE_PREFIX_3 "Native bridging %s and %s\n", c0->name, c1->name);
02992 
02993    chan_misdn_log(1, ch1->bc->port, "* Making Native Bridge between %s and %s\n", ch1->bc->oad, ch2->bc->oad);
02994  
02995    if (! (flags & AST_BRIDGE_DTMF_CHANNEL_0) )
02996       ch1->ignore_dtmf = 1;
02997 
02998    if (! (flags & AST_BRIDGE_DTMF_CHANNEL_1) )
02999       ch2->ignore_dtmf = 1;
03000 
03001    for (;/*ever*/;) {
03002       to = -1;
03003       who = ast_waitfor_n(carr, 2, &to);
03004 
03005       if (!who) {
03006          ast_log(LOG_NOTICE, "misdn_bridge: empty read, breaking out\n");
03007          break;
03008       }
03009       f = ast_read(who);
03010 
03011       if (!f || f->frametype == AST_FRAME_CONTROL) {
03012          /* got hangup .. */
03013 
03014          if (!f) 
03015             chan_misdn_log(4, ch1->bc->port, "Read Null Frame\n");
03016          else
03017             chan_misdn_log(4, ch1->bc->port, "Read Frame Control class:%d\n", f->subclass);
03018 
03019          *fo = f;
03020          *rc = who;
03021          break;
03022       }
03023       
03024       if ( f->frametype == AST_FRAME_DTMF ) {
03025          chan_misdn_log(1, 0, "Read DTMF %d from %s\n", f->subclass, who->exten);
03026 
03027          *fo = f;
03028          *rc = who;
03029          break;
03030       }
03031    
03032 #if 0
03033       if (f->frametype == AST_FRAME_VOICE) {
03034          chan_misdn_log(1, ch1->bc->port, "I SEND: Splitting conference with Number:%d\n", ch1->bc->pid +1);
03035    
03036          continue;
03037       }
03038 #endif
03039 
03040       if (who == c0) {
03041          ast_write(c1, f);
03042       }
03043       else {
03044          ast_write(c0, f);
03045       }
03046    }
03047 
03048    chan_misdn_log(1, ch1->bc->port, "I SEND: Splitting conference with Number:%d\n", ch1->bc->pid + 1);
03049 
03050    misdn_lib_split_bridge(ch1->bc, ch2->bc);
03051 
03052    return AST_BRIDGE_COMPLETE;
03053 }
03054 
03055 /** AST INDICATIONS END **/
03056 
03057 static int dialtone_indicate(struct chan_list *cl)
03058 {
03059    const struct tone_zone_sound *ts = NULL;
03060    struct ast_channel *ast = cl->ast;
03061    int nd = 0;
03062 
03063    if (!ast) {
03064       chan_misdn_log(0, cl->bc->port, "No Ast in dialtone_indicate\n");
03065       return -1;
03066    }
03067 
03068    misdn_cfg_get(cl->bc->port, MISDN_CFG_NODIALTONE, &nd, sizeof(nd));
03069 
03070    if (nd) {
03071       chan_misdn_log(1, cl->bc->port, "Not sending Dialtone, because config wants it\n");
03072       return 0;
03073    }
03074    
03075    chan_misdn_log(3, cl->bc->port, " --> Dial\n");
03076    ts = ast_get_indication_tone(ast->zone, "dial");
03077    cl->ts = ts;   
03078    
03079    if (ts) {
03080       cl->notxtone = 0;
03081       cl->norxtone = 0;
03082       /* This prods us in misdn_write */
03083       ast_playtones_start(ast, 0, ts->data, 0);
03084    }
03085 
03086    return 0;
03087 }
03088 
03089 static void hanguptone_indicate(struct chan_list *cl)
03090 {
03091    misdn_lib_send_tone(cl->bc, TONE_HANGUP);
03092 }
03093 
03094 static int stop_indicate(struct chan_list *cl)
03095 {
03096    struct ast_channel *ast = cl->ast;
03097 
03098    if (!ast) {
03099       chan_misdn_log(0, cl->bc->port, "No Ast in stop_indicate\n");
03100       return -1;
03101    }
03102 
03103    chan_misdn_log(3, cl->bc->port, " --> None\n");
03104    misdn_lib_tone_generator_stop(cl->bc);
03105    ast_playtones_stop(ast);
03106 
03107    cl->ts = NULL;
03108    /*ast_deactivate_generator(ast);*/
03109 
03110    return 0;
03111 }
03112 
03113 
03114 static int start_bc_tones(struct chan_list* cl)
03115 {
03116    misdn_lib_tone_generator_stop(cl->bc);
03117    cl->notxtone = 0;
03118    cl->norxtone = 0;
03119    return 0;
03120 }
03121 
03122 static int stop_bc_tones(struct chan_list *cl)
03123 {
03124    if (!cl) return -1;
03125 
03126    cl->notxtone = 1;
03127    cl->norxtone = 1;
03128    
03129    return 0;
03130 }
03131 
03132 
03133 static struct chan_list *init_chan_list(int orig)
03134 {
03135    struct chan_list *cl;
03136 
03137    cl = calloc(1, sizeof(struct chan_list));
03138    if (!cl) {
03139       chan_misdn_log(-1, 0, "misdn_request: malloc failed!");
03140       return NULL;
03141    }
03142    
03143    cl->originator = orig;
03144    cl->need_queue_hangup = 1;
03145    cl->need_hangup = 1;
03146    cl->need_busy = 1;
03147    cl->overlap_dial_task = -1;
03148 
03149    return cl;
03150 }
03151 
03152 static struct ast_channel *misdn_request(const char *type, int format, void *data, int *cause)
03153 {
03154    struct ast_channel *tmp = NULL;
03155    char group[BUFFERSIZE + 1] = "";
03156    char dial_str[128];
03157    char *buf2 = ast_strdupa(data);
03158    char *ext;
03159    char *port_str;
03160    char *p = NULL;
03161    int channel = 0;
03162    int port = 0;
03163    struct misdn_bchannel *newbc = NULL;
03164    int dec = 0;
03165    struct chan_list *cl;
03166 
03167    snprintf(dial_str, sizeof(dial_str), "%s/%s", misdn_type, (char *) data);
03168 
03169    /*
03170     * data is ---v
03171     * Dial(mISDN/g:group_name[/extension[/options]])
03172     * Dial(mISDN/port[:preselected_channel][/extension[/options]])
03173     *
03174     * The dial extension could be empty if you are using MISDN_KEYPAD
03175     * to control ISDN provider features.
03176     */
03177    port_str = strsep(&buf2, "/");
03178    if (!ast_strlen_zero(port_str)) {
03179       if (port_str[0] == 'g' && port_str[1] == ':' ) {
03180          /* We make a group call lets checkout which ports are in my group */
03181          port_str += 2;
03182          ast_copy_string(group, port_str, sizeof(group));
03183          chan_misdn_log(2, 0, " --> Group Call group: %s\n", group);
03184       } else if ((p = strchr(port_str, ':'))) {
03185          /* we have a preselected channel */
03186          *p = 0;
03187          channel = atoi(++p);
03188          port = atoi(port_str);
03189          chan_misdn_log(2, port, " --> Call on preselected Channel (%d).\n", channel);
03190       } else {
03191          port = atoi(port_str);
03192       }
03193    } else {
03194       ast_log(LOG_WARNING, " --> ! IND : Dial(%s) WITHOUT Port or Group, check extensions.conf\n", dial_str);
03195       return NULL;
03196    }
03197 
03198    ext = strsep(&buf2, "/");
03199    if (!ext) {
03200       ext = "";
03201    }
03202 
03203    if (misdn_cfg_is_group_method(group, METHOD_STANDARD_DEC)) {
03204       chan_misdn_log(4, port, " --> STARTING STANDARD DEC...\n");
03205       dec = 1;
03206    }
03207 
03208    if (!ast_strlen_zero(group)) {
03209       char cfg_group[BUFFERSIZE + 1];
03210       struct robin_list *rr = NULL;
03211 
03212       /* Group dial */
03213 
03214       if (misdn_cfg_is_group_method(group, METHOD_ROUND_ROBIN)) {
03215          chan_misdn_log(4, port, " --> STARTING ROUND ROBIN...\n");
03216          rr = get_robin_position(group);
03217       }
03218 
03219       if (rr) {
03220          int port_start = 0;
03221          int port_bak = rr->port;
03222          int chan_bak = rr->channel;
03223 
03224          if (!rr->port)
03225             rr->port = misdn_cfg_get_next_port_spin(rr->port);
03226          
03227          for (; rr->port > 0; rr->port = misdn_cfg_get_next_port_spin(rr->port)) {
03228             int port_up;
03229             int check;
03230             int max_chan;
03231             int last_chance = 0;
03232 
03233             misdn_cfg_get(rr->port, MISDN_CFG_GROUPNAME, cfg_group, BUFFERSIZE);
03234             if (strcasecmp(cfg_group, group))
03235                continue;
03236 
03237             misdn_cfg_get(rr->port, MISDN_CFG_PMP_L1_CHECK, &check, sizeof(int));
03238             port_up = misdn_lib_port_up(rr->port, check);
03239 
03240             if (check && !port_up) 
03241                chan_misdn_log(1, rr->port, "L1 is not Up on this Port\n");
03242 
03243             if (check && port_up < 0)
03244                ast_log(LOG_WARNING,"This port (%d) is blocked\n", rr->port);
03245 
03246             if ((port_start == rr->port) && (port_up <= 0))
03247                break;
03248 
03249             if (!port_start)
03250                port_start = rr->port;
03251 
03252             if (port_up <= 0)
03253                continue;
03254 
03255             max_chan = misdn_lib_get_maxchans(rr->port);
03256 
03257             for (++rr->channel; !last_chance && rr->channel <= max_chan; ++rr->channel) {
03258                if (rr->port == port_bak && rr->channel == chan_bak)
03259                   last_chance = 1;
03260 
03261                chan_misdn_log(1, 0, "trying port:%d channel:%d\n", rr->port, rr->channel);
03262                newbc = misdn_lib_get_free_bc(rr->port, rr->channel, 0, 0);
03263                if (newbc) {
03264                   chan_misdn_log(4, rr->port, " Success! Found port:%d channel:%d\n", newbc->port, newbc->channel);
03265                   if (port_up)
03266                      chan_misdn_log(4, rr->port, "portup:%d\n",  port_up);
03267                   port = rr->port;
03268                   break;
03269                }
03270             }
03271 
03272             if (newbc || last_chance)
03273                break;
03274 
03275             rr->channel = 0;
03276          }
03277          if (!newbc) {
03278             rr->port = port_bak;
03279             rr->channel = chan_bak;
03280          }
03281       } else {    
03282          for (port = misdn_cfg_get_next_port(0); port > 0;
03283              port = misdn_cfg_get_next_port(port)) {
03284 
03285             misdn_cfg_get(port, MISDN_CFG_GROUPNAME, cfg_group, BUFFERSIZE);
03286 
03287             chan_misdn_log(3, port, "Group [%s] Port [%d]\n", group, port);
03288             if (!strcasecmp(cfg_group, group)) {
03289                int port_up;
03290                int check;
03291                misdn_cfg_get(port, MISDN_CFG_PMP_L1_CHECK, &check, sizeof(int));
03292                port_up = misdn_lib_port_up(port, check);
03293 
03294                chan_misdn_log(4, port, "portup:%d\n", port_up);
03295 
03296                if (port_up > 0) {
03297                   newbc = misdn_lib_get_free_bc(port, 0, 0, dec);
03298                   if (newbc)
03299                      break;
03300                }
03301             }
03302          }
03303       }
03304       
03305       /* Group dial failed ?*/
03306       if (!newbc) {
03307          ast_log(LOG_WARNING, 
03308                "Could not Dial out on group '%s'.\n"
03309                "\tEither the L2 and L1 on all of these ports where DOWN (see 'show application misdn_check_l2l1')\n"
03310                "\tOr there was no free channel on none of the ports\n\n"
03311                , group);
03312          return NULL;
03313       }
03314    } else {
03315       /* 'Normal' Port dial * Port dial */
03316       if (channel)
03317          chan_misdn_log(1, port, " --> preselected_channel: %d\n", channel);
03318       newbc = misdn_lib_get_free_bc(port, channel, 0, dec);
03319 
03320       if (!newbc) {
03321          ast_log(LOG_WARNING, "Could not create channel on port:%d with extensions:%s\n", port, ext);
03322          return NULL;
03323       }
03324    }
03325    
03326 
03327    /* create ast_channel and link all the objects together */
03328    cl = init_chan_list(ORG_AST);
03329    if (!cl) {
03330       ast_log(LOG_ERROR, "Could not create call record for Dial(%s)\n", dial_str);
03331       return NULL;
03332    }
03333    cl->bc = newbc;
03334    
03335    tmp = misdn_new(cl, AST_STATE_RESERVED, ext, NULL, format, port, channel);
03336    if (!tmp) {
03337       free(cl);
03338       ast_log(LOG_ERROR,"Could not create Asterisk object\n");
03339       return NULL;
03340    }
03341 
03342    cl->ast=tmp;
03343    
03344    /* register chan in local list */
03345    cl_queue_chan(&cl_te, cl) ;
03346    
03347    /* fill in the config into the objects */
03348    read_config(cl, ORG_AST);
03349 
03350    /* important */
03351    cl->need_hangup = 0;
03352    
03353    return tmp;
03354 }
03355 
03356 
03357 static int misdn_send_text(struct ast_channel *chan, const char *text)
03358 {
03359    struct chan_list *tmp = chan->tech_pvt;
03360    
03361    if (tmp && tmp->bc) {
03362       ast_copy_string(tmp->bc->display, text, sizeof(tmp->bc->display));
03363       misdn_lib_send_event(tmp->bc, EVENT_INFORMATION);
03364    } else {
03365       ast_log(LOG_WARNING, "No chan_list but send_text request?\n");
03366       return -1;
03367    }
03368    
03369    return 0;
03370 }
03371 
03372 static struct ast_channel_tech misdn_tech = {
03373    .type = "mISDN",
03374    .description = "Channel driver for mISDN Support (Bri/Pri)",
03375    .capabilities = AST_FORMAT_ALAW ,
03376    .requester = misdn_request,
03377    .send_digit_begin = misdn_digit_begin,
03378    .send_digit_end = misdn_digit_end,
03379    .call = misdn_call,
03380    .bridge = misdn_bridge, 
03381    .hangup = misdn_hangup,
03382    .answer = misdn_answer,
03383    .read = misdn_read,
03384    .write = misdn_write,
03385    .indicate = misdn_indication,
03386    .fixup = misdn_fixup,
03387    .send_text = misdn_send_text,
03388    .properties = 0
03389 };
03390 
03391 static struct ast_channel_tech misdn_tech_wo_bridge = {
03392    .type = "mISDN",
03393    .description = "Channel driver for mISDN Support (Bri/Pri)",
03394    .capabilities = AST_FORMAT_ALAW ,
03395    .requester = misdn_request,
03396    .send_digit_begin = misdn_digit_begin,
03397    .send_digit_end = misdn_digit_end,
03398    .call = misdn_call,
03399    .hangup = misdn_hangup,
03400    .answer = misdn_answer,
03401    .read = misdn_read,
03402    .write = misdn_write,
03403    .indicate = misdn_indication,
03404    .fixup = misdn_fixup,
03405    .send_text = misdn_send_text,
03406    .properties = 0
03407 };
03408 
03409 
03410 static int glob_channel = 0;
03411 
03412 static void update_name(struct ast_channel *tmp, int port, int c) 
03413 {
03414    int chan_offset = 0;
03415    int tmp_port = misdn_cfg_get_next_port(0);
03416    for (; tmp_port > 0; tmp_port = misdn_cfg_get_next_port(tmp_port)) {
03417       if (tmp_port == port)
03418          break;
03419       chan_offset += misdn_lib_port_is_pri(tmp_port) ? 30 : 2; 
03420    }
03421    if (c < 0)
03422       c = 0;
03423 
03424    ast_string_field_build(tmp, name, "%s/%d-u%d",
03425       misdn_type, chan_offset + c, glob_channel++);
03426 
03427    chan_misdn_log(3, port, " --> updating channel name to [%s]\n", tmp->name);
03428 }
03429 
03430 static struct ast_channel *misdn_new(struct chan_list *chlist, int state,  char *exten, char *callerid, int format, int port, int c)
03431 {
03432    struct ast_channel *tmp;
03433    char *cid_name = 0, *cid_num = 0;
03434    int chan_offset = 0;
03435    int tmp_port = misdn_cfg_get_next_port(0);
03436    int bridging;
03437 
03438    for (; tmp_port > 0; tmp_port = misdn_cfg_get_next_port(tmp_port)) {
03439       if (tmp_port == port)
03440          break;
03441       chan_offset += misdn_lib_port_is_pri(tmp_port) ? 30 : 2;
03442    }
03443    if (c < 0)
03444       c = 0;
03445 
03446    if (callerid) {
03447       ast_callerid_parse(callerid, &cid_name, &cid_num);
03448    }
03449 
03450    tmp = ast_channel_alloc(1, state, cid_num, cid_name, "", exten, "", 0, "%s/%d-u%d", misdn_type, chan_offset + c, glob_channel++);
03451    if (tmp) {
03452       chan_misdn_log(2, 0, " --> * NEW CHANNEL dad:%s oad:%s\n", exten, callerid);
03453 
03454       tmp->nativeformats = prefformat;
03455 
03456       tmp->readformat = format;
03457       tmp->rawreadformat = format;
03458       tmp->writeformat = format;
03459       tmp->rawwriteformat = format;
03460     
03461       tmp->tech_pvt = chlist;
03462 
03463       misdn_cfg_get(0, MISDN_GEN_BRIDGING, &bridging, sizeof(int));
03464 
03465       if (bridging)
03466          tmp->tech = &misdn_tech;
03467       else
03468          tmp->tech = &misdn_tech_wo_bridge;
03469 
03470       tmp->writeformat = format;
03471       tmp->readformat = format;
03472       tmp->priority=1;
03473 
03474       if (exten) 
03475          ast_copy_string(tmp->exten, exten, sizeof(tmp->exten));
03476       else
03477          chan_misdn_log(1, 0, "misdn_new: no exten given.\n");
03478 
03479       if (callerid)
03480          /* Don't use ast_set_callerid() here because it will
03481           * generate a needless NewCallerID event */
03482          tmp->cid.cid_ani = ast_strdup(cid_num);
03483 
03484       if (pipe(chlist->pipe) < 0)
03485          perror("Pipe failed\n");
03486       tmp->fds[0] = chlist->pipe[0];
03487 
03488       if (state == AST_STATE_RING)
03489          tmp->rings = 1;
03490       else
03491          tmp->rings = 0;
03492       
03493    } else {
03494       chan_misdn_log(-1, 0, "Unable to allocate channel structure\n");
03495    }
03496    
03497    return tmp;
03498 }
03499 
03500 static struct chan_list *find_chan_by_bc(struct chan_list *list, struct misdn_bchannel *bc)
03501 {
03502    struct chan_list *help = list;
03503    for (; help; help = help->next) {
03504       if (help->bc == bc) return help;
03505    }
03506 
03507    chan_misdn_log(6, bc->port, "$$$ find_chan: No channel found for oad:%s dad:%s\n", bc->oad, bc->dad);
03508 
03509    return NULL;
03510 }
03511 
03512 static struct chan_list *find_chan_by_pid(struct chan_list *list, int pid)
03513 {
03514    struct chan_list *help = list;
03515    for (; help; help = help->next) {
03516       if ( help->bc && (help->bc->pid == pid) ) return help;
03517    }
03518 
03519    chan_misdn_log(6, 0, "$$$ find_chan: No channel found for pid:%d\n", pid);
03520 
03521    return NULL;
03522 }
03523 
03524 static struct chan_list *find_hold_call(struct chan_list *list, struct misdn_bchannel *bc)
03525 {
03526    struct chan_list *help = list;
03527 
03528    if (bc->pri) return NULL;
03529 
03530    chan_misdn_log(6, bc->port, "$$$ find_hold_call: channel:%d oad:%s dad:%s\n", bc->channel, bc->oad, bc->dad);
03531    for (;help; help = help->next) {
03532       chan_misdn_log(4, bc->port, "$$$ find_hold_call: --> hold:%d channel:%d\n", help->hold.state, help->hold.channel);
03533       if (help->hold.state == MISDN_HOLD_ACTIVE && help->hold.port == bc->port)
03534          return help;
03535    }
03536    chan_misdn_log(6, bc->port, "$$$ find_hold_call: No channel found for oad:%s dad:%s\n", bc->oad, bc->dad);
03537 
03538    return NULL;
03539 }
03540 
03541 
03542 static struct chan_list *find_hold_call_l3(struct chan_list *list, unsigned long l3_id)
03543 {
03544    struct chan_list *help = list;
03545 
03546    for (; help; help = help->next) {
03547       if (help->hold.state != MISDN_HOLD_IDLE && help->l3id == l3_id)
03548          return help;
03549    }
03550 
03551    return NULL;
03552 }
03553 
03554 #define TRANSFER_ON_HELD_CALL_HANGUP 1
03555 #if defined(TRANSFER_ON_HELD_CALL_HANGUP)
03556 /*!
03557  * \internal
03558  * \brief Find a suitable active call to go with a held call so we could try a transfer.
03559  *
03560  * \param list Channel list.
03561  * \param bc B channel record.
03562  *
03563  * \return Found call record or NULL.
03564  *
03565  * \note There could be a possibility where we find the wrong active call to transfer.
03566  * This concern is mitigated by the fact that there could be at most one other call
03567  * on a PTMP BRI link to another device.  Maybe the l3_id could help in locating an
03568  * active call on the same TEI?
03569  */
03570 static struct chan_list *find_hold_active_call(struct chan_list *list, struct misdn_bchannel *bc)
03571 {
03572    for (; list; list = list->next) {
03573       if (list->hold.state == MISDN_HOLD_IDLE && list->bc && list->bc->port == bc->port
03574          && list->ast) {
03575          switch (list->state) {
03576          case MISDN_PROCEEDING:
03577          case MISDN_PROGRESS:
03578          case MISDN_ALERTING:
03579          case MISDN_CONNECTED:
03580             return list;
03581          default:
03582             break;
03583          }
03584       }
03585    }
03586    return NULL;
03587 }
03588 #endif   /* defined(TRANSFER_ON_HELD_CALL_HANGUP) */
03589 
03590 static void cl_queue_chan(struct chan_list **list, struct chan_list *chan)
03591 {
03592    chan_misdn_log(4, chan->bc ? chan->bc->port : 0, "* Queuing chan %p\n", chan);
03593   
03594    ast_mutex_lock(&cl_te_lock);
03595    if (!*list) {
03596       *list = chan;
03597    } else {
03598       struct chan_list *help = *list;
03599       for (; help->next; help = help->next); 
03600       help->next = chan;
03601    }
03602    chan->next = NULL;
03603    ast_mutex_unlock(&cl_te_lock);
03604 }
03605 
03606 static void cl_dequeue_chan(struct chan_list **list, struct chan_list *chan) 
03607 {
03608    struct chan_list *help;
03609 
03610    if (chan->dsp) 
03611       ast_dsp_free(chan->dsp);
03612 
03613    ast_mutex_lock(&cl_te_lock);
03614    if (!*list) {
03615       ast_mutex_unlock(&cl_te_lock);
03616       return;
03617    }
03618   
03619    if (*list == chan) {
03620       *list = (*list)->next;
03621       ast_mutex_unlock(&cl_te_lock);
03622       return;
03623    }
03624   
03625    for (help = *list; help->next; help = help->next) {
03626       if (help->next == chan) {
03627          help->next = help->next->next;
03628          ast_mutex_unlock(&cl_te_lock);
03629          return;
03630       }
03631    }
03632    
03633    ast_mutex_unlock(&cl_te_lock);
03634 }
03635 
03636 /** Channel Queue End **/
03637 
03638 
03639 static int pbx_start_chan(struct chan_list *ch)
03640 {
03641    int ret = ast_pbx_start(ch->ast);   
03642 
03643    if (ret >= 0) 
03644       ch->need_hangup = 0;
03645    else
03646       ch->need_hangup = 1;
03647 
03648    return ret;
03649 }
03650 
03651 static void hangup_chan(struct chan_list *ch, struct misdn_bchannel *bc)
03652 {
03653    int port;
03654 
03655    if (!ch) {
03656       cb_log(1, 0, "Cannot hangup chan, no ch\n");
03657       return;
03658    }
03659 
03660    port = bc->port;
03661    cb_log(5, port, "hangup_chan called\n");
03662 
03663    if (ch->need_hangup) {
03664       cb_log(2, port, " --> hangup\n");
03665       ch->need_hangup = 0;
03666       ch->need_queue_hangup = 0;
03667       if (ch->ast) {
03668          send_cause2ast(ch->ast, bc, ch);
03669          ast_hangup(ch->ast);
03670       }
03671       return;
03672    }
03673 
03674    if (!ch->need_queue_hangup) {
03675       cb_log(2, port, " --> No need to queue hangup\n");
03676    }
03677 
03678    ch->need_queue_hangup = 0;
03679    if (ch->ast) {
03680       send_cause2ast(ch->ast, bc, ch);
03681       ast_queue_hangup(ch->ast);
03682       cb_log(2, port, " --> queue_hangup\n");
03683    } else {
03684       cb_log(1, port, "Cannot hangup chan, no ast\n");
03685    }
03686 }
03687 
03688 /*!
03689  * \internal
03690  * \brief ISDN asked us to release channel, pendant to misdn_hangup.
03691  *
03692  * \param ch Call channel record to release.
03693  * \param bc Current B channel record associated with ch.
03694  *
03695  * \return Nothing
03696  *
03697  * \note ch must not be referenced after calling.
03698  */
03699 static void release_chan(struct chan_list *ch, struct misdn_bchannel *bc)
03700 {
03701    struct ast_channel *ast;
03702 
03703    ch->state = MISDN_CLEANING;
03704 
03705    ast_mutex_lock(&release_lock);
03706 
03707    cl_dequeue_chan(&cl_te, ch);
03708 
03709    chan_misdn_log(5, bc->port, "release_chan: bc with pid:%d l3id: %x\n", bc->pid, bc->l3_id);
03710 
03711    /* releasing jitterbuffer */
03712    if (ch->jb) {
03713       misdn_jb_destroy(ch->jb);
03714       ch->jb = NULL;
03715    } else {
03716       if (!bc->nojitter) {
03717          chan_misdn_log(5, bc->port, "Jitterbuffer already destroyed.\n");
03718       }
03719    }
03720 
03721    if (ch->overlap_dial) {
03722       if (ch->overlap_dial_task != -1) {
03723          misdn_tasks_remove(ch->overlap_dial_task);
03724          ch->overlap_dial_task = -1;
03725       }
03726       ast_mutex_destroy(&ch->overlap_tv_lock);
03727    }
03728 
03729    if (ch->originator == ORG_AST) {
03730       --misdn_out_calls[bc->port];
03731    } else {
03732       --misdn_in_calls[bc->port];
03733    }
03734 
03735    close(ch->pipe[0]);
03736    close(ch->pipe[1]);
03737 
03738    ast = ch->ast;
03739    if (ast) {
03740       MISDN_ASTERISK_TECH_PVT(ast) = NULL;
03741       chan_misdn_log(1, bc->port,
03742          "* RELEASING CHANNEL pid:%d ctx:%s dad:%s oad:%s\n",
03743          bc->pid,
03744          ast->context,
03745          ast->exten,
03746          ast->cid.cid_num);
03747 
03748       if (ast->_state != AST_STATE_RESERVED) {
03749          chan_misdn_log(3, bc->port, " --> Setting AST State to down\n");
03750          ast_setstate(ast, AST_STATE_DOWN);
03751       }
03752    }
03753 
03754    free(ch);
03755 
03756    ast_mutex_unlock(&release_lock);
03757 }
03758 
03759 /*!
03760  * \internal
03761  * \brief Do everything in release_chan() that makes sense without a bc.
03762  *
03763  * \param ch Call channel record to release.
03764  *
03765  * \return Nothing
03766  *
03767  * \note ch must not be referenced after calling.
03768  */
03769 static void release_chan_early(struct chan_list *ch)
03770 {
03771    struct ast_channel *ast;
03772 
03773    ch->state = MISDN_CLEANING;
03774 
03775    ast_mutex_lock(&release_lock);
03776 
03777    cl_dequeue_chan(&cl_te, ch);
03778 
03779    /* releasing jitterbuffer */
03780    if (ch->jb) {
03781       misdn_jb_destroy(ch->jb);
03782       ch->jb = NULL;
03783    }
03784 
03785    if (ch->overlap_dial) {
03786       if (ch->overlap_dial_task != -1) {
03787          misdn_tasks_remove(ch->overlap_dial_task);
03788          ch->overlap_dial_task = -1;
03789       }
03790       ast_mutex_destroy(&ch->overlap_tv_lock);
03791    }
03792 
03793    if (ch->hold.state != MISDN_HOLD_IDLE) {
03794       if (ch->originator == ORG_AST) {
03795          --misdn_out_calls[ch->hold.port];
03796       } else {
03797          --misdn_in_calls[ch->hold.port];
03798       }
03799    }
03800 
03801    close(ch->pipe[0]);
03802    close(ch->pipe[1]);
03803 
03804    ast = ch->ast;
03805    if (ast) {
03806       MISDN_ASTERISK_TECH_PVT(ast) = NULL;
03807       if (ast->_state != AST_STATE_RESERVED) {
03808          ast_setstate(ast, AST_STATE_DOWN);
03809       }
03810    }
03811 
03812    free(ch);
03813 
03814    ast_mutex_unlock(&release_lock);
03815 }
03816 
03817 /*!
03818  * \internal
03819  * \brief Attempt to transfer the active channel party to the held channel party.
03820  *
03821  * \param active_ch Channel currently connected.
03822  * \param held_ch Channel currently on hold.
03823  *
03824  * \retval 0 on success.
03825  * \retval -1 on error.
03826  */
03827 static int misdn_attempt_transfer(struct chan_list *active_ch, struct chan_list *held_ch)
03828 {
03829    int retval;
03830    struct ast_channel *bridged;
03831 
03832    switch (active_ch->state) {
03833    case MISDN_PROCEEDING:
03834    case MISDN_PROGRESS:
03835    case MISDN_ALERTING:
03836    case MISDN_CONNECTED:
03837       break;
03838    default:
03839       return -1;
03840    }
03841 
03842    bridged = ast_bridged_channel(held_ch->ast);
03843    if (bridged) {
03844       ast_queue_control(held_ch->ast, AST_CONTROL_UNHOLD);
03845       held_ch->hold.state = MISDN_HOLD_TRANSFER;
03846 
03847       chan_misdn_log(1, held_ch->hold.port, "TRANSFERRING %s to %s\n",
03848          held_ch->ast->name, active_ch->ast->name);
03849       retval = ast_channel_masquerade(active_ch->ast, bridged);
03850    } else {
03851       /*
03852        * Could not transfer.  Held channel is not bridged anymore.
03853        * Held party probably got tired of waiting and hung up.
03854        */
03855       retval = -1;
03856    }
03857 
03858    return retval;
03859 }
03860 
03861 
03862 static void do_immediate_setup(struct misdn_bchannel *bc, struct chan_list *ch, struct ast_channel *ast)
03863 {
03864    char predial[256]="";
03865    char *p = predial;
03866   
03867    struct ast_frame fr;
03868 
03869    strncpy(predial, ast->exten, sizeof(predial) -1 );
03870 
03871    ch->state = MISDN_DIALING;
03872 
03873    if (!ch->noautorespond_on_setup) {
03874       if (bc->nt) {
03875          int ret; 
03876          ret = misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE );
03877       } else {
03878          int ret;
03879          if ( misdn_lib_is_ptp(bc->port)) {
03880             ret = misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE );
03881          } else {
03882             ret = misdn_lib_send_event(bc, EVENT_PROCEEDING );
03883          }
03884       }
03885    } else {
03886       ch->state = MISDN_INCOMING_SETUP;
03887    }
03888 
03889    chan_misdn_log(1, bc->port, "* Starting Ast ctx:%s dad:%s oad:%s with 's' extension\n", ast->context, ast->exten, ast->cid.cid_num);
03890   
03891    strcpy(ast->exten, "s");
03892  
03893    if (!ast_canmatch_extension(ast, ast->context, ast->exten, 1, bc->oad) || pbx_start_chan(ch) < 0) {
03894       ast = NULL;
03895       bc->out_cause = AST_CAUSE_UNALLOCATED;
03896       hangup_chan(ch, bc);
03897       hanguptone_indicate(ch);
03898 
03899       if (bc->nt)
03900          misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE );
03901       else
03902          misdn_lib_send_event(bc, EVENT_DISCONNECT );
03903    }
03904   
03905   
03906    while (!ast_strlen_zero(p) ) {
03907       fr.frametype = AST_FRAME_DTMF;
03908       fr.subclass = *p;
03909       fr.src = NULL;
03910       fr.data = NULL;
03911       fr.datalen = 0;
03912       fr.samples = 0;
03913       fr.mallocd = 0;
03914       fr.offset = 0;
03915       fr.delivery = ast_tv(0,0);
03916 
03917       if (ch->ast && MISDN_ASTERISK_PVT(ch->ast) && MISDN_ASTERISK_TECH_PVT(ch->ast)) {
03918          ast_queue_frame(ch->ast, &fr);
03919       }
03920       p++;
03921    }
03922 }
03923 
03924 
03925 
03926 static void send_cause2ast(struct ast_channel *ast, struct misdn_bchannel *bc, struct chan_list *ch) {
03927    if (!ast) {
03928       chan_misdn_log(1, 0, "send_cause2ast: No Ast\n");
03929       return;
03930    }
03931    if (!bc) {
03932       chan_misdn_log(1, 0, "send_cause2ast: No BC\n");
03933       return;
03934    }
03935    if (!ch) {
03936       chan_misdn_log(1, 0, "send_cause2ast: No Ch\n");
03937       return;
03938    }
03939 
03940    ast->hangupcause = bc->cause;
03941 
03942    switch (bc->cause) {
03943 
03944    case AST_CAUSE_UNALLOCATED:
03945    case AST_CAUSE_NO_ROUTE_TRANSIT_NET:
03946    case AST_CAUSE_NO_ROUTE_DESTINATION:
03947    case 4:  /* Send special information tone */
03948    case AST_CAUSE_NUMBER_CHANGED:
03949    case AST_CAUSE_DESTINATION_OUT_OF_ORDER:
03950       /* Congestion Cases */
03951       /*
03952        * Not Queueing the Congestion anymore, since we want to hear
03953        * the inband message
03954        *
03955       chan_misdn_log(1, bc ? bc->port : 0, " --> * SEND: Queue Congestion pid:%d\n", bc ? bc->pid : -1);
03956       ch->state = MISDN_BUSY;
03957       
03958       ast_queue_control(ast, AST_CONTROL_CONGESTION);
03959       */
03960       break;
03961 
03962    case AST_CAUSE_CALL_REJECTED:
03963    case AST_CAUSE_USER_BUSY:
03964       ch->state = MISDN_BUSY;
03965 
03966       if (!ch->need_busy) {
03967          chan_misdn_log(1, bc ? bc->port : 0, "Queued busy already\n");
03968          break;
03969       }
03970 
03971       chan_misdn_log(1, bc ? bc->port : 0, " --> * SEND: Queue Busy pid:%d\n", bc ? bc->pid : -1);
03972       
03973       ast_queue_control(ast, AST_CONTROL_BUSY);
03974       
03975       ch->need_busy = 0;
03976       
03977       break;
03978    }
03979 }
03980 
03981 
03982 /*! \brief Import parameters from the dialplan environment variables */
03983 void import_ch(struct ast_channel *chan, struct misdn_bchannel *bc, struct chan_list *ch)
03984 {
03985    const char *tmp;
03986 
03987    tmp = pbx_builtin_getvar_helper(chan, "MISDN_PID");
03988    if (tmp) {
03989       ch->other_pid = atoi(tmp);
03990       chan_misdn_log(3, bc->port, " --> IMPORT_PID: importing pid:%s\n", tmp);
03991       if (ch->other_pid > 0) {
03992          ch->other_ch = find_chan_by_pid(cl_te, ch->other_pid);
03993          if (ch->other_ch)
03994             ch->other_ch->other_ch = ch;
03995       }
03996    }
03997 
03998    tmp = pbx_builtin_getvar_helper(chan, "MISDN_ADDRESS_COMPLETE");
03999    if (tmp && (atoi(tmp) == 1)) {
04000       bc->sending_complete = 1;
04001    }
04002 
04003    tmp = pbx_builtin_getvar_helper(chan, "MISDN_USERUSER");
04004    if (tmp) {
04005       ast_log(LOG_NOTICE, "MISDN_USERUSER: %s\n", tmp);
04006       ast_copy_string(bc->uu, tmp, sizeof(bc->uu));
04007       bc->uulen = strlen(bc->uu);
04008    }
04009 
04010    tmp = pbx_builtin_getvar_helper(chan, "MISDN_KEYPAD");
04011    if (tmp) {
04012       ast_copy_string(bc->keypad, tmp, sizeof(bc->keypad));
04013    }
04014 }
04015 
04016 /*! \brief Export parameters to the dialplan environment variables */
04017 void export_ch(struct ast_channel *chan, struct misdn_bchannel *bc, struct chan_list *ch)
04018 {
04019    char tmp[32];
04020    chan_misdn_log(3, bc->port, " --> EXPORT_PID: pid:%d\n", bc->pid);
04021    snprintf(tmp, sizeof(tmp), "%d", bc->pid);
04022    pbx_builtin_setvar_helper(chan, "_MISDN_PID", tmp);
04023 
04024    if (bc->sending_complete) {
04025       snprintf(tmp, sizeof(tmp), "%d", bc->sending_complete);
04026       pbx_builtin_setvar_helper(chan, "MISDN_ADDRESS_COMPLETE", tmp);
04027    }
04028 
04029    if (bc->urate) {
04030       snprintf(tmp, sizeof(tmp), "%d", bc->urate);
04031       pbx_builtin_setvar_helper(chan, "MISDN_URATE", tmp);
04032    }
04033 
04034    if (bc->uulen && (bc->uulen < sizeof(bc->uu))) {
04035       bc->uu[bc->uulen] = 0;
04036       pbx_builtin_setvar_helper(chan, "MISDN_USERUSER", bc->uu);
04037    }
04038 
04039    if (!ast_strlen_zero(bc->keypad)) 
04040       pbx_builtin_setvar_helper(chan, "MISDN_KEYPAD", bc->keypad);
04041 }
04042 
04043 int add_in_calls(int port)
04044 {
04045    int max_in_calls;
04046    
04047    misdn_cfg_get(port, MISDN_CFG_MAX_IN, &max_in_calls, sizeof(max_in_calls));
04048    misdn_in_calls[port]++;
04049 
04050    if (max_in_calls >= 0 && max_in_calls < misdn_in_calls[port]) {
04051       ast_log(LOG_NOTICE, "Marking Incoming Call on port[%d]\n", port);
04052       return misdn_in_calls[port] - max_in_calls;
04053    }
04054    
04055    return 0;
04056 }
04057 
04058 int add_out_calls(int port)
04059 {
04060    int max_out_calls;
04061    
04062    misdn_cfg_get(port, MISDN_CFG_MAX_OUT, &max_out_calls, sizeof(max_out_calls));
04063 
04064    if (max_out_calls >= 0 && max_out_calls <= misdn_out_calls[port]) {
04065       ast_log(LOG_NOTICE, "Rejecting Outgoing Call on port[%d]\n", port);
04066       return (misdn_out_calls[port] + 1) - max_out_calls;
04067    }
04068 
04069    misdn_out_calls[port]++;
04070    
04071    return 0;
04072 }
04073 
04074 static void start_pbx(struct chan_list *ch, struct misdn_bchannel *bc, struct ast_channel *chan) {
04075    if (pbx_start_chan(ch) < 0) {
04076       hangup_chan(ch, bc);
04077       chan_misdn_log(-1, bc->port, "ast_pbx_start returned <0 in SETUP\n");
04078       if (bc->nt) {
04079          hanguptone_indicate(ch);
04080          misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE);
04081       } else
04082          misdn_lib_send_event(bc, EVENT_RELEASE);
04083    }
04084 }
04085 
04086 static void wait_for_digits(struct chan_list *ch, struct misdn_bchannel *bc, struct ast_channel *chan) {
04087    ch->state=MISDN_WAITING4DIGS;
04088    misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE );
04089    if (bc->nt && !bc->dad[0])
04090       dialtone_indicate(ch);
04091 }
04092 
04093 
04094 /************************************************************/
04095 /*  Receive Events from isdn_lib  here                     */
04096 /************************************************************/
04097 static enum event_response_e
04098 cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
04099 {
04100    int msn_valid;
04101    struct chan_list *held_ch;
04102    struct chan_list *ch = find_chan_by_bc(cl_te, bc);
04103    
04104    if (event != EVENT_BCHAN_DATA && event != EVENT_TONE_GENERATE) { /*  Debug Only Non-Bchan */
04105       int debuglevel = 1;
04106       if ( event == EVENT_CLEANUP && !user_data)
04107          debuglevel = 5;
04108 
04109       chan_misdn_log(debuglevel, bc->port, "I IND :%s oad:%s dad:%s pid:%d state:%s\n", manager_isdn_get_info(event), bc->oad, bc->dad, bc->pid, ch ? misdn_get_ch_state(ch) : "none");
04110       if (debuglevel == 1) {
04111          misdn_lib_log_ies(bc);
04112          chan_misdn_log(4, bc->port, " --> bc_state:%s\n", bc_state2str(bc->bc_state));
04113       }
04114    }
04115    
04116    if (!ch) {
04117       switch(event) {
04118       case EVENT_SETUP:
04119       case EVENT_DISCONNECT:
04120       case EVENT_RELEASE:
04121       case EVENT_RELEASE_COMPLETE:
04122       case EVENT_PORT_ALARM:
04123       case EVENT_RETRIEVE:
04124       case EVENT_NEW_BC:
04125       case EVENT_FACILITY:
04126          break;
04127       case EVENT_CLEANUP:
04128       case EVENT_TONE_GENERATE:
04129       case EVENT_BCHAN_DATA:
04130          return -1;
04131       default:
04132          chan_misdn_log(1, bc->port, "Chan not existing at the moment bc->l3id:%x bc:%p event:%s port:%d channel:%d\n", bc->l3_id, bc, manager_isdn_get_info(event), bc->port, bc->channel);
04133          return -1;
04134       }
04135    }
04136    
04137    if (ch) {
04138       switch (event) {
04139       case EVENT_TONE_GENERATE:
04140          break;
04141       case EVENT_DISCONNECT:
04142       case EVENT_RELEASE:
04143       case EVENT_RELEASE_COMPLETE:
04144       case EVENT_CLEANUP:
04145       case EVENT_TIMEOUT:
04146          if (!ch->ast)
04147             chan_misdn_log(3, bc->port, "ast_hangup already called, so we have no ast ptr anymore in event(%s)\n", manager_isdn_get_info(event));
04148          break;
04149       default:
04150          if (!ch->ast  || !MISDN_ASTERISK_PVT(ch->ast) || !MISDN_ASTERISK_TECH_PVT(ch->ast)) {
04151             if (event != EVENT_BCHAN_DATA)
04152                ast_log(LOG_NOTICE, "No Ast or No private Pointer in Event (%d:%s)\n", event, manager_isdn_get_info(event));
04153             return -1;
04154          }
04155       }
04156    }
04157    
04158    
04159    switch (event) {
04160    case EVENT_PORT_ALARM:
04161       {
04162          int boa = 0;
04163          misdn_cfg_get(bc->port, MISDN_CFG_ALARM_BLOCK, &boa, sizeof(int));
04164          if (boa) {
04165             cb_log(1, bc->port, " --> blocking\n");
04166             misdn_lib_port_block(bc->port); 
04167          }
04168       }
04169       break;
04170    case EVENT_BCHAN_ACTIVATED:
04171       break;
04172       
04173    case EVENT_NEW_CHANNEL:
04174       update_name(ch->ast,bc->port,bc->channel);
04175       break;
04176       
04177    case EVENT_NEW_L3ID:
04178       ch->l3id=bc->l3_id;
04179       ch->addr=bc->addr;
04180       break;
04181 
04182    case EVENT_NEW_BC:
04183       if (!ch) {
04184          ch = find_hold_call(cl_te,bc);
04185       }
04186       
04187       if (!ch) {
04188          ast_log(LOG_WARNING, "NEW_BC without chan_list?\n");
04189          break;
04190       }
04191 
04192       if (bc)
04193          ch->bc = (struct misdn_bchannel *)user_data;
04194       break;
04195       
04196    case EVENT_DTMF_TONE:
04197    {
04198       /*  sending INFOS as DTMF-Frames :) */
04199       struct ast_frame fr;
04200 
04201       memset(&fr, 0, sizeof(fr));
04202       fr.frametype = AST_FRAME_DTMF;
04203       fr.subclass = bc->dtmf ;
04204       fr.src = NULL;
04205       fr.data = NULL;
04206       fr.datalen = 0;
04207       fr.samples = 0;
04208       fr.mallocd = 0;
04209       fr.offset = 0;
04210       fr.delivery = ast_tv(0,0);
04211       
04212       if (!ch->ignore_dtmf) {
04213          chan_misdn_log(2, bc->port, " --> DTMF:%c\n", bc->dtmf);
04214          ast_queue_frame(ch->ast, &fr);
04215       } else {
04216          chan_misdn_log(2, bc->port, " --> Ignoring DTMF:%c due to bridge flags\n", bc->dtmf);
04217       }
04218    }
04219       break;
04220    case EVENT_STATUS:
04221       break;
04222     
04223    case EVENT_INFORMATION:
04224    {
04225       if ( ch->state != MISDN_CONNECTED ) 
04226          stop_indicate(ch);
04227    
04228       if (!ch->ast)
04229          break;
04230 
04231       if (ch->state == MISDN_WAITING4DIGS ) {
04232          /*  Ok, incomplete Setup, waiting till extension exists */
04233          if (ast_strlen_zero(bc->info_dad) && ! ast_strlen_zero(bc->keypad)) {
04234             chan_misdn_log(1, bc->port, " --> using keypad as info\n");
04235             ast_copy_string(bc->info_dad, bc->keypad, sizeof(bc->info_dad));
04236          }
04237 
04238          strncat(bc->dad, bc->info_dad, sizeof(bc->dad) - strlen(bc->dad) - 1);
04239          ast_copy_string(ch->ast->exten, bc->dad, sizeof(ch->ast->exten));
04240 
04241          /* Check for Pickup Request first */
04242          if (!strcmp(ch->ast->exten, ast_pickup_ext())) {
04243             if (ast_pickup_call(ch->ast)) {
04244                hangup_chan(ch, bc);
04245             } else {
04246                struct ast_channel *chan = ch->ast;
04247                ch->state = MISDN_CALLING_ACKNOWLEDGE;
04248                ast_setstate(chan, AST_STATE_DOWN);
04249                hangup_chan(ch, bc);
04250                ch->ast = NULL;
04251                break;
04252             }
04253          }
04254          
04255          if (!ast_canmatch_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) {
04256             if (ast_exists_extension(ch->ast, ch->context, "i", 1, bc->oad)) {
04257                ast_log(LOG_WARNING,
04258                   "Extension '%s@%s' can never match. Jumping to 'i' extension. port:%d\n",
04259                   bc->dad, ch->context, bc->port);
04260                strcpy(ch->ast->exten, "i");
04261 
04262                ch->state = MISDN_DIALING;
04263                start_pbx(ch, bc, ch->ast);
04264                break;
04265             }
04266 
04267             ast_log(LOG_WARNING,
04268                "Extension '%s@%s' can never match. Disconnecting. port:%d\n"
04269                "\tMaybe you want to add an 'i' extension to catch this case.\n",
04270                bc->dad, ch->context, bc->port);
04271 
04272             if (bc->nt)
04273                hanguptone_indicate(ch);
04274             ch->state = MISDN_EXTCANTMATCH;
04275             bc->out_cause = AST_CAUSE_UNALLOCATED;
04276 
04277             misdn_lib_send_event(bc, EVENT_DISCONNECT);
04278             break;
04279          }
04280 
04281          if (ch->overlap_dial) {
04282             ast_mutex_lock(&ch->overlap_tv_lock);
04283             ch->overlap_tv = ast_tvnow();
04284             ast_mutex_unlock(&ch->overlap_tv_lock);
04285             if (ch->overlap_dial_task == -1) {
04286                ch->overlap_dial_task = 
04287                   misdn_tasks_add_variable(ch->overlap_dial, misdn_overlap_dial_task, ch);
04288             }
04289             break;
04290          }
04291 
04292          if (ast_exists_extension(ch->ast, ch->context, bc->dad, 1, bc->oad))  {
04293             
04294             ch->state = MISDN_DIALING;
04295             start_pbx(ch, bc, ch->ast);
04296          }
04297       } else {
04298          /*  sending INFOS as DTMF-Frames :) */
04299          struct ast_frame fr;
04300          int digits;
04301 
04302          memset(&fr, 0, sizeof(fr));
04303          fr.frametype = AST_FRAME_DTMF;
04304          fr.subclass = bc->info_dad[0] ;
04305          fr.src = NULL;
04306          fr.data = NULL;
04307          fr.datalen = 0;
04308          fr.samples = 0;
04309          fr.mallocd = 0;
04310          fr.offset = 0;
04311          fr.delivery = ast_tv(0,0);
04312 
04313          misdn_cfg_get(0, MISDN_GEN_APPEND_DIGITS2EXTEN, &digits, sizeof(int));
04314          if (ch->state != MISDN_CONNECTED ) {
04315             if (digits) {
04316                strncat(bc->dad, bc->info_dad, sizeof(bc->dad) - strlen(bc->dad) - 1);
04317                ast_copy_string(ch->ast->exten, bc->dad, sizeof(ch->ast->exten));
04318                ast_cdr_update(ch->ast);
04319             }
04320             
04321             ast_queue_frame(ch->ast, &fr);
04322          }
04323       }
04324    }
04325       break;
04326    case EVENT_SETUP:
04327    {
04328       struct chan_list *ch = find_chan_by_bc(cl_te, bc);
04329       struct ast_channel *chan;
04330       int exceed;
04331       int pres, screen;
04332       int ai;
04333       int im;
04334 
04335       if (ch) {
04336          switch (ch->state) {
04337          case MISDN_NOTHING:
04338             ch = NULL;
04339             break;
04340          default:
04341             chan_misdn_log(1, bc->port, " --> Ignoring Call we have already one\n");
04342             return RESPONSE_IGNORE_SETUP_WITHOUT_CLOSE; /*  Ignore MSNs which are not in our List */
04343          }
04344       }
04345 
04346       msn_valid = misdn_cfg_is_msn_valid(bc->port, bc->dad);
04347       if (!bc->nt && ! msn_valid) {
04348          chan_misdn_log(1, bc->port, " --> Ignoring Call, its not in our MSN List\n");
04349          return RESPONSE_IGNORE_SETUP; /*  Ignore MSNs which are not in our List */
04350       }
04351 
04352       if (bc->cw) {
04353          int cause;
04354          chan_misdn_log(0, bc->port, " --> Call Waiting on PMP sending RELEASE_COMPLETE\n");
04355          misdn_cfg_get(bc->port, MISDN_CFG_REJECT_CAUSE, &cause, sizeof(cause));
04356          bc->out_cause = cause ? cause : AST_CAUSE_NORMAL_CLEARING;
04357          return RESPONSE_RELEASE_SETUP;
04358       }
04359 
04360       print_bearer(bc);
04361 
04362       ch = init_chan_list(ORG_MISDN);
04363 
04364       if (!ch) {
04365          chan_misdn_log(-1, bc->port, "cb_events: malloc for chan_list failed!\n");
04366          return 0;
04367       }
04368 
04369       ch->bc = bc;
04370       ch->l3id = bc->l3_id;
04371       ch->addr = bc->addr;
04372       ch->originator = ORG_MISDN;
04373 
04374       chan = misdn_new(ch, AST_STATE_RESERVED, bc->dad, bc->oad, AST_FORMAT_ALAW, bc->port, bc->channel);
04375       if (!chan) {
04376          free(ch);
04377          misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE);
04378          ast_log(LOG_ERROR, "cb_events: misdn_new failed !\n"); 
04379          return 0;
04380       }
04381 
04382       ch->ast = chan;
04383 
04384       if ((exceed = add_in_calls(bc->port))) {
04385          char tmp[16];
04386          snprintf(tmp, sizeof(tmp), "%d", exceed);
04387          pbx_builtin_setvar_helper(chan, "MAX_OVERFLOW", tmp);
04388       }
04389 
04390       read_config(ch, ORG_MISDN);
04391 
04392       export_ch(chan, bc, ch);
04393 
04394       ch->ast->rings = 1;
04395       ast_setstate(ch->ast, AST_STATE_RINGING);
04396 
04397       switch (bc->pres) {
04398       case 1:
04399          pres = AST_PRES_RESTRICTED;
04400          chan_misdn_log(2, bc->port, " --> PRES: Restricted (1)\n");
04401          break;
04402       case 2:
04403          pres = AST_PRES_UNAVAILABLE;
04404          chan_misdn_log(2, bc->port, " --> PRES: Unavailable (2)\n");
04405          break;
04406       default:
04407          pres = AST_PRES_ALLOWED;
04408          chan_misdn_log(2, bc->port, " --> PRES: Allowed (%d)\n", bc->pres);
04409          break;
04410       }
04411 
04412       switch (bc->screen) {
04413       default:
04414       case 0:
04415          screen = AST_PRES_USER_NUMBER_UNSCREENED;
04416          chan_misdn_log(2, bc->port, " --> SCREEN: Unscreened (%d)\n", bc->screen);
04417          break;
04418       case 1:
04419          screen = AST_PRES_USER_NUMBER_PASSED_SCREEN;
04420          chan_misdn_log(2, bc->port, " --> SCREEN: Passed screen (1)\n");
04421          break;
04422       case 2:
04423          screen = AST_PRES_USER_NUMBER_FAILED_SCREEN;
04424          chan_misdn_log(2, bc->port, " --> SCREEN: failed screen (2)\n");
04425          break;
04426       case 3:
04427          screen = AST_PRES_NETWORK_NUMBER;
04428          chan_misdn_log(2, bc->port, " --> SCREEN: Network Number (3)\n");
04429          break;
04430       }
04431 
04432       chan->cid.cid_pres = pres | screen;
04433 
04434       pbx_builtin_setvar_helper(chan, "TRANSFERCAPABILITY", ast_transfercapability2str(bc->capability));
04435       chan->transfercapability = bc->capability;
04436 
04437       switch (bc->capability) {
04438       case INFO_CAPABILITY_DIGITAL_UNRESTRICTED:
04439          pbx_builtin_setvar_helper(chan, "CALLTYPE", "DIGITAL");
04440          break;
04441       default:
04442          pbx_builtin_setvar_helper(chan, "CALLTYPE", "SPEECH");
04443       }
04444 
04445       /** queue new chan **/
04446       cl_queue_chan(&cl_te, ch);
04447 
04448       if (!strstr(ch->allowed_bearers, "all")) {
04449          int i;
04450 
04451          for (i = 0; i < ARRAY_LEN(allowed_bearers_array); ++i) {
04452             if (allowed_bearers_array[i].cap == bc->capability) {
04453                if (strstr(ch->allowed_bearers, allowed_bearers_array[i].name)) {
04454                   /* The bearer capability is allowed */
04455                   if (allowed_bearers_array[i].deprecated) {
04456                      chan_misdn_log(0, bc->port, "%s in allowed_bearers list is deprecated\n",
04457                         allowed_bearers_array[i].name);
04458                   }
04459                   break;
04460                }
04461             }
04462          }  /* end for */
04463          if (i == ARRAY_LEN(allowed_bearers_array)) {
04464             /* We did not find the bearer capability */
04465             chan_misdn_log(0, bc->port, "Bearer capability not allowed: %s(%d)\n",
04466                bearer2str(bc->capability), bc->capability);
04467             bc->out_cause = AST_CAUSE_INCOMPATIBLE_DESTINATION;
04468 
04469             ch->state = MISDN_EXTCANTMATCH;
04470             misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE);
04471             return RESPONSE_OK;
04472          }
04473       }
04474 
04475       /* Check for Pickup Request first */
04476       if (!strcmp(chan->exten, ast_pickup_ext())) {
04477          if (!ch->noautorespond_on_setup) {
04478             int ret;/** Sending SETUP_ACK**/
04479             ret = misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE );
04480          } else {
04481             ch->state = MISDN_INCOMING_SETUP;
04482          }
04483          if (ast_pickup_call(chan)) {
04484             hangup_chan(ch, bc);
04485          } else {
04486             ch->state = MISDN_CALLING_ACKNOWLEDGE;
04487             ast_setstate(chan, AST_STATE_DOWN);
04488             hangup_chan(ch, bc);
04489             ch->ast = NULL;
04490             break;
04491          }
04492       }
04493 
04494       /*
04495        * added support for s extension hope it will help those poor cretains
04496        * which haven't overlap dial.
04497        */
04498       misdn_cfg_get(bc->port, MISDN_CFG_ALWAYS_IMMEDIATE, &ai, sizeof(ai));
04499       if (ai) {
04500          do_immediate_setup(bc, ch, chan);
04501          break;
04502       }
04503 
04504       /* check if we should jump into s when we have no dad */
04505       misdn_cfg_get(bc->port, MISDN_CFG_IMMEDIATE, &im, sizeof(im));
04506       if (im && ast_strlen_zero(bc->dad)) {
04507          do_immediate_setup(bc, ch, chan);
04508          break;
04509       }
04510 
04511       chan_misdn_log(5, bc->port, "CONTEXT:%s\n", ch->context);
04512       if(!ast_canmatch_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) {
04513          if (ast_exists_extension(ch->ast, ch->context, "i", 1, bc->oad)) {
04514             ast_log(LOG_WARNING,
04515                "Extension '%s@%s' can never match. Jumping to 'i' extension. port:%d\n",
04516                bc->dad, ch->context, bc->port);
04517             strcpy(ch->ast->exten, "i");
04518             misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE);
04519             ch->state = MISDN_DIALING;
04520             start_pbx(ch, bc, chan);
04521             break;
04522          }
04523 
04524          ast_log(LOG_WARNING,
04525             "Extension '%s@%s' can never match. Disconnecting. port:%d\n"
04526             "\tMaybe you want to add an 'i' extension to catch this case.\n",
04527             bc->dad, ch->context, bc->port);
04528          if (bc->nt)
04529             hanguptone_indicate(ch);
04530 
04531          ch->state = MISDN_EXTCANTMATCH;
04532          bc->out_cause = AST_CAUSE_UNALLOCATED;
04533 
04534          if (bc->nt)
04535             misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE );
04536          else
04537             misdn_lib_send_event(bc, EVENT_RELEASE );
04538 
04539          break;
04540       }
04541 
04542       /* Whatever happens, when sending_complete is set or we are PTMP TE, we will definitely 
04543        * jump into the dialplan, when the dialed extension does not exist, the 's' extension 
04544        * will be used by Asterisk automatically. */
04545       if (bc->sending_complete || (!bc->nt && !misdn_lib_is_ptp(bc->port))) {
04546          if (!ch->noautorespond_on_setup) {
04547             ch->state=MISDN_DIALING;
04548             misdn_lib_send_event(bc, EVENT_PROCEEDING );
04549          } else {
04550             ch->state = MISDN_INCOMING_SETUP;
04551          }
04552          start_pbx(ch, bc, chan);
04553          break;
04554       }
04555 
04556 
04557       /*
04558        * When we are NT and overlapdial is set and if 
04559        * the number is empty, we wait for the ISDN timeout
04560        * instead of our own timer.
04561        */
04562       if (ch->overlap_dial && bc->nt && !bc->dad[0] ) {
04563          wait_for_digits(ch, bc, chan);
04564          break;
04565       }
04566 
04567       /* 
04568        * If overlapdial we will definitely send a SETUP_ACKNOWLEDGE and wait for more 
04569        * Infos with a Interdigit Timeout.
04570        * */
04571       if (ch->overlap_dial) {
04572          ast_mutex_lock(&ch->overlap_tv_lock);
04573          ch->overlap_tv = ast_tvnow();
04574          ast_mutex_unlock(&ch->overlap_tv_lock);
04575 
04576          wait_for_digits(ch, bc, chan);
04577          if (ch->overlap_dial_task == -1) 
04578             ch->overlap_dial_task = 
04579                misdn_tasks_add_variable(ch->overlap_dial, misdn_overlap_dial_task, ch);
04580 
04581          break;
04582       }
04583 
04584       /* If the extension does not exist and we're not TE_PTMP we wait for more digits 
04585        * without interdigit timeout.
04586        * */
04587       if (!ast_exists_extension(ch->ast, ch->context, bc->dad, 1, bc->oad))  {
04588          wait_for_digits(ch, bc, chan);
04589          break;
04590       }
04591 
04592       /*
04593        * If the extension exists let's just jump into it.
04594        * */
04595       if (ast_exists_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) {
04596          if (bc->need_more_infos)
04597             misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE );
04598          else
04599             misdn_lib_send_event(bc, EVENT_PROCEEDING);
04600 
04601          ch->state = MISDN_DIALING;
04602          start_pbx(ch, bc, chan);
04603          break;
04604       }
04605    }
04606    break;
04607 
04608    case EVENT_SETUP_ACKNOWLEDGE:
04609    {
04610       ch->state = MISDN_CALLING_ACKNOWLEDGE;
04611 
04612       if (bc->channel) 
04613          update_name(ch->ast,bc->port,bc->channel);
04614       
04615       if (!ast_strlen_zero(bc->infos_pending)) {
04616          /* TX Pending Infos */
04617          strncat(bc->dad, bc->infos_pending, sizeof(bc->dad) - strlen(bc->dad) - 1);
04618 
04619          if (!ch->ast)
04620             break;
04621          ast_copy_string(ch->ast->exten, bc->dad, sizeof(ch->ast->exten));
04622          ast_copy_string(bc->info_dad, bc->infos_pending, sizeof(bc->info_dad));
04623          ast_copy_string(bc->infos_pending, "", sizeof(bc->infos_pending));
04624 
04625          misdn_lib_send_event(bc, EVENT_INFORMATION);
04626       }
04627    }
04628    break;
04629    case EVENT_PROCEEDING:
04630    {
04631       if (bc->channel) 
04632          update_name(ch->ast, bc->port, bc->channel);
04633 
04634       if (misdn_cap_is_speech(bc->capability) &&
04635            misdn_inband_avail(bc) ) {
04636          start_bc_tones(ch);
04637       }
04638 
04639       ch->state = MISDN_PROCEEDING;
04640       
04641       if (!ch->ast)
04642          break;
04643 
04644       ast_queue_control(ch->ast, AST_CONTROL_PROCEEDING);
04645    }
04646    break;
04647    case EVENT_PROGRESS:
04648       if (bc->channel) 
04649          update_name(ch->ast, bc->port, bc->channel);
04650 
04651       if (!bc->nt ) {
04652          if ( misdn_cap_is_speech(bc->capability) &&
04653               misdn_inband_avail(bc)
04654             ) {
04655             start_bc_tones(ch);
04656          }
04657          
04658          ch->state = MISDN_PROGRESS;
04659 
04660          if (!ch->ast)
04661             break;
04662          ast_queue_control(ch->ast, AST_CONTROL_PROGRESS);
04663       }
04664       break;
04665       
04666       
04667    case EVENT_ALERTING:
04668    {
04669       if (bc->channel) 
04670          update_name(ch->ast, bc->port, bc->channel);
04671 
04672       ch->state = MISDN_ALERTING;
04673       
04674       if (!ch->ast)
04675          break;
04676 
04677       ast_queue_control(ch->ast, AST_CONTROL_RINGING);
04678       ast_setstate(ch->ast, AST_STATE_RINGING);
04679       
04680       cb_log(7, bc->port, " --> Set State Ringing\n");
04681       
04682       if (misdn_cap_is_speech(bc->capability) && misdn_inband_avail(bc)) {
04683          cb_log(1, bc->port, "Starting Tones, we have inband Data\n");
04684          start_bc_tones(ch);
04685       } else {
04686          cb_log(3, bc->port, " --> We have no inband Data, the other end must create ringing\n");
04687          if (ch->far_alerting) {
04688             cb_log(1, bc->port, " --> The other end can not do ringing eh ?.. we must do all ourself..");
04689             start_bc_tones(ch);
04690             /*tone_indicate(ch, TONE_FAR_ALERTING);*/
04691          }
04692       }
04693    }
04694    break;
04695    case EVENT_CONNECT:
04696    {
04697       struct ast_channel *bridged;
04698 
04699       /*we answer when we've got our very new L3 ID from the NT stack */
04700       misdn_lib_send_event(bc, EVENT_CONNECT_ACKNOWLEDGE);
04701 
04702       if (!ch->ast)
04703          break;
04704 
04705       bridged = ast_bridged_channel(ch->ast);
04706       stop_indicate(ch);
04707 
04708       if (bridged && !strcasecmp(bridged->tech->type, "mISDN")) {
04709          struct chan_list *bridged_ch = MISDN_ASTERISK_TECH_PVT(bridged);
04710 
04711          chan_misdn_log(1, bc->port, " --> copying cpndialplan:%d and cad:%s to the A-Channel\n", bc->cpnnumplan, bc->cad);
04712          if (bridged_ch) {
04713             bridged_ch->bc->cpnnumplan = bc->cpnnumplan;
04714             ast_copy_string(bridged_ch->bc->cad, bc->cad, sizeof(bridged_ch->bc->cad));
04715          }
04716       }
04717    }
04718    ch->l3id=bc->l3_id;
04719    ch->addr=bc->addr;
04720 
04721    start_bc_tones(ch);
04722    
04723    ch->state = MISDN_CONNECTED;
04724    
04725    ast_queue_control(ch->ast, AST_CONTROL_ANSWER);
04726    break;
04727    case EVENT_CONNECT_ACKNOWLEDGE:
04728    {
04729       ch->l3id = bc->l3_id;
04730       ch->addr = bc->addr;
04731 
04732       start_bc_tones(ch);
04733 
04734       ch->state = MISDN_CONNECTED;
04735    }
04736    break;
04737    case EVENT_DISCONNECT:
04738       /*we might not have an ch->ast ptr here anymore*/
04739       if (ch) {
04740          chan_misdn_log(3, bc->port, " --> org:%d nt:%d, inbandavail:%d state:%d\n", ch->originator, bc->nt, misdn_inband_avail(bc), ch->state);
04741          if (ch->originator == ORG_AST && !bc->nt && misdn_inband_avail(bc) && ch->state != MISDN_CONNECTED) {
04742             /* If there's inband information available (e.g. a
04743                recorded message saying what was wrong with the
04744                dialled number, or perhaps even giving an
04745                alternative number, then play it instead of
04746                immediately releasing the call */
04747             chan_misdn_log(1, bc->port, " --> Inband Info Avail, not sending RELEASE\n");
04748       
04749             ch->state = MISDN_DISCONNECTED;
04750             start_bc_tones(ch);
04751 
04752             if (ch->ast) {
04753                ch->ast->hangupcause = bc->cause;
04754                if (bc->cause == AST_CAUSE_USER_BUSY)
04755                   ast_queue_control(ch->ast, AST_CONTROL_BUSY);
04756             }
04757             ch->need_busy = 0;
04758             break;
04759          }
04760 
04761          bc->need_disconnect = 0;
04762          stop_bc_tones(ch);
04763 
04764          /* Check for held channel, to implement transfer */
04765          held_ch = find_hold_call(cl_te, bc);
04766          if (!held_ch || !ch->ast || misdn_attempt_transfer(ch, held_ch)) {
04767             hangup_chan(ch, bc);
04768          }
04769       } else {
04770          held_ch = find_hold_call_l3(cl_te, bc->l3_id);
04771          if (held_ch && held_ch->hold.state == MISDN_HOLD_ACTIVE) {
04772             bc->need_disconnect = 0;
04773 
04774 #if defined(TRANSFER_ON_HELD_CALL_HANGUP)
04775             /*
04776              * Some phones disconnect the held call and the active call at the
04777              * same time to do the transfer.  Unfortunately, either call could
04778              * be disconnected first.
04779              */
04780             ch = find_hold_active_call(cl_te, bc);
04781             if (!ch || misdn_attempt_transfer(ch, held_ch)) {
04782                held_ch->hold.state = MISDN_HOLD_DISCONNECT;
04783                hangup_chan(held_ch, bc);
04784             }
04785 #else
04786             hangup_chan(held_ch, bc);
04787 #endif   /* defined(TRANSFER_ON_HELD_CALL_HANGUP) */
04788          }
04789       }
04790       bc->out_cause = -1;
04791       if (bc->need_release)
04792          misdn_lib_send_event(bc, EVENT_RELEASE);
04793       break;
04794    
04795    case EVENT_RELEASE:
04796       if (!ch) {
04797          ch = find_hold_call_l3(cl_te, bc->l3_id);
04798          if (!ch) {
04799             chan_misdn_log(1, bc->port,
04800                " --> no Ch, so we've already released. (%s)\n",
04801                manager_isdn_get_info(event));
04802             return -1;
04803          }
04804       }
04805 
04806       bc->need_disconnect = 0;
04807       bc->need_release = 0;
04808 
04809       hangup_chan(ch, bc);
04810       release_chan(ch, bc);
04811       break;
04812    case EVENT_RELEASE_COMPLETE:
04813       if (!ch) {
04814          ch = find_hold_call_l3(cl_te, bc->l3_id);
04815          if (!ch) {
04816             chan_misdn_log(1, bc->port,
04817                " --> no Ch, so we've already released. (%s)\n",
04818                manager_isdn_get_info(event));
04819             break;
04820          }
04821       }
04822 
04823       bc->need_disconnect = 0;
04824       bc->need_release = 0;
04825       bc->need_release_complete = 0;
04826 
04827       stop_bc_tones(ch);
04828       hangup_chan(ch, bc);
04829       release_chan(ch, bc);
04830       break;
04831    case EVENT_BCHAN_ERROR:
04832    case EVENT_CLEANUP:
04833    {
04834       stop_bc_tones(ch);
04835       
04836       switch (ch->state) {
04837       case MISDN_CALLING:
04838          bc->cause = AST_CAUSE_DESTINATION_OUT_OF_ORDER;
04839          break;
04840       default:
04841          break;
04842       }
04843       
04844       hangup_chan(ch, bc);
04845       release_chan(ch, bc);
04846    }
04847    break;
04848 
04849    case EVENT_TONE_GENERATE:
04850    {
04851       int tone_len = bc->tone_cnt;
04852       struct ast_channel *ast = ch->ast;
04853       void *tmp;
04854       int res;
04855       int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples);
04856 
04857       chan_misdn_log(9, bc->port, "TONE_GEN: len:%d\n", tone_len);
04858 
04859       if (!ast)
04860          break;
04861 
04862       if (!ast->generator)
04863          break;
04864 
04865       tmp = ast->generatordata;
04866       ast->generatordata = NULL;
04867       generate = ast->generator->generate;
04868 
04869       if (tone_len < 0 || tone_len > 512 ) {
04870          ast_log(LOG_NOTICE, "TONE_GEN: len was %d, set to 128\n", tone_len);
04871          tone_len = 128;
04872       }
04873 
04874       res = generate(ast, tmp, tone_len, tone_len);
04875       ast->generatordata = tmp;
04876       
04877       if (res) {
04878          ast_log(LOG_WARNING, "Auto-deactivating generator\n");
04879          ast_deactivate_generator(ast);
04880       } else {
04881          bc->tone_cnt = 0;
04882       }
04883    }
04884    break;
04885 
04886    case EVENT_BCHAN_DATA:
04887    {
04888       if (!misdn_cap_is_speech(ch->bc->capability)) {
04889          struct ast_frame frame;
04890          /*In Data Modes we queue frames*/
04891          memset(&frame, 0, sizeof(frame));
04892          frame.frametype  = AST_FRAME_VOICE; /*we have no data frames yet*/
04893          frame.subclass = AST_FORMAT_ALAW;
04894          frame.datalen = bc->bframe_len;
04895          frame.samples = bc->bframe_len;
04896          frame.mallocd = 0;
04897          frame.offset = 0;
04898          frame.delivery = ast_tv(0,0);
04899          frame.src = NULL;
04900          frame.data = bc->bframe;
04901 
04902          if (ch->ast) 
04903             ast_queue_frame(ch->ast, &frame);
04904       } else {
04905          struct pollfd pfd = { .fd = ch->pipe[1], .events = POLLOUT };
04906          int t;
04907 
04908          t = ast_poll(&pfd, 1, 0);
04909 
04910          if (t < 0) {
04911             chan_misdn_log(-1, bc->port, "poll() error (err=%s)\n", strerror(errno));
04912             break;
04913          }
04914 
04915          if (!t) {
04916             chan_misdn_log(9, bc->port, "poll() timed out\n");
04917             break;
04918          }
04919 
04920          if (pfd.revents & POLLOUT) {
04921             chan_misdn_log(9, bc->port, "writing %d bytes to asterisk\n", bc->bframe_len);
04922             if (write(ch->pipe[1], bc->bframe, bc->bframe_len) <= 0) {
04923                chan_misdn_log(0, bc->port, "Write returned <=0 (err=%s) --> hanging up channel\n", strerror(errno));
04924 
04925                stop_bc_tones(ch);
04926                hangup_chan(ch, bc);
04927                release_chan(ch, bc);
04928             }
04929          } else {
04930             chan_misdn_log(1, bc->port, "Write Pipe full!\n");
04931          }
04932       }
04933    }
04934    break;
04935    case EVENT_TIMEOUT:
04936    {
04937       if (ch && bc)
04938          chan_misdn_log(1, bc->port, "--> state: %s\n", misdn_get_ch_state(ch));
04939 
04940       switch (ch->state) {
04941       case MISDN_DIALING:
04942       case MISDN_PROGRESS:
04943          if (bc->nt && !ch->nttimeout)
04944             break;
04945          
04946       case MISDN_CALLING:
04947       case MISDN_ALERTING:
04948       case MISDN_PROCEEDING:
04949       case MISDN_CALLING_ACKNOWLEDGE:
04950          if (bc->nt) {
04951             bc->progress_indicator = INFO_PI_INBAND_AVAILABLE;
04952             hanguptone_indicate(ch);
04953          }
04954             
04955          bc->out_cause = AST_CAUSE_UNALLOCATED;
04956          misdn_lib_send_event(bc, EVENT_DISCONNECT);
04957          break;
04958 
04959       case MISDN_WAITING4DIGS:
04960          if (bc->nt) {
04961             bc->progress_indicator = INFO_PI_INBAND_AVAILABLE;
04962             bc->out_cause = AST_CAUSE_UNALLOCATED;
04963             hanguptone_indicate(ch);
04964             misdn_lib_send_event(bc, EVENT_DISCONNECT);
04965          } else {
04966             bc->out_cause = AST_CAUSE_NORMAL_CLEARING;
04967             misdn_lib_send_event(bc, EVENT_RELEASE);
04968          }
04969             
04970          break;
04971 
04972       case MISDN_CLEANING: 
04973          chan_misdn_log(1,bc->port," --> in state cleaning .. so ignoring, the stack should clean it for us\n");
04974          break;
04975 
04976       default:
04977          misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE);
04978       }
04979    }
04980    break;
04981 
04982     
04983    /****************************/
04984    /** Supplementary Services **/
04985    /****************************/
04986    case EVENT_RETRIEVE:
04987       if (!ch) {
04988          chan_misdn_log(4, bc->port, " --> no CH, searching for held call\n");
04989          ch = find_hold_call_l3(cl_te, bc->l3_id);
04990          if (!ch || ch->hold.state != MISDN_HOLD_ACTIVE) {
04991             ast_log(LOG_WARNING, "No held call found, cannot Retrieve\n");
04992             misdn_lib_send_event(bc, EVENT_RETRIEVE_REJECT);
04993             break;
04994          }
04995       }
04996 
04997       /* remember the channel again */
04998       ch->bc = bc;
04999 
05000       ch->hold.state = MISDN_HOLD_IDLE;
05001       ch->hold.port = 0;
05002       ch->hold.channel = 0;
05003 
05004       ast_queue_control(ch->ast, AST_CONTROL_UNHOLD);
05005    
05006       if (misdn_lib_send_event(bc, EVENT_RETRIEVE_ACKNOWLEDGE) < 0) {
05007          chan_misdn_log(4, bc->port, " --> RETRIEVE_ACK failed\n");
05008          misdn_lib_send_event(bc, EVENT_RETRIEVE_REJECT);
05009       }
05010       break;
05011     
05012    case EVENT_HOLD:
05013    {
05014       int hold_allowed;
05015       struct ast_channel *bridged;
05016 
05017       misdn_cfg_get(bc->port, MISDN_CFG_HOLD_ALLOWED, &hold_allowed, sizeof(int));
05018 
05019       if (!hold_allowed) {
05020 
05021          chan_misdn_log(-1, bc->port, "Hold not allowed this port.\n");
05022          misdn_lib_send_event(bc, EVENT_HOLD_REJECT);
05023          break;
05024       }
05025 
05026       bridged = ast_bridged_channel(ch->ast);
05027       if (bridged) {
05028          chan_misdn_log(2, bc->port, "Bridge Partner is of type: %s\n", bridged->tech->type);
05029          ch->l3id = bc->l3_id;
05030 
05031          /* forget the channel now */
05032          ch->bc = NULL;
05033          ch->hold.state = MISDN_HOLD_ACTIVE;
05034          ch->hold.port = bc->port;
05035          ch->hold.channel = bc->channel;
05036 
05037          ast_queue_control(ch->ast, AST_CONTROL_HOLD);
05038          
05039          misdn_lib_send_event(bc, EVENT_HOLD_ACKNOWLEDGE);
05040       } else {
05041          misdn_lib_send_event(bc, EVENT_HOLD_REJECT);
05042          chan_misdn_log(0, bc->port, "We aren't bridged to anybody\n");
05043       }
05044    } 
05045    break;
05046    
05047    case EVENT_FACILITY:
05048       if (!ch) {
05049          /* This may come from a call we don't know nothing about, so we ignore it. */
05050          chan_misdn_log(-1, bc->port, "Got EVENT_FACILITY but we don't have a ch!\n");
05051          break;
05052       }
05053 
05054       print_facility(&(bc->fac_in), bc);
05055       
05056       switch (bc->fac_in.Function) {
05057       case Fac_CD:
05058          {
05059             struct ast_channel *bridged = ast_bridged_channel(ch->ast);
05060             struct chan_list *ch_br;
05061             if (bridged && MISDN_ASTERISK_TECH_PVT(bridged)) {
05062                ch_br = MISDN_ASTERISK_TECH_PVT(bridged);
05063                /*ch->state = MISDN_FACILITY_DEFLECTED;*/
05064                if (ch_br->bc) {
05065                   if (ast_exists_extension(bridged, ch->context, (char *)bc->fac_in.u.CDeflection.DeflectedToNumber, 1, bc->oad)) {
05066                      ch_br->state = MISDN_DIALING;
05067                      if (pbx_start_chan(ch_br) < 0) {
05068                         chan_misdn_log(-1, ch_br->bc->port, "ast_pbx_start returned < 0 in misdn_overlap_dial_task\n");
05069                      }
05070                   }
05071                }
05072             }
05073             misdn_lib_send_event(bc, EVENT_DISCONNECT);
05074          } 
05075          break;
05076       case Fac_AOCDCurrency:
05077          {
05078             bc->AOCDtype = Fac_AOCDCurrency;
05079             memcpy(&(bc->AOCD.currency), &(bc->fac_in.u.AOCDcur), sizeof(struct FacAOCDCurrency));
05080             export_aoc_vars(ch->originator, ch->ast, bc);
05081          }
05082          break;
05083       case Fac_AOCDChargingUnit:
05084          {
05085             bc->AOCDtype = Fac_AOCDChargingUnit;
05086             memcpy(&(bc->AOCD.chargingUnit), &(bc->fac_in.u.AOCDchu), sizeof(struct FacAOCDChargingUnit));
05087             export_aoc_vars(ch->originator, ch->ast, bc);
05088          }
05089          break;
05090       default:
05091          chan_misdn_log(0, bc->port," --> not yet handled: facility type:%d\n", bc->fac_in.Function);
05092       }
05093       
05094       break;
05095 
05096    case EVENT_RESTART:
05097 
05098       if (!bc->dummy) {
05099          stop_bc_tones(ch);
05100          release_chan(ch, bc);
05101       }
05102       break;
05103 
05104    default:
05105       chan_misdn_log(1, 0, "Got Unknown Event\n");
05106       break;
05107    }
05108    
05109    return RESPONSE_OK;
05110 }
05111 
05112 /** TE STUFF END **/
05113 
05114 /******************************************
05115  *
05116  *   Asterisk Channel Endpoint END
05117  *
05118  *
05119  *******************************************/
05120 
05121 
05122 
05123 static int unload_module(void)
05124 {
05125    /* First, take us out of the channel loop */
05126    ast_log(LOG_VERBOSE, "-- Unregistering mISDN Channel Driver --\n");
05127 
05128    misdn_tasks_destroy();
05129    
05130    if (!g_config_initialized)
05131       return 0;
05132    
05133    ast_cli_unregister_multiple(chan_misdn_clis, sizeof(chan_misdn_clis) / sizeof(struct ast_cli_entry));
05134    
05135    /* ast_unregister_application("misdn_crypt"); */
05136    ast_unregister_application("misdn_set_opt");
05137    ast_unregister_application("misdn_facility");
05138    ast_unregister_application("misdn_check_l2l1");
05139   
05140    ast_channel_unregister(&misdn_tech);
05141 
05142    free_robin_list();
05143    misdn_cfg_destroy();
05144    misdn_lib_destroy();
05145   
05146    free(misdn_out_calls);
05147    free(misdn_in_calls);
05148    free(misdn_debug_only);
05149    free(misdn_ports);
05150    free(misdn_debug);
05151    
05152    return 0;
05153 }
05154 
05155 static int load_module(void)
05156 {
05157    int i, port;
05158    int ntflags = 0, ntkc = 0;
05159    char ports[256] = "";
05160    char tempbuf[BUFFERSIZE + 1];
05161    char ntfile[BUFFERSIZE + 1];
05162    struct misdn_lib_iface iface = {
05163       .cb_event = cb_events,
05164       .cb_log = chan_misdn_log,
05165       .cb_jb_empty = chan_misdn_jb_empty,
05166    };
05167 
05168    max_ports = misdn_lib_maxports_get();
05169    
05170    if (max_ports <= 0) {
05171       ast_log(LOG_ERROR, "Unable to initialize mISDN\n");
05172       return AST_MODULE_LOAD_DECLINE;
05173    }
05174    
05175    if (misdn_cfg_init(max_ports)) {
05176       ast_log(LOG_ERROR, "Unable to initialize misdn_config.\n");
05177       return AST_MODULE_LOAD_DECLINE;
05178    }
05179    g_config_initialized = 1;
05180    
05181    misdn_debug = (int *) malloc(sizeof(int) * (max_ports + 1));
05182    if (!misdn_debug) {
05183       ast_log(LOG_ERROR, "Out of memory for misdn_debug\n");
05184       return AST_MODULE_LOAD_DECLINE;
05185    }
05186    misdn_ports = (int *) malloc(sizeof(int) * (max_ports + 1));
05187    if (!misdn_ports) {
05188       free(misdn_debug);
05189       ast_log(LOG_ERROR, "Out of memory for misdn_ports\n");
05190       return AST_MODULE_LOAD_DECLINE;
05191    }
05192    misdn_cfg_get(0, MISDN_GEN_DEBUG, &misdn_debug[0], sizeof(int));
05193    for (i = 1; i <= max_ports; i++) {
05194       misdn_debug[i] = misdn_debug[0];
05195       misdn_ports[i] = i;
05196    }
05197    *misdn_ports = 0;
05198    misdn_debug_only = (int *) calloc(max_ports + 1, sizeof(int));
05199    if (!misdn_debug_only) {
05200       free(misdn_ports);
05201       free(misdn_debug);
05202       ast_log(LOG_ERROR, "Out of memory for misdn_debug_only\n");
05203       return AST_MODULE_LOAD_DECLINE;
05204    }
05205 
05206    misdn_cfg_get(0, MISDN_GEN_TRACEFILE, tempbuf, BUFFERSIZE);
05207    if (!ast_strlen_zero(tempbuf))
05208       tracing = 1;
05209 
05210    misdn_in_calls = (int *) malloc(sizeof(int) * (max_ports + 1));
05211    if (!misdn_in_calls) {
05212       free(misdn_debug_only);
05213       free(misdn_ports);
05214       free(misdn_debug);
05215       ast_log(LOG_ERROR, "Out of memory for misdn_in_calls\n");
05216       return AST_MODULE_LOAD_DECLINE;
05217    }
05218    misdn_out_calls = (int *) malloc(sizeof(int) * (max_ports + 1));
05219    if (!misdn_out_calls) {
05220       free(misdn_in_calls);
05221       free(misdn_debug_only);
05222       free(misdn_ports);
05223       free(misdn_debug);
05224       ast_log(LOG_ERROR, "Out of memory for misdn_out_calls\n");
05225       return AST_MODULE_LOAD_DECLINE;
05226    }
05227 
05228    for (i = 1; i <= max_ports; i++) {
05229       misdn_in_calls[i] = 0;
05230       misdn_out_calls[i] = 0;
05231    }
05232 
05233    ast_mutex_init(&cl_te_lock);
05234    ast_mutex_init(&release_lock);
05235 
05236    misdn_cfg_update_ptp();
05237    misdn_cfg_get_ports_string(ports);
05238 
05239    if (!ast_strlen_zero(ports))
05240       chan_misdn_log(0, 0, "Got: %s from get_ports\n", ports);
05241    if (misdn_lib_init(ports, &iface, NULL))
05242       chan_misdn_log(0, 0, "No te ports initialized\n");
05243 
05244    misdn_cfg_get(0, MISDN_GEN_NTDEBUGFLAGS, &ntflags, sizeof(int));
05245    misdn_cfg_get(0, MISDN_GEN_NTDEBUGFILE, &ntfile, BUFFERSIZE);
05246    misdn_lib_nt_debug_init(ntflags, ntfile);
05247 
05248    misdn_cfg_get( 0, MISDN_GEN_NTKEEPCALLS, &ntkc, sizeof(int));
05249    misdn_lib_nt_keepcalls(ntkc);
05250 
05251    if (ast_channel_register(&misdn_tech)) {
05252       ast_log(LOG_ERROR, "Unable to register channel class %s\n", misdn_type);
05253       unload_module();
05254       return -1;
05255    }
05256   
05257    ast_cli_register_multiple(chan_misdn_clis, sizeof(chan_misdn_clis) / sizeof(struct ast_cli_entry));
05258 
05259    ast_register_application("misdn_set_opt", misdn_set_opt_exec, "misdn_set_opt",
05260       "misdn_set_opt(:<opt><optarg>:<opt><optarg>...):\n"
05261       "Sets mISDN opts. and optargs\n"
05262       "\n"
05263       "The available options are:\n"
05264       "    a - Have Asterisk detect DTMF tones on called channel\n"
05265       "    c - Make crypted outgoing call, optarg is keyindex\n"
05266       "    d - Send display text to called phone, text is the optarg\n"
05267       "    e - Perform echo cancellation on this channel,\n"
05268       "        takes taps as optarg (32,64,128,256)\n"
05269       "   e! - Disable echo cancellation on this channel\n"
05270       "    f - Enable fax detection\n"
05271       "    h - Make digital outgoing call\n"
05272       "   h1 - Make HDLC mode digital outgoing call\n"
05273       "    i - Ignore detected DTMF tones, don't signal them to Asterisk,\n"
05274       "        they will be transported inband.\n"
05275       "   jb - Set jitter buffer length, optarg is length\n"
05276       "   jt - Set jitter buffer upper threshold, optarg is threshold\n"
05277       "   jn - Disable jitter buffer\n"
05278       "    n - Disable mISDN DSP on channel.\n"
05279       "        Disables: echo cancel, DTMF detection, and volume control.\n"
05280       "    p - Caller ID presentation,\n"
05281       "        optarg is either 'allowed' or 'restricted'\n"
05282       "    s - Send Non-inband DTMF as inband\n"
05283       "   vr - Rx gain control, optarg is gain\n"
05284       "   vt - Tx gain control, optarg is gain\n"
05285       );
05286 
05287    
05288    ast_register_application("misdn_facility", misdn_facility_exec, "misdn_facility",
05289              "misdn_facility(<FACILITY_TYPE>|<ARG1>|..)\n"
05290              "Sends the Facility Message FACILITY_TYPE with \n"
05291              "the given Arguments to the current ISDN Channel\n"
05292              "Supported Facilities are:\n"
05293              "\n"
05294              "type=calldeflect args=Nr where to deflect\n"
05295       );
05296 
05297 
05298    ast_register_application("misdn_check_l2l1", misdn_check_l2l1, "misdn_check_l2l1",
05299              "misdn_check_l2l1(<port>||g:<groupname>,timeout)"
05300              "Checks if the L2 and L1 are up on either the given <port> or\n"
05301              "on the ports in the group with <groupname>\n"
05302              "If the L1/L2 are down, check_l2l1 gets up the L1/L2 and waits\n"
05303              "for <timeout> seconds that this happens. Otherwise, nothing happens\n"
05304              "\n"
05305              "This application, ensures the L1/L2 state of the Ports in a group\n"
05306              "it is intended to make the pmp_l1_check option redundant and to\n"
05307              "fix a buggy switch config from your provider\n"
05308              "\n"
05309              "a sample dialplan would look like:\n\n"
05310              "exten => _X.,1,misdn_check_l2l1(g:out|2)\n"
05311              "exten => _X.,n,dial(mISDN/g:out/${EXTEN})\n"
05312              "\n"
05313       );
05314 
05315 
05316    misdn_cfg_get(0, MISDN_GEN_TRACEFILE, global_tracefile, BUFFERSIZE);
05317 
05318    /* start the l1 watchers */
05319    
05320    for (port = misdn_cfg_get_next_port(0); port >= 0; port = misdn_cfg_get_next_port(port)) {
05321       int l1timeout;
05322       misdn_cfg_get(port, MISDN_CFG_L1_TIMEOUT, &l1timeout, sizeof(l1timeout));
05323       if (l1timeout) {
05324          chan_misdn_log(4, 0, "Adding L1watcher task: port:%d timeout:%ds\n", port, l1timeout);
05325          misdn_tasks_add(l1timeout * 1000, misdn_l1_task, &misdn_ports[port]);  
05326       }
05327    }
05328 
05329    chan_misdn_log(0, 0, "-- mISDN Channel Driver Registered --\n");
05330 
05331    return 0;
05332 }
05333 
05334 
05335 
05336 static int reload(void)
05337 {
05338    reload_config();
05339 
05340    return 0;
05341 }
05342 
05343 /*** SOME APPS ;)***/
05344 
05345 static int misdn_facility_exec(struct ast_channel *chan, void *data)
05346 {
05347    struct chan_list *ch = MISDN_ASTERISK_TECH_PVT(chan);
05348    char *tok, *tokb;
05349 
05350    chan_misdn_log(0, 0, "TYPE: %s\n", chan->tech->type);
05351    
05352    if (strcasecmp(chan->tech->type, "mISDN")) {
05353       ast_log(LOG_WARNING, "misdn_facility makes only sense with chan_misdn channels!\n");
05354       return -1;
05355    }
05356    
05357    if (ast_strlen_zero((char *)data)) {
05358       ast_log(LOG_WARNING, "misdn_facility Requires arguments\n");
05359       return -1;
05360    }
05361 
05362    tok = strtok_r((char*) data, "|", &tokb) ;
05363 
05364    if (!tok) {
05365       ast_log(LOG_WARNING, "misdn_facility Requires arguments\n");
05366       return -1;
05367    }
05368 
05369    if (!strcasecmp(tok, "calldeflect")) {
05370       tok = strtok_r(NULL, "|", &tokb) ;
05371       
05372       if (!tok) {
05373          ast_log(LOG_WARNING, "Facility: Call Defl Requires arguments\n");
05374       }
05375 
05376       if (strlen(tok) >= sizeof(ch->bc->fac_out.u.CDeflection.DeflectedToNumber)) {
05377          ast_log(LOG_WARNING, "Facility: Number argument too long (up to 15 digits are allowed). Ignoring.\n");
05378          return 0; 
05379       }
05380       ch->bc->fac_out.Function = Fac_CD;
05381       ast_copy_string((char *)ch->bc->fac_out.u.CDeflection.DeflectedToNumber, tok, sizeof(ch->bc->fac_out.u.CDeflection.DeflectedToNumber));
05382       misdn_lib_send_event(ch->bc, EVENT_FACILITY);
05383    } else {
05384       chan_misdn_log(1, ch->bc->port, "Unknown Facility: %s\n", tok);
05385    }
05386 
05387    return 0;
05388 }
05389 
05390 static int misdn_check_l2l1(struct ast_channel *chan, void *data)
05391 {
05392    char group[BUFFERSIZE + 1];
05393    char *port_str;
05394    int port = 0;
05395    int timeout;
05396    int dowait = 0;
05397    int port_up;
05398 
05399    AST_DECLARE_APP_ARGS(args,
05400          AST_APP_ARG(grouppar);
05401          AST_APP_ARG(timeout);
05402    );
05403 
05404    if (ast_strlen_zero((char *)data)) {
05405       ast_log(LOG_WARNING, "misdn_check_l2l1 Requires arguments\n");
05406       return -1;
05407    }
05408 
05409    AST_STANDARD_APP_ARGS(args, data);
05410 
05411    if (args.argc != 2) {
05412       ast_log(LOG_WARNING, "Wrong argument count\n");
05413       return 0;
05414    }
05415 
05416    /*ast_log(LOG_NOTICE, "Arguments: group/port '%s' timeout '%s'\n", args.grouppar, args.timeout);*/
05417    timeout = atoi(args.timeout);
05418    port_str = args.grouppar;
05419 
05420    if (port_str[0] == 'g' && port_str[1] == ':' ) {
05421       /* We make a group call lets checkout which ports are in my group */
05422       port_str += 2;
05423       ast_copy_string(group, port_str, sizeof(group));
05424       chan_misdn_log(2, 0, "Checking Ports in group: %s\n", group);
05425 
05426       for ( port = misdn_cfg_get_next_port(port); 
05427          port > 0;
05428          port = misdn_cfg_get_next_port(port)) {
05429          char cfg_group[BUFFERSIZE + 1];
05430 
05431          chan_misdn_log(2, 0, "trying port %d\n", port);
05432 
05433          misdn_cfg_get(port, MISDN_CFG_GROUPNAME, cfg_group, BUFFERSIZE);
05434 
05435          if (!strcasecmp(cfg_group, group)) {
05436             port_up = misdn_lib_port_up(port, 1);
05437 
05438             if (!port_up) {
05439                chan_misdn_log(2, 0, " --> port '%d'\n", port);
05440                misdn_lib_get_port_up(port);
05441                dowait = 1;
05442             }
05443          }
05444       }
05445 
05446    } else {
05447       port = atoi(port_str);
05448       chan_misdn_log(2, 0, "Checking Port: %d\n",port);
05449       port_up = misdn_lib_port_up(port, 1);
05450       if (!port_up) {
05451          misdn_lib_get_port_up(port);
05452          dowait = 1;
05453       }
05454    }
05455 
05456    if (dowait) {
05457       chan_misdn_log(2, 0, "Waiting for '%d' seconds\n", timeout);
05458       sleep(timeout);
05459    }
05460 
05461    return 0;
05462 }
05463 
05464 static int misdn_set_opt_exec(struct ast_channel *chan, void *data)
05465 {
05466    struct chan_list *ch = MISDN_ASTERISK_TECH_PVT(chan);
05467    char *tok, *tokb;
05468    int  keyidx = 0;
05469    int rxgain = 0;
05470    int txgain = 0;
05471    int change_jitter = 0;
05472 
05473    if (strcasecmp(chan->tech->type, "mISDN")) {
05474       ast_log(LOG_WARNING, "misdn_set_opt makes only sense with chan_misdn channels!\n");
05475       return -1;
05476    }
05477    
05478    if (ast_strlen_zero((char *)data)) {
05479       ast_log(LOG_WARNING, "misdn_set_opt Requires arguments\n");
05480       return -1;
05481    }
05482 
05483    for (tok = strtok_r((char*) data, ":", &tokb);
05484         tok;
05485         tok = strtok_r(NULL, ":", &tokb) ) {
05486       int neglect = 0;
05487 
05488       if (tok[0] == '!' ) {
05489          neglect = 1;
05490          tok++;
05491       }
05492       
05493       switch(tok[0]) {
05494          
05495       case 'd' :
05496          ast_copy_string(ch->bc->display, ++tok, sizeof(ch->bc->display));
05497          chan_misdn_log(1, ch->bc->port, "SETOPT: Display:%s\n", ch->bc->display);
05498          break;
05499          
05500       case 'n':
05501          chan_misdn_log(1, ch->bc->port, "SETOPT: No DSP\n");
05502          ch->bc->nodsp = 1;
05503          break;
05504 
05505       case 'j':
05506          chan_misdn_log(1, ch->bc->port, "SETOPT: jitter\n");
05507          tok++;
05508          change_jitter = 1;
05509 
05510          switch ( tok[0] ) {
05511          case 'b':
05512             ch->jb_len = atoi(++tok);
05513             chan_misdn_log(1, ch->bc->port, " --> buffer_len:%d\n", ch->jb_len);
05514             break;
05515          case 't' :
05516             ch->jb_upper_threshold = atoi(++tok);
05517             chan_misdn_log(1, ch->bc->port, " --> upper_threshold:%d\n", ch->jb_upper_threshold);
05518             break;
05519          case 'n':
05520             ch->bc->nojitter = 1;
05521             chan_misdn_log(1, ch->bc->port, " --> nojitter\n");
05522             break;
05523          default:
05524             ch->jb_len = 4000;
05525             ch->jb_upper_threshold = 0;
05526             chan_misdn_log(1, ch->bc->port, " --> buffer_len:%d (default)\n", ch->jb_len);
05527             chan_misdn_log(1, ch->bc->port, " --> upper_threshold:%d (default)\n", ch->jb_upper_threshold);
05528          }
05529          break;
05530       case 'v':
05531          tok++;
05532 
05533          switch (tok[0]) {
05534          case 'r' :
05535             rxgain = atoi(++tok);
05536             if (rxgain < -8)
05537                rxgain = -8;
05538             if (rxgain > 8)
05539                rxgain = 8;
05540             ch->bc->rxgain = rxgain;
05541             chan_misdn_log(1, ch->bc->port, "SETOPT: Volume:%d\n", rxgain);
05542             break;
05543          case 't':
05544             txgain = atoi(++tok);
05545             if (txgain < -8)
05546                txgain = -8;
05547             if (txgain > 8)
05548                txgain = 8;
05549             ch->bc->txgain = txgain;
05550             chan_misdn_log(1, ch->bc->port, "SETOPT: Volume:%d\n", txgain);
05551             break;
05552          }
05553          break;
05554       
05555       case 'c':
05556          keyidx = atoi(++tok);
05557          {
05558             char keys[4096];
05559             char *key = NULL, *tmp = keys;
05560             int i;
05561             misdn_cfg_get(0, MISDN_GEN_CRYPT_KEYS, keys, sizeof(keys));
05562 
05563             for (i = 0; i < keyidx; i++) {
05564                key = strsep(&tmp, ",");
05565             }
05566 
05567             if (key) {
05568                ast_copy_string(ch->bc->crypt_key, key, sizeof(ch->bc->crypt_key));
05569             }
05570 
05571             chan_misdn_log(0, ch->bc->port, "SETOPT: crypt with key:%s\n", ch->bc->crypt_key);
05572             break;
05573          }
05574       case 'e':
05575          chan_misdn_log(1, ch->bc->port, "SETOPT: EchoCancel\n");
05576          
05577          if (neglect) {
05578             chan_misdn_log(1, ch->bc->port, " --> disabled\n");
05579 #ifdef MISDN_1_2
05580             *ch->bc->pipeline = 0;
05581 #else
05582             ch->bc->ec_enable = 0;
05583 #endif
05584          } else {
05585 #ifdef MISDN_1_2
05586             update_pipeline_config(ch->bc);
05587 #else
05588             ch->bc->ec_enable = 1;
05589             ch->bc->orig = ch->originator;
05590             tok++;
05591             if (*tok) {
05592                ch->bc->ec_deftaps = atoi(tok);
05593             }
05594 #endif
05595          }
05596          
05597          break;
05598       case 'h':
05599          chan_misdn_log(1, ch->bc->port, "SETOPT: Digital\n");
05600          
05601          if (strlen(tok) > 1 && tok[1] == '1') {
05602             chan_misdn_log(1, ch->bc->port, "SETOPT: HDLC \n");
05603             if (!ch->bc->hdlc) {
05604                ch->bc->hdlc = 1;
05605             }
05606          }
05607          ch->bc->capability = INFO_CAPABILITY_DIGITAL_UNRESTRICTED;
05608          break;
05609             
05610       case 's':
05611          chan_misdn_log(1, ch->bc->port, "SETOPT: Send DTMF\n");
05612          ch->bc->send_dtmf = 1;
05613          break;
05614          
05615       case 'f':
05616          chan_misdn_log(1, ch->bc->port, "SETOPT: Faxdetect\n");
05617          ch->faxdetect = 1;
05618          misdn_cfg_get(ch->bc->port, MISDN_CFG_FAXDETECT_TIMEOUT, &ch->faxdetect_timeout, sizeof(ch->faxdetect_timeout));
05619          break;
05620 
05621       case 'a':
05622          chan_misdn_log(1, ch->bc->port, "SETOPT: AST_DSP (for DTMF)\n");
05623          ch->ast_dsp = 1;
05624          break;
05625 
05626       case 'p':
05627          chan_misdn_log(1, ch->bc->port, "SETOPT: callerpres: %s\n", &tok[1]);
05628          /* CRICH: callingpres!!! */
05629          if (strstr(tok,"allowed")) {
05630             ch->bc->pres = 0;
05631          } else if (strstr(tok, "restricted")) {
05632             ch->bc->pres = 1;
05633          } else if (strstr(tok, "not_screened")) {
05634             chan_misdn_log(0, ch->bc->port, "SETOPT: callerpres: not_screened is deprecated\n");
05635             ch->bc->pres = 1;
05636          }
05637          break;
05638       case 'i' :
05639          chan_misdn_log(1, ch->bc->port, "Ignoring dtmf tones, just use them inband\n");
05640          ch->ignore_dtmf=1;
05641          break;
05642       default:
05643          break;
05644       }
05645    }
05646 
05647    if (change_jitter)
05648       config_jitterbuffer(ch);
05649 
05650    if (ch->faxdetect || ch->ast_dsp) {
05651       if (!ch->dsp)
05652          ch->dsp = ast_dsp_new();
05653       if (ch->dsp)
05654          ast_dsp_set_features(ch->dsp, DSP_FEATURE_DTMF_DETECT| DSP_FEATURE_FAX_DETECT);
05655    }
05656 
05657    if (ch->ast_dsp) {
05658       chan_misdn_log(1, ch->bc->port, "SETOPT: with AST_DSP we deactivate mISDN_dsp\n");
05659       ch->bc->nodsp = 1;
05660    }
05661    
05662    return 0;
05663 }
05664 
05665 
05666 int chan_misdn_jb_empty ( struct misdn_bchannel *bc, char *buf, int len) 
05667 {
05668    struct chan_list *ch = find_chan_by_bc(cl_te, bc);
05669    
05670    if (ch && ch->jb) {
05671       return misdn_jb_empty(ch->jb, buf, len);
05672    }
05673    
05674    return -1;
05675 }
05676 
05677 
05678 
05679 /*******************************************************/
05680 /***************** JITTERBUFFER ************************/
05681 /*******************************************************/
05682 
05683 
05684 /* allocates the jb-structure and initialize the elements*/
05685 struct misdn_jb *misdn_jb_init(int size, int upper_threshold)
05686 {
05687    int i;
05688    struct misdn_jb *jb;
05689 
05690    jb = malloc(sizeof(struct misdn_jb));
05691    if (!jb) {
05692        chan_misdn_log(-1, 0, "No free Mem for jb\n");
05693        return NULL;
05694    }
05695    jb->size = size;
05696    jb->upper_threshold = upper_threshold;
05697    jb->wp = 0;
05698    jb->rp = 0;
05699    jb->state_full = 0;
05700    jb->state_empty = 0;
05701    jb->bytes_wrote = 0;
05702    jb->samples = malloc(size * sizeof(char));
05703    if (!jb->samples) {
05704       free(jb);
05705       chan_misdn_log(-1, 0, "No free Mem for jb->samples\n");
05706       return NULL;
05707    }
05708 
05709    jb->ok = malloc(size * sizeof(char));
05710    if (!jb->ok) {
05711       free(jb->samples);
05712       free(jb);
05713       chan_misdn_log(-1, 0, "No free Mem for jb->ok\n");
05714       return NULL;
05715    }
05716 
05717    for (i = 0; i < size; i++)
05718       jb->ok[i] = 0;
05719 
05720    ast_mutex_init(&jb->mutexjb);
05721 
05722    return jb;
05723 }
05724 
05725 /* frees the data and destroys the given jitterbuffer struct */
05726 void misdn_jb_destroy(struct misdn_jb *jb)
05727 {
05728    ast_mutex_destroy(&jb->mutexjb);
05729    
05730    free(jb->ok);
05731    free(jb->samples);
05732    free(jb);
05733 }
05734 
05735 /* fills the jitterbuffer with len data returns < 0 if there was an
05736    error (buffer overflow). */
05737 int misdn_jb_fill(struct misdn_jb *jb, const char *data, int len)
05738 {
05739    int i, j, rp, wp;
05740 
05741    if (!jb || ! data)
05742       return 0;
05743 
05744    ast_mutex_lock(&jb->mutexjb);
05745    
05746    wp = jb->wp;
05747    rp = jb->rp;
05748    
05749    for (i = 0; i < len; i++) {
05750       jb->samples[wp] = data[i];
05751       jb->ok[wp] = 1;
05752       wp = (wp != jb->size - 1) ? wp + 1 : 0;
05753 
05754       if (wp == jb->rp)
05755          jb->state_full = 1;
05756    }
05757 
05758    if (wp >= rp)
05759       jb->state_buffer = wp - rp;
05760    else
05761       jb->state_buffer = jb->size - rp + wp;
05762    chan_misdn_log(9, 0, "misdn_jb_fill: written:%d | Buffer status:%d p:%p\n", len, jb->state_buffer, jb);
05763 
05764    if (jb->state_full) {
05765       jb->wp = wp;
05766 
05767       rp = wp;
05768       for (j = 0; j < jb->upper_threshold; j++)
05769          rp = (rp != 0) ? rp - 1 : jb->size - 1;
05770       jb->rp = rp;
05771       jb->state_full = 0;
05772       jb->state_empty = 1;
05773 
05774       ast_mutex_unlock(&jb->mutexjb);
05775 
05776       return -1;
05777    }
05778 
05779    if (!jb->state_empty) {
05780       jb->bytes_wrote += len;
05781       if (jb->bytes_wrote >= jb->upper_threshold) {
05782          jb->state_empty = 1;
05783          jb->bytes_wrote = 0;
05784       }
05785    }
05786    jb->wp = wp;
05787 
05788    ast_mutex_unlock(&jb->mutexjb);
05789    
05790    return 0;
05791 }
05792 
05793 /* gets len bytes out of the jitterbuffer if available, else only the
05794 available data is returned and the return value indicates the number
05795 of data. */
05796 int misdn_jb_empty(struct misdn_jb *jb, char *data, int len)
05797 {
05798    int i, wp, rp, read = 0;
05799 
05800    ast_mutex_lock(&jb->mutexjb);
05801 
05802    rp = jb->rp;
05803    wp = jb->wp;
05804 
05805    if (jb->state_empty) {  
05806       for (i = 0; i < len; i++) {
05807          if (wp == rp) {
05808             jb->rp = rp;
05809             jb->state_empty = 0;
05810 
05811             ast_mutex_unlock(&jb->mutexjb);
05812 
05813             return read;
05814          } else {
05815             if (jb->ok[rp] == 1) {
05816                data[i] = jb->samples[rp];
05817                jb->ok[rp] = 0;
05818                rp = (rp != jb->size - 1) ? rp + 1 : 0;
05819                read += 1;
05820             }
05821          }
05822       }
05823 
05824       if (wp >= rp)
05825          jb->state_buffer = wp - rp;
05826       else
05827          jb->state_buffer = jb->size - rp + wp;
05828       chan_misdn_log(9, 0, "misdn_jb_empty: read:%d | Buffer status:%d p:%p\n", len, jb->state_buffer, jb);
05829 
05830       jb->rp = rp;
05831    } else
05832       chan_misdn_log(9, 0, "misdn_jb_empty: Wait...requested:%d p:%p\n", len, jb);
05833 
05834    ast_mutex_unlock(&jb->mutexjb);
05835 
05836    return read;
05837 }
05838 
05839 
05840 
05841 
05842 /*******************************************************/
05843 /*************** JITTERBUFFER  END *********************/
05844 /*******************************************************/
05845 
05846 
05847 
05848 
05849 static void chan_misdn_log(int level, int port, char *tmpl, ...)
05850 {
05851    va_list ap;
05852    char buf[1024];
05853    char port_buf[8];
05854 
05855    if (! ((0 <= port) && (port <= max_ports))) {
05856       ast_log(LOG_WARNING, "cb_log called with out-of-range port number! (%d)\n", port);
05857       port = 0;
05858       level = -1;
05859    }
05860 
05861    snprintf(port_buf, sizeof(port_buf), "P[%2d] ", port);
05862 
05863    va_start(ap, tmpl);
05864    vsnprintf(buf, sizeof(buf), tmpl, ap);
05865    va_end(ap);
05866 
05867    if (level == -1)
05868       ast_log(LOG_WARNING, "%s", buf);
05869 
05870    else if (misdn_debug_only[port] ? 
05871          (level == 1 && misdn_debug[port]) || (level == misdn_debug[port]) 
05872        : level <= misdn_debug[port]) {
05873       
05874       ast_console_puts(port_buf);
05875       ast_console_puts(buf);
05876    }
05877    
05878    if ((level <= misdn_debug[0]) && !ast_strlen_zero(global_tracefile) ) {
05879       time_t tm = time(NULL);
05880       char *tmp = ctime(&tm), *p;
05881 
05882       FILE *fp = fopen(global_tracefile, "a+");
05883 
05884       p = strchr(tmp, '\n');
05885       if (p)
05886          *p = ':';
05887       
05888       if (!fp) {
05889          ast_console_puts("Error opening Tracefile: [ ");
05890          ast_console_puts(global_tracefile);
05891          ast_console_puts(" ] ");
05892          
05893          ast_console_puts(strerror(errno));
05894          ast_console_puts("\n");
05895          return ;
05896       }
05897       
05898       fputs(tmp, fp);
05899       fputs(" ", fp);
05900       fputs(port_buf, fp);
05901       fputs(" ", fp);
05902       fputs(buf, fp);
05903 
05904       fclose(fp);
05905    }
05906 }
05907 
05908 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Channel driver for mISDN Support (BRI/PRI)",
05909    .load = load_module,
05910    .unload = unload_module,
05911    .reload = reload,
05912 );

Generated on Thu Oct 11 06:42:04 2012 for Asterisk - the Open Source PBX by  doxygen 1.5.6