Sat Aug 6 00:39:25 2011

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

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