Sun May 20 06:33:54 2012

Asterisk developer's documentation


isdn_msg_parser.c

Go to the documentation of this file.
00001 /*
00002  * Chan_Misdn -- Channel Driver for Asterisk
00003  *
00004  * Interface to mISDN
00005  *
00006  * Copyright (C) 2004, Christian Richter
00007  *
00008  * Christian Richter <crich@beronet.com>
00009  *
00010  * This program is free software, distributed under the terms of
00011  * the GNU General Public License
00012  */
00013 
00014 /*! \file
00015  * \brief Interface to mISDN - message parser
00016  * \author Christian Richter <crich@beronet.com>
00017  */
00018 
00019 
00020 
00021 #include "isdn_lib_intern.h"
00022 
00023 
00024 #include "isdn_lib.h"
00025 
00026 #include "ie.c"
00027 
00028 /*!
00029  * \internal
00030  * \brief Build the name, number, name/number display message string
00031  *
00032  * \param display Display buffer to fill in
00033  * \param display_length Length of the display buffer to fill in
00034  * \param display_format Display format enumeration
00035  * \param name Name string to use
00036  * \param number Number string to use
00037  *
00038  * \return Nothing
00039  */
00040 static void build_display_str(char *display, size_t display_length, int display_format, const char *name, const char *number)
00041 {
00042    display[0] = 0;
00043    switch (display_format) {
00044    default:
00045    case 0:     /* none */
00046       break;
00047 
00048    case 1:     /* name */
00049       snprintf(display, display_length, "%s", name);
00050       break;
00051 
00052    case 2:     /* number */
00053       snprintf(display, display_length, "%s", number);
00054       break;
00055 
00056    case 3:     /* both */
00057       if (name[0] || number[0]) {
00058          snprintf(display, display_length, "\"%s\" <%s>", name, number);
00059       }
00060       break;
00061    }
00062 }
00063 
00064 /*!
00065  * \internal
00066  * \brief Encode the Facility IE and put it into the message structure.
00067  *
00068  * \param ntmode Where the encoded facility was put when in NT mode.
00069  * \param msg General message structure
00070  * \param fac Data to encode into the facility ie.
00071  * \param nt TRUE if in NT mode.
00072  *
00073  * \return Nothing
00074  */
00075 static void enc_ie_facility(unsigned char **ntmode, msg_t *msg, struct FacParm *fac, int nt)
00076 {
00077    int len;
00078    Q931_info_t *qi;
00079    unsigned char *p;
00080    unsigned char buf[256];
00081 
00082    len = encodeFac(buf, fac);
00083    if (len <= 0) {
00084       /*
00085        * mISDN does not know how to build the requested facility structure
00086        * Clear facility information
00087        */
00088       fac->Function = Fac_None;
00089       return;
00090    }
00091 
00092    p = msg_put(msg, len);
00093    if (nt) {
00094       *ntmode = p + 1;
00095    } else {
00096       qi = (Q931_info_t *) (msg->data + mISDN_HEADER_LEN);
00097       qi->QI_ELEMENT(facility) = p - (unsigned char *) qi - sizeof(Q931_info_t);
00098    }
00099 
00100    memcpy(p, buf, len);
00101 
00102    /* Clear facility information */
00103    fac->Function = Fac_None;
00104 }
00105 
00106 /*!
00107  * \internal
00108  * \brief Decode the Facility IE.
00109  *
00110  * \param p Encoded facility ie data to decode. (NT mode)
00111  * \param qi Encoded facility ie data to decode. (TE mode)
00112  * \param fac Where to put the decoded facility ie data if it is available.
00113  * \param nt TRUE if in NT mode.
00114  * \param bc Associated B channel
00115  *
00116  * \return Nothing
00117  */
00118 static void dec_ie_facility(unsigned char *p, Q931_info_t *qi, struct FacParm *fac, int nt, struct misdn_bchannel *bc)
00119 {
00120    fac->Function = Fac_None;
00121 
00122    if (!nt) {
00123       p = NULL;
00124       if (qi->QI_ELEMENT(facility)) {
00125          p = (unsigned char *) qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(facility) + 1;
00126       }
00127    }
00128    if (!p) {
00129       return;
00130    }
00131 
00132    if (decodeFac(p, fac)) {
00133       cb_log(3, bc->port, "Decoding facility ie failed! Unrecognized facility message?\n");
00134    }
00135 }
00136 
00137 
00138 
00139 static void set_channel(struct misdn_bchannel *bc, int channel)
00140 {
00141 
00142    cb_log(3,bc->port,"set_channel: bc->channel:%d channel:%d\n", bc->channel, channel);
00143 
00144 
00145    if (channel==0xff) {
00146       /* any channel */
00147       channel=-1;
00148    }
00149 
00150    /*  ALERT: is that everytime true ?  */
00151    if (channel > 0 && bc->nt ) {
00152 
00153       if (bc->channel && ( bc->channel != 0xff) ) {
00154          cb_log(0,bc->port,"We already have a channel (%d)\n", bc->channel);
00155       } else {
00156          bc->channel = channel;
00157          cb_event(EVENT_NEW_CHANNEL,bc,NULL);
00158       }
00159    }
00160 
00161    if (channel > 0 && !bc->nt ) {
00162       bc->channel = channel;
00163       cb_event(EVENT_NEW_CHANNEL,bc,NULL);
00164    }
00165 }
00166 
00167 static void parse_proceeding (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
00168 {
00169    int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
00170    CALL_PROCEEDING_t *proceeding = (CALL_PROCEEDING_t *) (msg->data + HEADER_LEN);
00171    //struct misdn_stack *stack=get_stack_by_bc(bc);
00172 
00173    {
00174       int  exclusive, channel;
00175       dec_ie_channel_id(proceeding->CHANNEL_ID, (Q931_info_t *)proceeding, &exclusive, &channel, nt,bc);
00176 
00177       set_channel(bc,channel);
00178 
00179    }
00180 
00181    dec_ie_progress(proceeding->PROGRESS, (Q931_info_t *)proceeding, &bc->progress_coding, &bc->progress_location, &bc->progress_indicator, nt, bc);
00182 
00183    dec_ie_facility(proceeding->FACILITY, (Q931_info_t *) proceeding, &bc->fac_in, nt, bc);
00184 
00185    /* dec_ie_redir_dn */
00186 
00187 #ifdef DEBUG
00188    printf("Parsing PROCEEDING Msg\n");
00189 #endif
00190 }
00191 static msg_t *build_proceeding (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
00192 {
00193    int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
00194    CALL_PROCEEDING_t *proceeding;
00195    msg_t *msg =(msg_t*)create_l3msg(CC_PROCEEDING | REQUEST, MT_CALL_PROCEEDING,  bc?bc->l3_id:-1, sizeof(CALL_PROCEEDING_t) ,nt);
00196 
00197    proceeding=(CALL_PROCEEDING_t*)((msg->data+HEADER_LEN));
00198 
00199    enc_ie_channel_id(&proceeding->CHANNEL_ID, msg, 1,bc->channel, nt,bc);
00200 
00201    if (nt)
00202       enc_ie_progress(&proceeding->PROGRESS, msg, 0, nt?1:5, 8, nt,bc);
00203 
00204    if (bc->fac_out.Function != Fac_None) {
00205       enc_ie_facility(&proceeding->FACILITY, msg, &bc->fac_out, nt);
00206    }
00207 
00208    /* enc_ie_redir_dn */
00209 
00210 #ifdef DEBUG
00211    printf("Building PROCEEDING Msg\n");
00212 #endif
00213    return msg;
00214 }
00215 
00216 static void parse_alerting (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
00217 {
00218    int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
00219    ALERTING_t *alerting = (ALERTING_t *) (msg->data + HEADER_LEN);
00220    //Q931_info_t *qi=(Q931_info_t*)(msg->data+HEADER_LEN);
00221 
00222    dec_ie_facility(alerting->FACILITY, (Q931_info_t *) alerting, &bc->fac_in, nt, bc);
00223 
00224    /* dec_ie_redir_dn */
00225 
00226    dec_ie_progress(alerting->PROGRESS, (Q931_info_t *)alerting, &bc->progress_coding, &bc->progress_location, &bc->progress_indicator, nt, bc);
00227 
00228 #ifdef DEBUG
00229    printf("Parsing ALERTING Msg\n");
00230 #endif
00231 
00232 
00233 }
00234 
00235 static msg_t *build_alerting (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
00236 {
00237    int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
00238    ALERTING_t *alerting;
00239    msg_t *msg =(msg_t*)create_l3msg(CC_ALERTING | REQUEST, MT_ALERTING,  bc?bc->l3_id:-1, sizeof(ALERTING_t) ,nt);
00240 
00241    alerting=(ALERTING_t*)((msg->data+HEADER_LEN));
00242 
00243    enc_ie_channel_id(&alerting->CHANNEL_ID, msg, 1,bc->channel, nt,bc);
00244 
00245    if (nt)
00246       enc_ie_progress(&alerting->PROGRESS, msg, 0, nt?1:5, 8, nt,bc);
00247 
00248    if (bc->fac_out.Function != Fac_None) {
00249       enc_ie_facility(&alerting->FACILITY, msg, &bc->fac_out, nt);
00250    }
00251 
00252    /* enc_ie_redir_dn */
00253 
00254 #ifdef DEBUG
00255    printf("Building ALERTING Msg\n");
00256 #endif
00257    return msg;
00258 }
00259 
00260 
00261 static void parse_progress (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
00262 {
00263    int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
00264    PROGRESS_t *progress = (PROGRESS_t *) (msg->data + HEADER_LEN);
00265    //Q931_info_t *qi=(Q931_info_t*)(msg->data+HEADER_LEN);
00266 
00267    dec_ie_progress(progress->PROGRESS, (Q931_info_t *)progress, &bc->progress_coding, &bc->progress_location, &bc->progress_indicator, nt, bc);
00268 
00269    dec_ie_facility(progress->FACILITY, (Q931_info_t *) progress, &bc->fac_in, nt, bc);
00270 
00271 #ifdef DEBUG
00272    printf("Parsing PROGRESS Msg\n");
00273 #endif
00274 }
00275 
00276 static msg_t *build_progress (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
00277 {
00278    int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
00279    PROGRESS_t *progress;
00280    msg_t *msg =(msg_t*)create_l3msg(CC_PROGRESS | REQUEST, MT_PROGRESS,  bc?bc->l3_id:-1, sizeof(PROGRESS_t) ,nt);
00281 
00282    progress=(PROGRESS_t*)((msg->data+HEADER_LEN));
00283 
00284    if (bc->fac_out.Function != Fac_None) {
00285       enc_ie_facility(&progress->FACILITY, msg, &bc->fac_out, nt);
00286    }
00287 
00288 #ifdef DEBUG
00289    printf("Building PROGRESS Msg\n");
00290 #endif
00291    return msg;
00292 }
00293 
00294 #if defined(AST_MISDN_ENHANCEMENTS)
00295 /*!
00296  * \internal
00297  * \brief Extract the SETUP message's BC, HLC, and LLC encoded ie contents.
00298  *
00299  * \param setup Indexed setup message contents
00300  * \param nt TRUE if in NT mode.
00301  * \param bc Associated B channel
00302  *
00303  * \return Nothing
00304  */
00305 static void extract_setup_Bc_Hlc_Llc(SETUP_t *setup, int nt, struct misdn_bchannel *bc)
00306 {
00307    __u8 *p;
00308    Q931_info_t *qi;
00309 
00310    qi = (Q931_info_t *) setup;
00311 
00312    /* Extract Bearer Capability */
00313    if (nt) {
00314       p = (__u8 *) setup->BEARER;
00315    } else {
00316       if (qi->QI_ELEMENT(bearer_capability)) {
00317          p = (__u8 *) qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(bearer_capability) + 1;
00318       } else {
00319          p = NULL;
00320       }
00321    }
00322    if (!p || *p == 0 || sizeof(bc->setup_bc_hlc_llc.Bc.Contents) < *p) {
00323       bc->setup_bc_hlc_llc.Bc.Length = 0;
00324    } else {
00325       bc->setup_bc_hlc_llc.Bc.Length = *p;
00326       memcpy(bc->setup_bc_hlc_llc.Bc.Contents, p + 1, *p);
00327    }
00328 
00329    /* Extract Low Layer Compatibility */
00330    if (nt) {
00331       p = (__u8 *) setup->LLC;
00332    } else {
00333       if (qi->QI_ELEMENT(llc)) {
00334          p = (__u8 *) qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(llc) + 1;
00335       } else {
00336          p = NULL;
00337       }
00338    }
00339    if (!p || *p == 0 || sizeof(bc->setup_bc_hlc_llc.Llc.Contents) < *p) {
00340       bc->setup_bc_hlc_llc.Llc.Length = 0;
00341    } else {
00342       bc->setup_bc_hlc_llc.Llc.Length = *p;
00343       memcpy(bc->setup_bc_hlc_llc.Llc.Contents, p + 1, *p);
00344    }
00345 
00346    /* Extract High Layer Compatibility */
00347    if (nt) {
00348       p = (__u8 *) setup->HLC;
00349    } else {
00350       if (qi->QI_ELEMENT(hlc)) {
00351          p = (__u8 *) qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(hlc) + 1;
00352       } else {
00353          p = NULL;
00354       }
00355    }
00356    if (!p || *p == 0 || sizeof(bc->setup_bc_hlc_llc.Hlc.Contents) < *p) {
00357       bc->setup_bc_hlc_llc.Hlc.Length = 0;
00358    } else {
00359       bc->setup_bc_hlc_llc.Hlc.Length = *p;
00360       memcpy(bc->setup_bc_hlc_llc.Hlc.Contents, p + 1, *p);
00361    }
00362 }
00363 #endif   /* defined(AST_MISDN_ENHANCEMENTS) */
00364 
00365 static void parse_setup (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
00366 {
00367    int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
00368    SETUP_t *setup = (SETUP_t *) (msg->data + HEADER_LEN);
00369    Q931_info_t *qi = (Q931_info_t *) (msg->data + HEADER_LEN);
00370    int type;
00371    int plan;
00372    int present;
00373    int screen;
00374    int reason;
00375 
00376 #ifdef DEBUG
00377    printf("Parsing SETUP Msg\n");
00378 #endif
00379 
00380    dec_ie_calling_pn(setup->CALLING_PN, qi, &type, &plan, &present, &screen, bc->caller.number, sizeof(bc->caller.number), nt, bc);
00381    bc->caller.number_type = type;
00382    bc->caller.number_plan = plan;
00383    switch (present) {
00384    default:
00385    case 0:
00386       bc->caller.presentation = 0;  /* presentation allowed */
00387       break;
00388    case 1:
00389       bc->caller.presentation = 1;  /* presentation restricted */
00390       break;
00391    case 2:
00392       bc->caller.presentation = 2;  /* Number not available */
00393       break;
00394    }
00395    if (0 <= screen) {
00396       bc->caller.screening = screen;
00397    } else {
00398       bc->caller.screening = 0;  /* Unscreened */
00399    }
00400 
00401    dec_ie_facility(setup->FACILITY, (Q931_info_t *) setup, &bc->fac_in, nt, bc);
00402 
00403    dec_ie_called_pn(setup->CALLED_PN, (Q931_info_t *) setup, &type, &plan, bc->dialed.number, sizeof(bc->dialed.number), nt, bc);
00404    bc->dialed.number_type = type;
00405    bc->dialed.number_plan = plan;
00406 
00407    dec_ie_keypad(setup->KEYPAD, (Q931_info_t *) setup, bc->keypad, sizeof(bc->keypad), nt, bc);
00408 
00409    dec_ie_complete(setup->COMPLETE, (Q931_info_t *) setup, &bc->sending_complete, nt, bc);
00410 
00411    dec_ie_redir_nr(setup->REDIR_NR, (Q931_info_t *) setup, &type, &plan, &present, &screen, &reason, bc->redirecting.from.number, sizeof(bc->redirecting.from.number), nt, bc);
00412    bc->redirecting.from.number_type = type;
00413    bc->redirecting.from.number_plan = plan;
00414    switch (present) {
00415    default:
00416    case 0:
00417       bc->redirecting.from.presentation = 0; /* presentation allowed */
00418       break;
00419    case 1:
00420       bc->redirecting.from.presentation = 1; /* presentation restricted */
00421       break;
00422    case 2:
00423       bc->redirecting.from.presentation = 2; /* Number not available */
00424       break;
00425    }
00426    if (0 <= screen) {
00427       bc->redirecting.from.screening = screen;
00428    } else {
00429       bc->redirecting.from.screening = 0; /* Unscreened */
00430    }
00431    if (0 <= reason) {
00432       bc->redirecting.reason = reason;
00433    } else {
00434       bc->redirecting.reason = mISDN_REDIRECTING_REASON_UNKNOWN;
00435    }
00436 
00437    {
00438       int  coding, capability, mode, rate, multi, user, async, urate, stopbits, dbits, parity;
00439 
00440       dec_ie_bearer(setup->BEARER, (Q931_info_t *)setup, &coding, &capability, &mode, &rate, &multi, &user, &async, &urate, &stopbits, &dbits, &parity, nt,bc);
00441       switch (capability) {
00442       case -1: bc->capability=INFO_CAPABILITY_DIGITAL_UNRESTRICTED;
00443          break;
00444       case 0: bc->capability=INFO_CAPABILITY_SPEECH;
00445          break;
00446       case 18: bc->capability=INFO_CAPABILITY_VIDEO;
00447          break;
00448       case 8: bc->capability=INFO_CAPABILITY_DIGITAL_UNRESTRICTED;
00449          bc->user1 = user;
00450          bc->urate = urate;
00451 
00452          bc->rate = rate;
00453          bc->mode = mode;
00454          break;
00455       case 9: bc->capability=INFO_CAPABILITY_DIGITAL_RESTRICTED;
00456          break;
00457       default:
00458          break;
00459       }
00460 
00461       switch(user) {
00462       case 2:
00463          bc->law=INFO_CODEC_ULAW;
00464          break;
00465       case 3:
00466          bc->law=INFO_CODEC_ALAW;
00467          break;
00468       default:
00469          bc->law=INFO_CODEC_ALAW;
00470 
00471       }
00472 
00473       bc->capability=capability;
00474    }
00475    {
00476       int  exclusive, channel;
00477       dec_ie_channel_id(setup->CHANNEL_ID, (Q931_info_t *)setup, &exclusive, &channel, nt,bc);
00478 
00479       set_channel(bc,channel);
00480    }
00481 
00482    {
00483       int  protocol ;
00484       dec_ie_useruser(setup->USER_USER, (Q931_info_t *)setup, &protocol, bc->uu, &bc->uulen, nt,bc);
00485       if (bc->uulen) cb_log(1,bc->port,"USERUESRINFO:%s\n",bc->uu);
00486       else
00487       cb_log(1,bc->port,"NO USERUESRINFO\n");
00488    }
00489 
00490    dec_ie_progress(setup->PROGRESS, (Q931_info_t *)setup, &bc->progress_coding, &bc->progress_location, &bc->progress_indicator, nt, bc);
00491 
00492 #if defined(AST_MISDN_ENHANCEMENTS)
00493    extract_setup_Bc_Hlc_Llc(setup, nt, bc);
00494 #endif   /* defined(AST_MISDN_ENHANCEMENTS) */
00495 }
00496 
00497 #define ANY_CHANNEL 0xff /* IE attribute for 'any channel' */
00498 static msg_t *build_setup (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
00499 {
00500    int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
00501    SETUP_t *setup;
00502    msg_t *msg =(msg_t*)create_l3msg(CC_SETUP | REQUEST, MT_SETUP,  bc?bc->l3_id:-1, sizeof(SETUP_t) ,nt);
00503    int is_ptp;
00504    enum FacFunction fac_type;
00505 
00506    setup=(SETUP_t*)((msg->data+HEADER_LEN));
00507 
00508    if (bc->channel == 0 || bc->channel == ANY_CHANNEL || bc->channel==-1)
00509       enc_ie_channel_id(&setup->CHANNEL_ID, msg, 0, bc->channel, nt,bc);
00510    else
00511       enc_ie_channel_id(&setup->CHANNEL_ID, msg, 1, bc->channel, nt,bc);
00512 
00513    fac_type = bc->fac_out.Function;
00514    if (fac_type != Fac_None) {
00515       enc_ie_facility(&setup->FACILITY, msg, &bc->fac_out, nt);
00516    }
00517 
00518    enc_ie_calling_pn(&setup->CALLING_PN, msg, bc->caller.number_type, bc->caller.number_plan,
00519       bc->caller.presentation, bc->caller.screening, bc->caller.number, nt, bc);
00520 
00521    if (bc->dialed.number[0]) {
00522       enc_ie_called_pn(&setup->CALLED_PN, msg, bc->dialed.number_type, bc->dialed.number_plan, bc->dialed.number, nt, bc);
00523    }
00524 
00525    switch (bc->outgoing_colp) {
00526    case 0:/* pass */
00527    case 1:/* restricted */
00528       is_ptp = misdn_lib_is_ptp(bc->port);
00529       if (bc->redirecting.from.number[0]
00530          && ((!is_ptp && nt)
00531             || (is_ptp
00532 #if defined(AST_MISDN_ENHANCEMENTS)
00533                /*
00534                 * There is no need to send out this ie when we are also sending
00535                 * a Fac_DivertingLegInformation2 as well.  The
00536                 * Fac_DivertingLegInformation2 supercedes the information in
00537                 * this ie.
00538                 */
00539                && fac_type != Fac_DivertingLegInformation2
00540 #endif   /* defined(AST_MISDN_ENHANCEMENTS) */
00541          ))) {
00542 #if 1
00543          /* ETSI and Q.952 do not define the screening field */
00544          enc_ie_redir_nr(&setup->REDIR_NR, msg, bc->redirecting.from.number_type,
00545             bc->redirecting.from.number_plan, bc->redirecting.from.presentation, 0,
00546             bc->redirecting.reason, bc->redirecting.from.number, nt, bc);
00547 #else
00548          /* Q.931 defines the screening field */
00549          enc_ie_redir_nr(&setup->REDIR_NR, msg, bc->redirecting.from.number_type,
00550             bc->redirecting.from.number_plan, bc->redirecting.from.presentation,
00551             bc->redirecting.from.screening, bc->redirecting.reason,
00552             bc->redirecting.from.number, nt, bc);
00553 #endif
00554       }
00555       break;
00556    default:
00557       break;
00558    }
00559 
00560    if (bc->keypad[0]) {
00561       enc_ie_keypad(&setup->KEYPAD, msg, bc->keypad, nt,bc);
00562    }
00563 
00564 
00565 
00566    if (*bc->display) {
00567       enc_ie_display(&setup->DISPLAY, msg, bc->display, nt, bc);
00568    } else if (nt && bc->caller.presentation == 0) {
00569       char display[sizeof(bc->display)];
00570 
00571       /* Presentation is allowed */
00572       build_display_str(display, sizeof(display), bc->display_setup, bc->caller.name, bc->caller.number);
00573       if (display[0]) {
00574          enc_ie_display(&setup->DISPLAY, msg, display, nt, bc);
00575       }
00576    }
00577 
00578    {
00579       int coding = 0;
00580       int capability;
00581       int mode = 0;  /* 2 for packet! */
00582       int user;
00583       int rate = 0x10;
00584 
00585       switch (bc->law) {
00586       case INFO_CODEC_ULAW: user=2;
00587          break;
00588       case INFO_CODEC_ALAW: user=3;
00589          break;
00590       default:
00591          user=3;
00592       }
00593 
00594       switch (bc->capability) {
00595       case INFO_CAPABILITY_SPEECH: capability = 0;
00596          break;
00597       case INFO_CAPABILITY_DIGITAL_UNRESTRICTED: capability = 8;
00598          user=-1;
00599          mode=bc->mode;
00600          rate=bc->rate;
00601          break;
00602       case INFO_CAPABILITY_DIGITAL_RESTRICTED: capability = 9;
00603          user=-1;
00604          break;
00605       default:
00606          capability=bc->capability;
00607       }
00608 
00609       enc_ie_bearer(&setup->BEARER, msg, coding, capability, mode, rate, -1, user, nt,bc);
00610    }
00611 
00612    if (bc->sending_complete) {
00613       enc_ie_complete(&setup->COMPLETE,msg, bc->sending_complete, nt, bc);
00614    }
00615 
00616    if (bc->uulen) {
00617       int  protocol=4;
00618       enc_ie_useruser(&setup->USER_USER, msg, protocol, bc->uu, bc->uulen, nt,bc);
00619       cb_log(1,bc->port,"ENCODING USERUESRINFO:%s\n",bc->uu);
00620    }
00621 
00622 #if defined(AST_MISDN_ENHANCEMENTS)
00623    extract_setup_Bc_Hlc_Llc(setup, nt, bc);
00624 #endif   /* defined(AST_MISDN_ENHANCEMENTS) */
00625 
00626 #ifdef DEBUG
00627    printf("Building SETUP Msg\n");
00628 #endif
00629    return msg;
00630 }
00631 
00632 static void parse_connect (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
00633 {
00634    int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
00635    CONNECT_t *connect = (CONNECT_t *) (msg->data + HEADER_LEN);
00636    int type;
00637    int plan;
00638    int pres;
00639    int screen;
00640 
00641    bc->ces = connect->ces;
00642 
00643    dec_ie_progress(connect->PROGRESS, (Q931_info_t *)connect, &bc->progress_coding, &bc->progress_location, &bc->progress_indicator, nt, bc);
00644 
00645    dec_ie_connected_pn(connect->CONNECT_PN, (Q931_info_t *) connect, &type, &plan,
00646       &pres, &screen, bc->connected.number, sizeof(bc->connected.number), nt, bc);
00647    bc->connected.number_type = type;
00648    bc->connected.number_plan = plan;
00649    switch (pres) {
00650    default:
00651    case 0:
00652       bc->connected.presentation = 0;  /* presentation allowed */
00653       break;
00654    case 1:
00655       bc->connected.presentation = 1;  /* presentation restricted */
00656       break;
00657    case 2:
00658       bc->connected.presentation = 2;  /* Number not available */
00659       break;
00660    }
00661    if (0 <= screen) {
00662       bc->connected.screening = screen;
00663    } else {
00664       bc->connected.screening = 0;  /* Unscreened */
00665    }
00666 
00667    dec_ie_facility(connect->FACILITY, (Q931_info_t *) connect, &bc->fac_in, nt, bc);
00668 
00669    /*
00670       cb_log(1,bc->port,"CONNETED PN: %s cpn_dialplan:%d\n", connected_pn, type);
00671    */
00672 
00673 #ifdef DEBUG
00674    printf("Parsing CONNECT Msg\n");
00675 #endif
00676 }
00677 
00678 static msg_t *build_connect (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
00679 {
00680    int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
00681    CONNECT_t *connect;
00682    msg_t *msg =(msg_t*)create_l3msg(CC_CONNECT | REQUEST, MT_CONNECT,  bc?bc->l3_id:-1, sizeof(CONNECT_t) ,nt);
00683 
00684    cb_log(6,bc->port,"BUILD_CONNECT: bc:%p bc->l3id:%d, nt:%d\n",bc,bc->l3_id,nt);
00685 
00686    connect=(CONNECT_t*)((msg->data+HEADER_LEN));
00687 
00688    if (nt) {
00689       time_t now;
00690       time(&now);
00691       enc_ie_date(&connect->DATE, msg, now, nt,bc);
00692    }
00693 
00694    switch (bc->outgoing_colp) {
00695    case 0:/* pass */
00696    case 1:/* restricted */
00697       enc_ie_connected_pn(&connect->CONNECT_PN, msg, bc->connected.number_type,
00698          bc->connected.number_plan, bc->connected.presentation,
00699          bc->connected.screening, bc->connected.number, nt, bc);
00700       break;
00701    default:
00702       break;
00703    }
00704 
00705    if (nt && bc->connected.presentation == 0) {
00706       char display[sizeof(bc->display)];
00707 
00708       /* Presentation is allowed */
00709       build_display_str(display, sizeof(display), bc->display_connected, bc->connected.name, bc->connected.number);
00710       if (display[0]) {
00711          enc_ie_display(&connect->DISPLAY, msg, display, nt, bc);
00712       }
00713    }
00714 
00715    if (bc->fac_out.Function != Fac_None) {
00716       enc_ie_facility(&connect->FACILITY, msg, &bc->fac_out, nt);
00717    }
00718 
00719 #ifdef DEBUG
00720    printf("Building CONNECT Msg\n");
00721 #endif
00722    return msg;
00723 }
00724 
00725 static void parse_setup_acknowledge (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
00726 {
00727    int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
00728    SETUP_ACKNOWLEDGE_t *setup_acknowledge = (SETUP_ACKNOWLEDGE_t *) (msg->data + HEADER_LEN);
00729 
00730    {
00731       int  exclusive, channel;
00732       dec_ie_channel_id(setup_acknowledge->CHANNEL_ID, (Q931_info_t *)setup_acknowledge, &exclusive, &channel, nt,bc);
00733 
00734 
00735       set_channel(bc, channel);
00736    }
00737 
00738    dec_ie_progress(setup_acknowledge->PROGRESS, (Q931_info_t *)setup_acknowledge, &bc->progress_coding, &bc->progress_location, &bc->progress_indicator, nt, bc);
00739 
00740    dec_ie_facility(setup_acknowledge->FACILITY, (Q931_info_t *) setup_acknowledge, &bc->fac_in, nt, bc);
00741 
00742 #ifdef DEBUG
00743    printf("Parsing SETUP_ACKNOWLEDGE Msg\n");
00744 #endif
00745 
00746 
00747 }
00748 
00749 static msg_t *build_setup_acknowledge (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
00750 {
00751    int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
00752    SETUP_ACKNOWLEDGE_t *setup_acknowledge;
00753    msg_t *msg =(msg_t*)create_l3msg(CC_SETUP_ACKNOWLEDGE | REQUEST, MT_SETUP_ACKNOWLEDGE,  bc?bc->l3_id:-1, sizeof(SETUP_ACKNOWLEDGE_t) ,nt);
00754 
00755    setup_acknowledge=(SETUP_ACKNOWLEDGE_t*)((msg->data+HEADER_LEN));
00756 
00757    enc_ie_channel_id(&setup_acknowledge->CHANNEL_ID, msg, 1,bc->channel, nt,bc);
00758 
00759    if (nt)
00760       enc_ie_progress(&setup_acknowledge->PROGRESS, msg, 0, nt?1:5, 8, nt,bc);
00761 
00762    if (bc->fac_out.Function != Fac_None) {
00763       enc_ie_facility(&setup_acknowledge->FACILITY, msg, &bc->fac_out, nt);
00764    }
00765 
00766 #ifdef DEBUG
00767    printf("Building SETUP_ACKNOWLEDGE Msg\n");
00768 #endif
00769    return msg;
00770 }
00771 
00772 static void parse_connect_acknowledge (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
00773 {
00774 #ifdef DEBUG
00775    printf("Parsing CONNECT_ACKNOWLEDGE Msg\n");
00776 #endif
00777 
00778 
00779 }
00780 
00781 static msg_t *build_connect_acknowledge (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
00782 {
00783    int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
00784    CONNECT_ACKNOWLEDGE_t *connect_acknowledge;
00785    msg_t *msg =(msg_t*)create_l3msg(CC_CONNECT | RESPONSE, MT_CONNECT,  bc?bc->l3_id:-1, sizeof(CONNECT_ACKNOWLEDGE_t) ,nt);
00786 
00787    connect_acknowledge=(CONNECT_ACKNOWLEDGE_t*)((msg->data+HEADER_LEN));
00788 
00789    enc_ie_channel_id(&connect_acknowledge->CHANNEL_ID, msg, 1, bc->channel, nt,bc);
00790 
00791 #ifdef DEBUG
00792    printf("Building CONNECT_ACKNOWLEDGE Msg\n");
00793 #endif
00794    return msg;
00795 }
00796 
00797 static void parse_user_information (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
00798 {
00799 #ifdef DEBUG
00800    printf("Parsing USER_INFORMATION Msg\n");
00801 #endif
00802 
00803 
00804 }
00805 
00806 static msg_t *build_user_information (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
00807 {
00808    msg_t *msg =(msg_t*)create_l3msg(CC_USER_INFORMATION | REQUEST, MT_USER_INFORMATION,  bc?bc->l3_id:-1, sizeof(USER_INFORMATION_t) ,nt);
00809 
00810 #ifdef DEBUG
00811    printf("Building USER_INFORMATION Msg\n");
00812 #endif
00813    return msg;
00814 }
00815 
00816 static void parse_suspend_reject (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
00817 {
00818 #ifdef DEBUG
00819    printf("Parsing SUSPEND_REJECT Msg\n");
00820 #endif
00821 
00822 
00823 }
00824 
00825 static msg_t *build_suspend_reject (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
00826 {
00827    msg_t *msg =(msg_t*)create_l3msg(CC_SUSPEND_REJECT | REQUEST, MT_SUSPEND_REJECT,  bc?bc->l3_id:-1, sizeof(SUSPEND_REJECT_t) ,nt);
00828 
00829 #ifdef DEBUG
00830    printf("Building SUSPEND_REJECT Msg\n");
00831 #endif
00832    return msg;
00833 }
00834 
00835 static void parse_resume_reject (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
00836 {
00837 #ifdef DEBUG
00838    printf("Parsing RESUME_REJECT Msg\n");
00839 #endif
00840 
00841 
00842 }
00843 
00844 static msg_t *build_resume_reject (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
00845 {
00846    msg_t *msg =(msg_t*)create_l3msg(CC_RESUME_REJECT | REQUEST, MT_RESUME_REJECT,  bc?bc->l3_id:-1, sizeof(RESUME_REJECT_t) ,nt);
00847 
00848 #ifdef DEBUG
00849    printf("Building RESUME_REJECT Msg\n");
00850 #endif
00851    return msg;
00852 }
00853 
00854 static void parse_hold (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
00855 {
00856 #ifdef DEBUG
00857    printf("Parsing HOLD Msg\n");
00858 #endif
00859 
00860 
00861 }
00862 
00863 static msg_t *build_hold (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
00864 {
00865    msg_t *msg =(msg_t*)create_l3msg(CC_HOLD | REQUEST, MT_HOLD,  bc?bc->l3_id:-1, sizeof(HOLD_t) ,nt);
00866 
00867 #ifdef DEBUG
00868    printf("Building HOLD Msg\n");
00869 #endif
00870    return msg;
00871 }
00872 
00873 static void parse_suspend (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
00874 {
00875 #ifdef DEBUG
00876    printf("Parsing SUSPEND Msg\n");
00877 #endif
00878 
00879 
00880 }
00881 
00882 static msg_t *build_suspend (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
00883 {
00884    msg_t *msg =(msg_t*)create_l3msg(CC_SUSPEND | REQUEST, MT_SUSPEND,  bc?bc->l3_id:-1, sizeof(SUSPEND_t) ,nt);
00885 
00886 #ifdef DEBUG
00887    printf("Building SUSPEND Msg\n");
00888 #endif
00889    return msg;
00890 }
00891 
00892 static void parse_resume (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
00893 {
00894 #ifdef DEBUG
00895    printf("Parsing RESUME Msg\n");
00896 #endif
00897 
00898 
00899 }
00900 
00901 static msg_t *build_resume (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
00902 {
00903    msg_t *msg =(msg_t*)create_l3msg(CC_RESUME | REQUEST, MT_RESUME,  bc?bc->l3_id:-1, sizeof(RESUME_t) ,nt);
00904 
00905 #ifdef DEBUG
00906    printf("Building RESUME Msg\n");
00907 #endif
00908    return msg;
00909 }
00910 
00911 static void parse_hold_acknowledge (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
00912 {
00913 #ifdef DEBUG
00914    printf("Parsing HOLD_ACKNOWLEDGE Msg\n");
00915 #endif
00916 
00917 
00918 }
00919 
00920 static msg_t *build_hold_acknowledge (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
00921 {
00922    msg_t *msg =(msg_t*)create_l3msg(CC_HOLD_ACKNOWLEDGE | REQUEST, MT_HOLD_ACKNOWLEDGE,  bc?bc->l3_id:-1, sizeof(HOLD_ACKNOWLEDGE_t) ,nt);
00923 
00924 #ifdef DEBUG
00925    printf("Building HOLD_ACKNOWLEDGE Msg\n");
00926 #endif
00927    return msg;
00928 }
00929 
00930 static void parse_suspend_acknowledge (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
00931 {
00932 #ifdef DEBUG
00933    printf("Parsing SUSPEND_ACKNOWLEDGE Msg\n");
00934 #endif
00935 
00936 
00937 }
00938 
00939 static msg_t *build_suspend_acknowledge (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
00940 {
00941    msg_t *msg =(msg_t*)create_l3msg(CC_SUSPEND_ACKNOWLEDGE | REQUEST, MT_SUSPEND_ACKNOWLEDGE,  bc?bc->l3_id:-1, sizeof(SUSPEND_ACKNOWLEDGE_t) ,nt);
00942 
00943 #ifdef DEBUG
00944    printf("Building SUSPEND_ACKNOWLEDGE Msg\n");
00945 #endif
00946    return msg;
00947 }
00948 
00949 static void parse_resume_acknowledge (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
00950 {
00951 #ifdef DEBUG
00952    printf("Parsing RESUME_ACKNOWLEDGE Msg\n");
00953 #endif
00954 
00955 
00956 }
00957 
00958 static msg_t *build_resume_acknowledge (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
00959 {
00960    msg_t *msg =(msg_t*)create_l3msg(CC_RESUME_ACKNOWLEDGE | REQUEST, MT_RESUME_ACKNOWLEDGE,  bc?bc->l3_id:-1, sizeof(RESUME_ACKNOWLEDGE_t) ,nt);
00961 
00962 #ifdef DEBUG
00963    printf("Building RESUME_ACKNOWLEDGE Msg\n");
00964 #endif
00965    return msg;
00966 }
00967 
00968 static void parse_hold_reject (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
00969 {
00970 #ifdef DEBUG
00971    printf("Parsing HOLD_REJECT Msg\n");
00972 #endif
00973 
00974 
00975 }
00976 
00977 static msg_t *build_hold_reject (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
00978 {
00979    msg_t *msg =(msg_t*)create_l3msg(CC_HOLD_REJECT | REQUEST, MT_HOLD_REJECT,  bc?bc->l3_id:-1, sizeof(HOLD_REJECT_t) ,nt);
00980 
00981 #ifdef DEBUG
00982    printf("Building HOLD_REJECT Msg\n");
00983 #endif
00984    return msg;
00985 }
00986 
00987 static void parse_retrieve (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
00988 {
00989 #ifdef DEBUG
00990    printf("Parsing RETRIEVE Msg\n");
00991 #endif
00992 
00993 
00994 }
00995 
00996 static msg_t *build_retrieve (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
00997 {
00998    msg_t *msg =(msg_t*)create_l3msg(CC_RETRIEVE | REQUEST, MT_RETRIEVE,  bc?bc->l3_id:-1, sizeof(RETRIEVE_t) ,nt);
00999 
01000 #ifdef DEBUG
01001    printf("Building RETRIEVE Msg\n");
01002 #endif
01003    return msg;
01004 }
01005 
01006 static void parse_retrieve_acknowledge (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
01007 {
01008 #ifdef DEBUG
01009    printf("Parsing RETRIEVE_ACKNOWLEDGE Msg\n");
01010 #endif
01011 
01012 
01013 }
01014 
01015 static msg_t *build_retrieve_acknowledge (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
01016 {
01017    int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
01018    RETRIEVE_ACKNOWLEDGE_t *retrieve_acknowledge;
01019    msg_t *msg =(msg_t*)create_l3msg(CC_RETRIEVE_ACKNOWLEDGE | REQUEST, MT_RETRIEVE_ACKNOWLEDGE,  bc?bc->l3_id:-1, sizeof(RETRIEVE_ACKNOWLEDGE_t) ,nt);
01020 
01021    retrieve_acknowledge=(RETRIEVE_ACKNOWLEDGE_t*)((msg->data+HEADER_LEN));
01022 
01023    enc_ie_channel_id(&retrieve_acknowledge->CHANNEL_ID, msg, 1, bc->channel, nt,bc);
01024 #ifdef DEBUG
01025    printf("Building RETRIEVE_ACKNOWLEDGE Msg\n");
01026 #endif
01027    return msg;
01028 }
01029 
01030 static void parse_retrieve_reject (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
01031 {
01032 #ifdef DEBUG
01033    printf("Parsing RETRIEVE_REJECT Msg\n");
01034 #endif
01035 
01036 
01037 }
01038 
01039 static msg_t *build_retrieve_reject (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
01040 {
01041    msg_t *msg =(msg_t*)create_l3msg(CC_RETRIEVE_REJECT | REQUEST, MT_RETRIEVE_REJECT,  bc?bc->l3_id:-1, sizeof(RETRIEVE_REJECT_t) ,nt);
01042 
01043 #ifdef DEBUG
01044    printf("Building RETRIEVE_REJECT Msg\n");
01045 #endif
01046    return msg;
01047 }
01048 
01049 static void parse_disconnect (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
01050 {
01051    int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
01052    DISCONNECT_t *disconnect = (DISCONNECT_t *) (msg->data + HEADER_LEN);
01053    int location;
01054    int cause;
01055    dec_ie_cause(disconnect->CAUSE, (Q931_info_t *)(disconnect), &location, &cause, nt,bc);
01056    if (cause>0) bc->cause=cause;
01057 
01058    dec_ie_facility(disconnect->FACILITY, (Q931_info_t *) disconnect, &bc->fac_in, nt, bc);
01059 
01060    dec_ie_progress(disconnect->PROGRESS, (Q931_info_t *)disconnect, &bc->progress_coding, &bc->progress_location, &bc->progress_indicator, nt, bc);
01061 #ifdef DEBUG
01062    printf("Parsing DISCONNECT Msg\n");
01063 #endif
01064 
01065 
01066 }
01067 
01068 static msg_t *build_disconnect (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
01069 {
01070    int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
01071    DISCONNECT_t *disconnect;
01072    msg_t *msg =(msg_t*)create_l3msg(CC_DISCONNECT | REQUEST, MT_DISCONNECT,  bc?bc->l3_id:-1, sizeof(DISCONNECT_t) ,nt);
01073 
01074    disconnect=(DISCONNECT_t*)((msg->data+HEADER_LEN));
01075 
01076    enc_ie_cause(&disconnect->CAUSE, msg, (nt)?1:0, bc->out_cause,nt,bc);
01077    if (nt) {
01078       enc_ie_progress(&disconnect->PROGRESS, msg, 0, nt ? 1 : 5, 8, nt, bc);
01079    }
01080 
01081    if (bc->fac_out.Function != Fac_None) {
01082       enc_ie_facility(&disconnect->FACILITY, msg, &bc->fac_out, nt);
01083    }
01084 
01085    if (bc->uulen) {
01086       int  protocol=4;
01087       enc_ie_useruser(&disconnect->USER_USER, msg, protocol, bc->uu, bc->uulen, nt,bc);
01088       cb_log(1,bc->port,"ENCODING USERUESRINFO:%s\n",bc->uu);
01089    }
01090 
01091 #ifdef DEBUG
01092    printf("Building DISCONNECT Msg\n");
01093 #endif
01094    return msg;
01095 }
01096 
01097 static void parse_restart (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
01098 {
01099    int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
01100    RESTART_t *restart = (RESTART_t *) (msg->data + HEADER_LEN);
01101 
01102    struct misdn_stack *stack=get_stack_by_bc(bc);
01103 
01104 #ifdef DEBUG
01105    printf("Parsing RESTART Msg\n");
01106 #endif
01107 
01108    {
01109       int  exclusive;
01110       dec_ie_channel_id(restart->CHANNEL_ID, (Q931_info_t *)restart, &exclusive, &bc->restart_channel, nt,bc);
01111       cb_log(3, stack->port, "CC_RESTART Request on channel:%d on this port.\n", bc->restart_channel);
01112    }
01113 
01114 }
01115 
01116 static msg_t *build_restart (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
01117 {
01118    int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
01119    RESTART_t *restart;
01120    msg_t *msg =(msg_t*)create_l3msg(CC_RESTART | REQUEST, MT_RESTART,  bc?bc->l3_id:-1, sizeof(RESTART_t) ,nt);
01121 
01122    restart=(RESTART_t*)((msg->data+HEADER_LEN));
01123 
01124 #ifdef DEBUG
01125    printf("Building RESTART Msg\n");
01126 #endif
01127 
01128    if (bc->channel > 0) {
01129       enc_ie_channel_id(&restart->CHANNEL_ID, msg, 1,bc->channel, nt,bc);
01130       enc_ie_restart_ind(&restart->RESTART_IND, msg, 0x80, nt, bc);
01131    } else {
01132       enc_ie_restart_ind(&restart->RESTART_IND, msg, 0x87, nt, bc);
01133    }
01134 
01135    cb_log(0,bc->port, "Restarting channel %d\n", bc->channel);
01136    return msg;
01137 }
01138 
01139 static void parse_release (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
01140 {
01141    int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
01142    RELEASE_t *release = (RELEASE_t *) (msg->data + HEADER_LEN);
01143    int location;
01144    int cause;
01145 
01146    dec_ie_cause(release->CAUSE, (Q931_info_t *)(release), &location, &cause, nt,bc);
01147    if (cause>0) bc->cause=cause;
01148 
01149    dec_ie_facility(release->FACILITY, (Q931_info_t *) release, &bc->fac_in, nt, bc);
01150 
01151 #ifdef DEBUG
01152    printf("Parsing RELEASE Msg\n");
01153 #endif
01154 
01155 
01156 }
01157 
01158 static msg_t *build_release (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
01159 {
01160    int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
01161    RELEASE_t *release;
01162    msg_t *msg =(msg_t*)create_l3msg(CC_RELEASE | REQUEST, MT_RELEASE,  bc?bc->l3_id:-1, sizeof(RELEASE_t) ,nt);
01163 
01164    release=(RELEASE_t*)((msg->data+HEADER_LEN));
01165 
01166    if (bc->out_cause>= 0)
01167       enc_ie_cause(&release->CAUSE, msg, nt?1:0, bc->out_cause, nt,bc);
01168 
01169    if (bc->fac_out.Function != Fac_None) {
01170       enc_ie_facility(&release->FACILITY, msg, &bc->fac_out, nt);
01171    }
01172 
01173    if (bc->uulen) {
01174       int  protocol=4;
01175       enc_ie_useruser(&release->USER_USER, msg, protocol, bc->uu, bc->uulen, nt,bc);
01176       cb_log(1,bc->port,"ENCODING USERUESRINFO:%s\n",bc->uu);
01177    }
01178 
01179 #ifdef DEBUG
01180    printf("Building RELEASE Msg\n");
01181 #endif
01182    return msg;
01183 }
01184 
01185 static void parse_release_complete (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
01186 {
01187    int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
01188    RELEASE_COMPLETE_t *release_complete = (RELEASE_COMPLETE_t *) (msg->data + HEADER_LEN);
01189    int location;
01190    int cause;
01191    iframe_t *frm = (iframe_t*) msg->data;
01192 
01193    struct misdn_stack *stack=get_stack_by_bc(bc);
01194    mISDNuser_head_t *hh;
01195    hh=(mISDNuser_head_t*)msg->data;
01196 
01197    /*hh=(mISDN_head_t*)msg->data;
01198    mISDN_head_t *hh;*/
01199 
01200    if (nt) {
01201       if (hh->prim == (CC_RELEASE_COMPLETE|CONFIRM)) {
01202          cb_log(0, stack->port, "CC_RELEASE_COMPLETE|CONFIRM [NT] \n");
01203          return;
01204       }
01205    } else {
01206       if (frm->prim == (CC_RELEASE_COMPLETE|CONFIRM)) {
01207          cb_log(0, stack->port, "CC_RELEASE_COMPLETE|CONFIRM [TE] \n");
01208          return;
01209       }
01210    }
01211    dec_ie_cause(release_complete->CAUSE, (Q931_info_t *)(release_complete), &location, &cause, nt,bc);
01212    if (cause>0) bc->cause=cause;
01213 
01214    dec_ie_facility(release_complete->FACILITY, (Q931_info_t *) release_complete, &bc->fac_in, nt, bc);
01215 
01216 #ifdef DEBUG
01217    printf("Parsing RELEASE_COMPLETE Msg\n");
01218 #endif
01219 }
01220 
01221 static msg_t *build_release_complete (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
01222 {
01223    int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
01224    RELEASE_COMPLETE_t *release_complete;
01225    msg_t *msg =(msg_t*)create_l3msg(CC_RELEASE_COMPLETE | REQUEST, MT_RELEASE_COMPLETE,  bc?bc->l3_id:-1, sizeof(RELEASE_COMPLETE_t) ,nt);
01226 
01227    release_complete=(RELEASE_COMPLETE_t*)((msg->data+HEADER_LEN));
01228 
01229    enc_ie_cause(&release_complete->CAUSE, msg, nt?1:0, bc->out_cause, nt,bc);
01230 
01231    if (bc->fac_out.Function != Fac_None) {
01232       enc_ie_facility(&release_complete->FACILITY, msg, &bc->fac_out, nt);
01233    }
01234 
01235    if (bc->uulen) {
01236       int  protocol=4;
01237       enc_ie_useruser(&release_complete->USER_USER, msg, protocol, bc->uu, bc->uulen, nt,bc);
01238       cb_log(1,bc->port,"ENCODING USERUESRINFO:%s\n",bc->uu);
01239    }
01240 
01241 #ifdef DEBUG
01242    printf("Building RELEASE_COMPLETE Msg\n");
01243 #endif
01244    return msg;
01245 }
01246 
01247 static void parse_facility (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
01248 {
01249    int HEADER_LEN = nt ? mISDNUSER_HEAD_SIZE : mISDN_HEADER_LEN;
01250    FACILITY_t *facility = (FACILITY_t*)(msg->data+HEADER_LEN);
01251    Q931_info_t *qi = (Q931_info_t*)(msg->data+HEADER_LEN);
01252    unsigned char *p = NULL;
01253 #if defined(AST_MISDN_ENHANCEMENTS)
01254    int description_code;
01255    int type;
01256    int plan;
01257    int present;
01258    char number[sizeof(bc->redirecting.to.number)];
01259 #endif   /* defined(AST_MISDN_ENHANCEMENTS) */
01260 
01261 #ifdef DEBUG
01262    printf("Parsing FACILITY Msg\n");
01263 #endif
01264 
01265    bc->fac_in.Function = Fac_None;
01266 
01267    if (!bc->nt) {
01268       if (qi->QI_ELEMENT(facility))
01269          p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(facility) + 1;
01270    } else {
01271       p = facility->FACILITY;
01272    }
01273    if (!p)
01274       return;
01275 
01276    if (decodeFac(p, &bc->fac_in)) {
01277       cb_log(3, bc->port, "Decoding facility ie failed! Unrecognized facility message?\n");
01278    }
01279 
01280 #if defined(AST_MISDN_ENHANCEMENTS)
01281    dec_ie_notify(facility->NOTIFY, qi, &description_code, nt, bc);
01282    if (description_code < 0) {
01283       bc->notify_description_code = mISDN_NOTIFY_CODE_INVALID;
01284    } else {
01285       bc->notify_description_code = description_code;
01286    }
01287 
01288    dec_ie_redir_dn(facility->REDIR_DN, qi, &type, &plan, &present, number, sizeof(number), nt, bc);
01289    if (0 <= type) {
01290       bc->redirecting.to_changed = 1;
01291 
01292       bc->redirecting.to.number_type = type;
01293       bc->redirecting.to.number_plan = plan;
01294       switch (present) {
01295       default:
01296       case 0:
01297          bc->redirecting.to.presentation = 0;   /* presentation allowed */
01298          break;
01299       case 1:
01300          bc->redirecting.to.presentation = 1;   /* presentation restricted */
01301          break;
01302       case 2:
01303          bc->redirecting.to.presentation = 2;   /* Number not available */
01304          break;
01305       }
01306       bc->redirecting.to.screening = 0;   /* Unscreened */
01307       strcpy(bc->redirecting.to.number, number);
01308    }
01309 #endif   /* defined(AST_MISDN_ENHANCEMENTS) */
01310 }
01311 
01312 static msg_t *build_facility (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
01313 {
01314    int len;
01315    int HEADER_LEN;
01316    unsigned char *ie_fac;
01317    unsigned char fac_tmp[256];
01318    msg_t *msg;
01319    FACILITY_t *facility;
01320    Q931_info_t *qi;
01321 
01322 #ifdef DEBUG
01323    printf("Building FACILITY Msg\n");
01324 #endif
01325 
01326    len = encodeFac(fac_tmp, &(bc->fac_out));
01327    if (len <= 0) {
01328       /*
01329        * mISDN does not know how to build the requested facility structure
01330        * Clear facility information
01331        */
01332       bc->fac_out.Function = Fac_None;
01333 
01334 #if defined(AST_MISDN_ENHANCEMENTS)
01335       /* Clear other one shot information. */
01336       bc->notify_description_code = mISDN_NOTIFY_CODE_INVALID;
01337       bc->redirecting.to_changed = 0;
01338 #endif   /* defined(AST_MISDN_ENHANCEMENTS) */
01339       return NULL;
01340    }
01341 
01342    msg = (msg_t *) create_l3msg(CC_FACILITY | REQUEST, MT_FACILITY, bc ? bc->l3_id : -1, sizeof(FACILITY_t), nt);
01343    HEADER_LEN = nt ? mISDNUSER_HEAD_SIZE : mISDN_HEADER_LEN;
01344    facility = (FACILITY_t *) (msg->data + HEADER_LEN);
01345 
01346    ie_fac = msg_put(msg, len);
01347    if (bc->nt) {
01348       facility->FACILITY = ie_fac + 1;
01349    } else {
01350       qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
01351       qi->QI_ELEMENT(facility) = ie_fac - (unsigned char *)qi - sizeof(Q931_info_t);
01352    }
01353 
01354    memcpy(ie_fac, fac_tmp, len);
01355 
01356    /* Clear facility information */
01357    bc->fac_out.Function = Fac_None;
01358 
01359    if (*bc->display) {
01360 #ifdef DEBUG
01361       printf("Sending %s as Display\n", bc->display);
01362 #endif
01363       enc_ie_display(&facility->DISPLAY, msg, bc->display, nt,bc);
01364    }
01365 
01366 #if defined(AST_MISDN_ENHANCEMENTS)
01367    if (bc->notify_description_code != mISDN_NOTIFY_CODE_INVALID) {
01368       enc_ie_notify(&facility->NOTIFY, msg, bc->notify_description_code, nt, bc);
01369       bc->notify_description_code = mISDN_NOTIFY_CODE_INVALID;
01370    }
01371 
01372    if (bc->redirecting.to_changed) {
01373       bc->redirecting.to_changed = 0;
01374       switch (bc->outgoing_colp) {
01375       case 0:/* pass */
01376       case 1:/* restricted */
01377          enc_ie_redir_dn(&facility->REDIR_DN, msg, bc->redirecting.to.number_type,
01378             bc->redirecting.to.number_plan, bc->redirecting.to.presentation,
01379             bc->redirecting.to.number, nt, bc);
01380          break;
01381       default:
01382          break;
01383       }
01384    }
01385 #endif   /* defined(AST_MISDN_ENHANCEMENTS) */
01386 
01387    return msg;
01388 }
01389 
01390 #if defined(AST_MISDN_ENHANCEMENTS)
01391 /*!
01392  * \internal
01393  * \brief Parse a received REGISTER message
01394  *
01395  * \param msgs Search table entry that called us.
01396  * \param msg Received message contents
01397  * \param bc Associated B channel
01398  * \param nt TRUE if in NT mode.
01399  *
01400  * \return Nothing
01401  */
01402 static void parse_register(struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
01403 {
01404    int HEADER_LEN;
01405    REGISTER_t *reg;
01406 
01407    HEADER_LEN = nt ? mISDNUSER_HEAD_SIZE : mISDN_HEADER_LEN;
01408    reg = (REGISTER_t *) (msg->data + HEADER_LEN);
01409 
01410    /*
01411     * A facility ie is optional.
01412     * The peer may just be establishing a connection to send
01413     * messages later.
01414     */
01415    dec_ie_facility(reg->FACILITY, (Q931_info_t *) reg, &bc->fac_in, nt, bc);
01416 }
01417 #endif   /* defined(AST_MISDN_ENHANCEMENTS) */
01418 
01419 #if defined(AST_MISDN_ENHANCEMENTS)
01420 /*!
01421  * \internal
01422  * \brief Construct a REGISTER message
01423  *
01424  * \param msgs Search table entry that called us.
01425  * \param bc Associated B channel
01426  * \param nt TRUE if in NT mode.
01427  *
01428  * \return Allocated built message
01429  */
01430 static msg_t *build_register(struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
01431 {
01432    int HEADER_LEN;
01433    REGISTER_t *reg;
01434    msg_t *msg;
01435 
01436    msg = (msg_t *) create_l3msg(CC_REGISTER | REQUEST, MT_REGISTER,  bc ? bc->l3_id : -1, sizeof(REGISTER_t), nt);
01437    HEADER_LEN = nt ? mISDNUSER_HEAD_SIZE : mISDN_HEADER_LEN;
01438    reg = (REGISTER_t *) (msg->data + HEADER_LEN);
01439 
01440    if (bc->fac_out.Function != Fac_None) {
01441       enc_ie_facility(&reg->FACILITY, msg, &bc->fac_out, nt);
01442    }
01443 
01444    return msg;
01445 }
01446 #endif   /* defined(AST_MISDN_ENHANCEMENTS) */
01447 
01448 static void parse_notify (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
01449 {
01450    int HEADER_LEN = nt ? mISDNUSER_HEAD_SIZE : mISDN_HEADER_LEN;
01451    NOTIFY_t *notify = (NOTIFY_t *) (msg->data + HEADER_LEN);
01452    int description_code;
01453    int type;
01454    int plan;
01455    int present;
01456    char number[sizeof(bc->redirecting.to.number)];
01457 
01458 #ifdef DEBUG
01459    printf("Parsing NOTIFY Msg\n");
01460 #endif
01461 
01462    dec_ie_notify(notify->NOTIFY, (Q931_info_t *) notify, &description_code, nt, bc);
01463    if (description_code < 0) {
01464       bc->notify_description_code = mISDN_NOTIFY_CODE_INVALID;
01465    } else {
01466       bc->notify_description_code = description_code;
01467    }
01468 
01469    dec_ie_redir_dn(notify->REDIR_DN, (Q931_info_t *) notify, &type, &plan, &present, number, sizeof(number), nt, bc);
01470    if (0 <= type) {
01471       bc->redirecting.to_changed = 1;
01472 
01473       bc->redirecting.to.number_type = type;
01474       bc->redirecting.to.number_plan = plan;
01475       switch (present) {
01476       default:
01477       case 0:
01478          bc->redirecting.to.presentation = 0;   /* presentation allowed */
01479          break;
01480       case 1:
01481          bc->redirecting.to.presentation = 1;   /* presentation restricted */
01482          break;
01483       case 2:
01484          bc->redirecting.to.presentation = 2;   /* Number not available */
01485          break;
01486       }
01487       bc->redirecting.to.screening = 0;   /* Unscreened */
01488       strcpy(bc->redirecting.to.number, number);
01489    }
01490 }
01491 
01492 static msg_t *build_notify (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
01493 {
01494    int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
01495    NOTIFY_t *notify;
01496    msg_t *msg =(msg_t*)create_l3msg(CC_NOTIFY | REQUEST, MT_NOTIFY,  bc?bc->l3_id:-1, sizeof(NOTIFY_t) ,nt);
01497 
01498 #ifdef DEBUG
01499    printf("Building NOTIFY Msg\n");
01500 #endif
01501 
01502    notify = (NOTIFY_t *) (msg->data + HEADER_LEN);
01503 
01504    enc_ie_notify(&notify->NOTIFY, msg, bc->notify_description_code, nt, bc);
01505    bc->notify_description_code = mISDN_NOTIFY_CODE_INVALID;
01506 
01507    if (bc->redirecting.to_changed) {
01508       bc->redirecting.to_changed = 0;
01509       switch (bc->outgoing_colp) {
01510       case 0:/* pass */
01511       case 1:/* restricted */
01512          enc_ie_redir_dn(&notify->REDIR_DN, msg, bc->redirecting.to.number_type,
01513             bc->redirecting.to.number_plan, bc->redirecting.to.presentation,
01514             bc->redirecting.to.number, nt, bc);
01515          break;
01516       default:
01517          break;
01518       }
01519    }
01520    return msg;
01521 }
01522 
01523 static void parse_status_enquiry (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
01524 {
01525 #ifdef DEBUG
01526    printf("Parsing STATUS_ENQUIRY Msg\n");
01527 #endif
01528 }
01529 
01530 static msg_t *build_status_enquiry (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
01531 {
01532    msg_t *msg =(msg_t*)create_l3msg(CC_STATUS_ENQUIRY | REQUEST, MT_STATUS_ENQUIRY,  bc?bc->l3_id:-1, sizeof(STATUS_ENQUIRY_t) ,nt);
01533 
01534 #ifdef DEBUG
01535    printf("Building STATUS_ENQUIRY Msg\n");
01536 #endif
01537    return msg;
01538 }
01539 
01540 static void parse_information (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
01541 {
01542    int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
01543    INFORMATION_t *information = (INFORMATION_t *) (msg->data + HEADER_LEN);
01544    int type, plan;
01545 
01546    dec_ie_called_pn(information->CALLED_PN, (Q931_info_t *) information, &type, &plan, bc->info_dad, sizeof(bc->info_dad), nt, bc);
01547    dec_ie_keypad(information->KEYPAD, (Q931_info_t *) information, bc->keypad, sizeof(bc->keypad), nt, bc);
01548 
01549 #ifdef DEBUG
01550    printf("Parsing INFORMATION Msg\n");
01551 #endif
01552 }
01553 
01554 static msg_t *build_information (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
01555 {
01556    int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
01557    INFORMATION_t *information;
01558    msg_t *msg =(msg_t*)create_l3msg(CC_INFORMATION | REQUEST, MT_INFORMATION,  bc?bc->l3_id:-1, sizeof(INFORMATION_t) ,nt);
01559 
01560    information=(INFORMATION_t*)((msg->data+HEADER_LEN));
01561 
01562    enc_ie_called_pn(&information->CALLED_PN, msg, 0, 1, bc->info_dad, nt,bc);
01563 
01564    {
01565       if (*bc->display) {
01566 #ifdef DEBUG
01567          printf("Sending %s as Display\n", bc->display);
01568 #endif
01569          enc_ie_display(&information->DISPLAY, msg, bc->display, nt,bc);
01570       }
01571    }
01572 
01573 #ifdef DEBUG
01574    printf("Building INFORMATION Msg\n");
01575 #endif
01576    return msg;
01577 }
01578 
01579 static void parse_status (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
01580 {
01581    int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
01582    STATUS_t *status = (STATUS_t *) (msg->data + HEADER_LEN);
01583    int location;
01584    int cause;
01585 
01586    dec_ie_cause(status->CAUSE, (Q931_info_t *)(status), &location, &cause, nt,bc);
01587    if (cause>0) bc->cause=cause;
01588 
01589 #ifdef DEBUG
01590    printf("Parsing STATUS Msg\n");
01591 #endif
01592 }
01593 
01594 static msg_t *build_status (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
01595 {
01596    msg_t *msg =(msg_t*)create_l3msg(CC_STATUS | REQUEST, MT_STATUS,  bc?bc->l3_id:-1, sizeof(STATUS_t) ,nt);
01597 
01598 #ifdef DEBUG
01599    printf("Building STATUS Msg\n");
01600 #endif
01601    return msg;
01602 }
01603 
01604 static void parse_timeout (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
01605 {
01606 #ifdef DEBUG
01607    printf("Parsing STATUS Msg\n");
01608 #endif
01609 }
01610 
01611 static msg_t *build_timeout (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
01612 {
01613    msg_t *msg =(msg_t*)create_l3msg(CC_STATUS | REQUEST, MT_STATUS,  bc?bc->l3_id:-1, sizeof(STATUS_t) ,nt);
01614 
01615 #ifdef DEBUG
01616    printf("Building STATUS Msg\n");
01617 #endif
01618    return msg;
01619 }
01620 
01621 
01622 /************************************/
01623 
01624 
01625 
01626 
01627 /** Msg Array **/
01628 
01629 struct isdn_msg msgs_g[] = {
01630 /* *INDENT-OFF* */
01631    /* misdn_msg,               event,                      msg_parser,                 msg_builder,                info */
01632    { CC_PROCEEDING,            EVENT_PROCEEDING,           parse_proceeding,           build_proceeding,           "PROCEEDING" },
01633    { CC_ALERTING,              EVENT_ALERTING,             parse_alerting,             build_alerting,             "ALERTING" },
01634    { CC_PROGRESS,              EVENT_PROGRESS,             parse_progress,             build_progress,             "PROGRESS" },
01635    { CC_SETUP,                 EVENT_SETUP,                parse_setup,                build_setup,                "SETUP" },
01636 #if defined(AST_MISDN_ENHANCEMENTS)
01637    { CC_REGISTER,              EVENT_REGISTER,             parse_register,             build_register,             "REGISTER" },
01638 #endif   /* defined(AST_MISDN_ENHANCEMENTS) */
01639    { CC_CONNECT,               EVENT_CONNECT,              parse_connect,              build_connect,              "CONNECT" },
01640    { CC_SETUP_ACKNOWLEDGE,     EVENT_SETUP_ACKNOWLEDGE,    parse_setup_acknowledge,    build_setup_acknowledge,    "SETUP_ACKNOWLEDGE" },
01641    { CC_CONNECT_ACKNOWLEDGE,   EVENT_CONNECT_ACKNOWLEDGE,  parse_connect_acknowledge,  build_connect_acknowledge,  "CONNECT_ACKNOWLEDGE " },
01642    { CC_USER_INFORMATION,      EVENT_USER_INFORMATION,     parse_user_information,     build_user_information,     "USER_INFORMATION" },
01643    { CC_SUSPEND_REJECT,        EVENT_SUSPEND_REJECT,       parse_suspend_reject,       build_suspend_reject,       "SUSPEND_REJECT" },
01644    { CC_RESUME_REJECT,         EVENT_RESUME_REJECT,        parse_resume_reject,        build_resume_reject,        "RESUME_REJECT" },
01645    { CC_HOLD,                  EVENT_HOLD,                 parse_hold,                 build_hold,                 "HOLD" },
01646    { CC_SUSPEND,               EVENT_SUSPEND,              parse_suspend,              build_suspend,              "SUSPEND" },
01647    { CC_RESUME,                EVENT_RESUME,               parse_resume,               build_resume,               "RESUME" },
01648    { CC_HOLD_ACKNOWLEDGE,      EVENT_HOLD_ACKNOWLEDGE,     parse_hold_acknowledge,     build_hold_acknowledge,     "HOLD_ACKNOWLEDGE" },
01649    { CC_SUSPEND_ACKNOWLEDGE,   EVENT_SUSPEND_ACKNOWLEDGE,  parse_suspend_acknowledge,  build_suspend_acknowledge,  "SUSPEND_ACKNOWLEDGE" },
01650    { CC_RESUME_ACKNOWLEDGE,    EVENT_RESUME_ACKNOWLEDGE,   parse_resume_acknowledge,   build_resume_acknowledge,   "RESUME_ACKNOWLEDGE" },
01651    { CC_HOLD_REJECT,           EVENT_HOLD_REJECT,          parse_hold_reject,          build_hold_reject,          "HOLD_REJECT" },
01652    { CC_RETRIEVE,              EVENT_RETRIEVE,             parse_retrieve,             build_retrieve,             "RETRIEVE" },
01653    { CC_RETRIEVE_ACKNOWLEDGE,  EVENT_RETRIEVE_ACKNOWLEDGE, parse_retrieve_acknowledge, build_retrieve_acknowledge, "RETRIEVE_ACKNOWLEDGE" },
01654    { CC_RETRIEVE_REJECT,       EVENT_RETRIEVE_REJECT,      parse_retrieve_reject,      build_retrieve_reject,      "RETRIEVE_REJECT" },
01655    { CC_DISCONNECT,            EVENT_DISCONNECT,           parse_disconnect,           build_disconnect,           "DISCONNECT" },
01656    { CC_RESTART,               EVENT_RESTART,              parse_restart,              build_restart,              "RESTART" },
01657    { CC_RELEASE,               EVENT_RELEASE,              parse_release,              build_release,              "RELEASE" },
01658    { CC_RELEASE_COMPLETE,      EVENT_RELEASE_COMPLETE,     parse_release_complete,     build_release_complete,     "RELEASE_COMPLETE" },
01659    { CC_FACILITY,              EVENT_FACILITY,             parse_facility,             build_facility,             "FACILITY" },
01660    { CC_NOTIFY,                EVENT_NOTIFY,               parse_notify,               build_notify,               "NOTIFY" },
01661    { CC_STATUS_ENQUIRY,        EVENT_STATUS_ENQUIRY,       parse_status_enquiry,       build_status_enquiry,       "STATUS_ENQUIRY" },
01662    { CC_INFORMATION,           EVENT_INFORMATION,          parse_information,          build_information,          "INFORMATION" },
01663    { CC_STATUS,                EVENT_STATUS,               parse_status,               build_status,               "STATUS" },
01664    { CC_TIMEOUT,               EVENT_TIMEOUT,              parse_timeout,              build_timeout,              "TIMEOUT" },
01665    { 0, 0, NULL, NULL, NULL }
01666 /* *INDENT-ON* */
01667 };
01668 
01669 #define msgs_max (sizeof(msgs_g)/sizeof(struct isdn_msg))
01670 
01671 /** INTERFACE FCTS ***/
01672 int isdn_msg_get_index(struct isdn_msg msgs[], msg_t *msg, int nt)
01673 {
01674    int i;
01675 
01676    if (nt){
01677       mISDNuser_head_t *hh = (mISDNuser_head_t*)msg->data;
01678 
01679       for (i=0; i< msgs_max -1; i++) {
01680          if ( (hh->prim&COMMAND_MASK)==(msgs[i].misdn_msg&COMMAND_MASK)) return i;
01681       }
01682 
01683    } else {
01684       iframe_t *frm = (iframe_t*)msg->data;
01685 
01686       for (i=0; i< msgs_max -1; i++)
01687          if ( (frm->prim&COMMAND_MASK)==(msgs[i].misdn_msg&COMMAND_MASK)) return i;
01688    }
01689 
01690    return -1;
01691 }
01692 
01693 int isdn_msg_get_index_by_event(struct isdn_msg msgs[], enum event_e event, int nt)
01694 {
01695    int i;
01696    for (i=0; i< msgs_max; i++)
01697       if ( event == msgs[i].event) return i;
01698 
01699    cb_log(10,0, "get_index: event not found!\n");
01700 
01701    return -1;
01702 }
01703 
01704 enum event_e isdn_msg_get_event(struct isdn_msg msgs[], msg_t *msg, int nt)
01705 {
01706    int i=isdn_msg_get_index(msgs, msg, nt);
01707    if(i>=0) return msgs[i].event;
01708    return EVENT_UNKNOWN;
01709 }
01710 
01711 char * isdn_msg_get_info(struct isdn_msg msgs[], msg_t *msg, int nt)
01712 {
01713    int i=isdn_msg_get_index(msgs, msg, nt);
01714    if(i>=0) return msgs[i].info;
01715    return NULL;
01716 }
01717 
01718 
01719 char EVENT_CLEAN_INFO[] = "CLEAN_UP";
01720 char EVENT_DTMF_TONE_INFO[] = "DTMF_TONE";
01721 char EVENT_NEW_L3ID_INFO[] = "NEW_L3ID";
01722 char EVENT_NEW_BC_INFO[] = "NEW_BC";
01723 char EVENT_PORT_ALARM_INFO[] = "ALARM";
01724 char EVENT_NEW_CHANNEL_INFO[] = "NEW_CHANNEL";
01725 char EVENT_BCHAN_DATA_INFO[] = "BCHAN_DATA";
01726 char EVENT_BCHAN_ACTIVATED_INFO[] = "BCHAN_ACTIVATED";
01727 char EVENT_TONE_GENERATE_INFO[] = "TONE_GENERATE";
01728 char EVENT_BCHAN_ERROR_INFO[] = "BCHAN_ERROR";
01729 
01730 char * isdn_get_info(struct isdn_msg msgs[], enum event_e event, int nt)
01731 {
01732    int i=isdn_msg_get_index_by_event(msgs, event, nt);
01733 
01734    if(i>=0) return msgs[i].info;
01735 
01736    if (event == EVENT_CLEANUP) return EVENT_CLEAN_INFO;
01737    if (event == EVENT_DTMF_TONE) return EVENT_DTMF_TONE_INFO;
01738    if (event == EVENT_NEW_L3ID) return EVENT_NEW_L3ID_INFO;
01739    if (event == EVENT_NEW_BC) return EVENT_NEW_BC_INFO;
01740    if (event == EVENT_NEW_CHANNEL) return EVENT_NEW_CHANNEL_INFO;
01741    if (event == EVENT_BCHAN_DATA) return EVENT_BCHAN_DATA_INFO;
01742    if (event == EVENT_BCHAN_ACTIVATED) return EVENT_BCHAN_ACTIVATED_INFO;
01743    if (event == EVENT_TONE_GENERATE) return EVENT_TONE_GENERATE_INFO;
01744    if (event == EVENT_PORT_ALARM) return EVENT_PORT_ALARM_INFO;
01745    if (event == EVENT_BCHAN_ERROR) return EVENT_BCHAN_ERROR_INFO;
01746 
01747    return NULL;
01748 }
01749 
01750 int isdn_msg_parse_event(struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
01751 {
01752    int i=isdn_msg_get_index(msgs, msg, nt);
01753    if(i<0) return -1;
01754 
01755    msgs[i].msg_parser(msgs, msg, bc, nt);
01756    return 0;
01757 }
01758 
01759 msg_t * isdn_msg_build_event(struct isdn_msg msgs[], struct misdn_bchannel *bc, enum event_e event, int nt)
01760 {
01761    int i=isdn_msg_get_index_by_event(msgs, event, nt);
01762    if(i<0) return NULL;
01763 
01764    return  msgs[i].msg_builder(msgs, bc, nt);
01765 }

Generated on Sun May 20 06:33:54 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6