Mon Jun 27 16:50:54 2011

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    int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
00809    USER_INFORMATION_t *user_information;
00810    msg_t *msg =(msg_t*)create_l3msg(CC_USER_INFORMATION | REQUEST, MT_USER_INFORMATION,  bc?bc->l3_id:-1, sizeof(USER_INFORMATION_t) ,nt);
00811 
00812    user_information=(USER_INFORMATION_t*)((msg->data+HEADER_LEN));
00813 
00814 #ifdef DEBUG
00815    printf("Building USER_INFORMATION Msg\n");
00816 #endif
00817    return msg;
00818 }
00819 
00820 static void parse_suspend_reject (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
00821 {
00822 #ifdef DEBUG
00823    printf("Parsing SUSPEND_REJECT Msg\n");
00824 #endif
00825 
00826 
00827 }
00828 
00829 static msg_t *build_suspend_reject (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
00830 {
00831    int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
00832    SUSPEND_REJECT_t *suspend_reject;
00833    msg_t *msg =(msg_t*)create_l3msg(CC_SUSPEND_REJECT | REQUEST, MT_SUSPEND_REJECT,  bc?bc->l3_id:-1, sizeof(SUSPEND_REJECT_t) ,nt);
00834 
00835    suspend_reject=(SUSPEND_REJECT_t*)((msg->data+HEADER_LEN));
00836 
00837 #ifdef DEBUG
00838    printf("Building SUSPEND_REJECT Msg\n");
00839 #endif
00840    return msg;
00841 }
00842 
00843 static void parse_resume_reject (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
00844 {
00845 #ifdef DEBUG
00846    printf("Parsing RESUME_REJECT Msg\n");
00847 #endif
00848 
00849 
00850 }
00851 
00852 static msg_t *build_resume_reject (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
00853 {
00854    int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
00855    RESUME_REJECT_t *resume_reject;
00856    msg_t *msg =(msg_t*)create_l3msg(CC_RESUME_REJECT | REQUEST, MT_RESUME_REJECT,  bc?bc->l3_id:-1, sizeof(RESUME_REJECT_t) ,nt);
00857 
00858    resume_reject=(RESUME_REJECT_t*)((msg->data+HEADER_LEN));
00859 
00860 #ifdef DEBUG
00861    printf("Building RESUME_REJECT Msg\n");
00862 #endif
00863    return msg;
00864 }
00865 
00866 static void parse_hold (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
00867 {
00868 #ifdef DEBUG
00869    printf("Parsing HOLD Msg\n");
00870 #endif
00871 
00872 
00873 }
00874 
00875 static msg_t *build_hold (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
00876 {
00877    int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
00878    HOLD_t *hold;
00879    msg_t *msg =(msg_t*)create_l3msg(CC_HOLD | REQUEST, MT_HOLD,  bc?bc->l3_id:-1, sizeof(HOLD_t) ,nt);
00880 
00881    hold=(HOLD_t*)((msg->data+HEADER_LEN));
00882 
00883 #ifdef DEBUG
00884    printf("Building HOLD Msg\n");
00885 #endif
00886    return msg;
00887 }
00888 
00889 static void parse_suspend (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
00890 {
00891 #ifdef DEBUG
00892    printf("Parsing SUSPEND Msg\n");
00893 #endif
00894 
00895 
00896 }
00897 
00898 static msg_t *build_suspend (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
00899 {
00900    int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
00901    SUSPEND_t *suspend;
00902    msg_t *msg =(msg_t*)create_l3msg(CC_SUSPEND | REQUEST, MT_SUSPEND,  bc?bc->l3_id:-1, sizeof(SUSPEND_t) ,nt);
00903 
00904    suspend=(SUSPEND_t*)((msg->data+HEADER_LEN));
00905 
00906 #ifdef DEBUG
00907    printf("Building SUSPEND Msg\n");
00908 #endif
00909    return msg;
00910 }
00911 
00912 static void parse_resume (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
00913 {
00914 #ifdef DEBUG
00915    printf("Parsing RESUME Msg\n");
00916 #endif
00917 
00918 
00919 }
00920 
00921 static msg_t *build_resume (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
00922 {
00923    int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
00924    RESUME_t *resume;
00925    msg_t *msg =(msg_t*)create_l3msg(CC_RESUME | REQUEST, MT_RESUME,  bc?bc->l3_id:-1, sizeof(RESUME_t) ,nt);
00926 
00927    resume=(RESUME_t*)((msg->data+HEADER_LEN));
00928 
00929 #ifdef DEBUG
00930    printf("Building RESUME Msg\n");
00931 #endif
00932    return msg;
00933 }
00934 
00935 static void parse_hold_acknowledge (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
00936 {
00937 #ifdef DEBUG
00938    printf("Parsing HOLD_ACKNOWLEDGE Msg\n");
00939 #endif
00940 
00941 
00942 }
00943 
00944 static msg_t *build_hold_acknowledge (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
00945 {
00946    int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
00947    HOLD_ACKNOWLEDGE_t *hold_acknowledge;
00948    msg_t *msg =(msg_t*)create_l3msg(CC_HOLD_ACKNOWLEDGE | REQUEST, MT_HOLD_ACKNOWLEDGE,  bc?bc->l3_id:-1, sizeof(HOLD_ACKNOWLEDGE_t) ,nt);
00949 
00950    hold_acknowledge=(HOLD_ACKNOWLEDGE_t*)((msg->data+HEADER_LEN));
00951 
00952 #ifdef DEBUG
00953    printf("Building HOLD_ACKNOWLEDGE Msg\n");
00954 #endif
00955    return msg;
00956 }
00957 
00958 static void parse_suspend_acknowledge (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
00959 {
00960 #ifdef DEBUG
00961    printf("Parsing SUSPEND_ACKNOWLEDGE Msg\n");
00962 #endif
00963 
00964 
00965 }
00966 
00967 static msg_t *build_suspend_acknowledge (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
00968 {
00969    int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
00970    SUSPEND_ACKNOWLEDGE_t *suspend_acknowledge;
00971    msg_t *msg =(msg_t*)create_l3msg(CC_SUSPEND_ACKNOWLEDGE | REQUEST, MT_SUSPEND_ACKNOWLEDGE,  bc?bc->l3_id:-1, sizeof(SUSPEND_ACKNOWLEDGE_t) ,nt);
00972 
00973    suspend_acknowledge=(SUSPEND_ACKNOWLEDGE_t*)((msg->data+HEADER_LEN));
00974 
00975 #ifdef DEBUG
00976    printf("Building SUSPEND_ACKNOWLEDGE Msg\n");
00977 #endif
00978    return msg;
00979 }
00980 
00981 static void parse_resume_acknowledge (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
00982 {
00983 #ifdef DEBUG
00984    printf("Parsing RESUME_ACKNOWLEDGE Msg\n");
00985 #endif
00986 
00987 
00988 }
00989 
00990 static msg_t *build_resume_acknowledge (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
00991 {
00992    int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
00993    RESUME_ACKNOWLEDGE_t *resume_acknowledge;
00994    msg_t *msg =(msg_t*)create_l3msg(CC_RESUME_ACKNOWLEDGE | REQUEST, MT_RESUME_ACKNOWLEDGE,  bc?bc->l3_id:-1, sizeof(RESUME_ACKNOWLEDGE_t) ,nt);
00995 
00996    resume_acknowledge=(RESUME_ACKNOWLEDGE_t*)((msg->data+HEADER_LEN));
00997 
00998 #ifdef DEBUG
00999    printf("Building RESUME_ACKNOWLEDGE Msg\n");
01000 #endif
01001    return msg;
01002 }
01003 
01004 static void parse_hold_reject (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
01005 {
01006 #ifdef DEBUG
01007    printf("Parsing HOLD_REJECT Msg\n");
01008 #endif
01009 
01010 
01011 }
01012 
01013 static msg_t *build_hold_reject (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
01014 {
01015    int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
01016    HOLD_REJECT_t *hold_reject;
01017    msg_t *msg =(msg_t*)create_l3msg(CC_HOLD_REJECT | REQUEST, MT_HOLD_REJECT,  bc?bc->l3_id:-1, sizeof(HOLD_REJECT_t) ,nt);
01018 
01019    hold_reject=(HOLD_REJECT_t*)((msg->data+HEADER_LEN));
01020 
01021 #ifdef DEBUG
01022    printf("Building HOLD_REJECT Msg\n");
01023 #endif
01024    return msg;
01025 }
01026 
01027 static void parse_retrieve (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
01028 {
01029 #ifdef DEBUG
01030    printf("Parsing RETRIEVE Msg\n");
01031 #endif
01032 
01033 
01034 }
01035 
01036 static msg_t *build_retrieve (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
01037 {
01038    int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
01039    RETRIEVE_t *retrieve;
01040    msg_t *msg =(msg_t*)create_l3msg(CC_RETRIEVE | REQUEST, MT_RETRIEVE,  bc?bc->l3_id:-1, sizeof(RETRIEVE_t) ,nt);
01041 
01042    retrieve=(RETRIEVE_t*)((msg->data+HEADER_LEN));
01043 
01044 #ifdef DEBUG
01045    printf("Building RETRIEVE Msg\n");
01046 #endif
01047    return msg;
01048 }
01049 
01050 static void parse_retrieve_acknowledge (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
01051 {
01052 #ifdef DEBUG
01053    printf("Parsing RETRIEVE_ACKNOWLEDGE Msg\n");
01054 #endif
01055 
01056 
01057 }
01058 
01059 static msg_t *build_retrieve_acknowledge (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
01060 {
01061    int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
01062    RETRIEVE_ACKNOWLEDGE_t *retrieve_acknowledge;
01063    msg_t *msg =(msg_t*)create_l3msg(CC_RETRIEVE_ACKNOWLEDGE | REQUEST, MT_RETRIEVE_ACKNOWLEDGE,  bc?bc->l3_id:-1, sizeof(RETRIEVE_ACKNOWLEDGE_t) ,nt);
01064 
01065    retrieve_acknowledge=(RETRIEVE_ACKNOWLEDGE_t*)((msg->data+HEADER_LEN));
01066 
01067    enc_ie_channel_id(&retrieve_acknowledge->CHANNEL_ID, msg, 1, bc->channel, nt,bc);
01068 #ifdef DEBUG
01069    printf("Building RETRIEVE_ACKNOWLEDGE Msg\n");
01070 #endif
01071    return msg;
01072 }
01073 
01074 static void parse_retrieve_reject (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
01075 {
01076 #ifdef DEBUG
01077    printf("Parsing RETRIEVE_REJECT Msg\n");
01078 #endif
01079 
01080 
01081 }
01082 
01083 static msg_t *build_retrieve_reject (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
01084 {
01085    int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
01086    RETRIEVE_REJECT_t *retrieve_reject;
01087    msg_t *msg =(msg_t*)create_l3msg(CC_RETRIEVE_REJECT | REQUEST, MT_RETRIEVE_REJECT,  bc?bc->l3_id:-1, sizeof(RETRIEVE_REJECT_t) ,nt);
01088 
01089    retrieve_reject=(RETRIEVE_REJECT_t*)((msg->data+HEADER_LEN));
01090 
01091 #ifdef DEBUG
01092    printf("Building RETRIEVE_REJECT Msg\n");
01093 #endif
01094    return msg;
01095 }
01096 
01097 static void parse_disconnect (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    DISCONNECT_t *disconnect = (DISCONNECT_t *) (msg->data + HEADER_LEN);
01101    int location;
01102    int cause;
01103    dec_ie_cause(disconnect->CAUSE, (Q931_info_t *)(disconnect), &location, &cause, nt,bc);
01104    if (cause>0) bc->cause=cause;
01105 
01106    dec_ie_facility(disconnect->FACILITY, (Q931_info_t *) disconnect, &bc->fac_in, nt, bc);
01107 
01108    dec_ie_progress(disconnect->PROGRESS, (Q931_info_t *)disconnect, &bc->progress_coding, &bc->progress_location, &bc->progress_indicator, nt, bc);
01109 #ifdef DEBUG
01110    printf("Parsing DISCONNECT Msg\n");
01111 #endif
01112 
01113 
01114 }
01115 
01116 static msg_t *build_disconnect (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
01117 {
01118    int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
01119    DISCONNECT_t *disconnect;
01120    msg_t *msg =(msg_t*)create_l3msg(CC_DISCONNECT | REQUEST, MT_DISCONNECT,  bc?bc->l3_id:-1, sizeof(DISCONNECT_t) ,nt);
01121 
01122    disconnect=(DISCONNECT_t*)((msg->data+HEADER_LEN));
01123 
01124    enc_ie_cause(&disconnect->CAUSE, msg, (nt)?1:0, bc->out_cause,nt,bc);
01125    if (nt) {
01126       enc_ie_progress(&disconnect->PROGRESS, msg, 0, nt ? 1 : 5, 8, nt, bc);
01127    }
01128 
01129    if (bc->fac_out.Function != Fac_None) {
01130       enc_ie_facility(&disconnect->FACILITY, msg, &bc->fac_out, nt);
01131    }
01132 
01133    if (bc->uulen) {
01134       int  protocol=4;
01135       enc_ie_useruser(&disconnect->USER_USER, msg, protocol, bc->uu, bc->uulen, nt,bc);
01136       cb_log(1,bc->port,"ENCODING USERUESRINFO:%s\n",bc->uu);
01137    }
01138 
01139 #ifdef DEBUG
01140    printf("Building DISCONNECT Msg\n");
01141 #endif
01142    return msg;
01143 }
01144 
01145 static void parse_restart (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
01146 {
01147    int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
01148    RESTART_t *restart = (RESTART_t *) (msg->data + HEADER_LEN);
01149 
01150    struct misdn_stack *stack=get_stack_by_bc(bc);
01151 
01152 #ifdef DEBUG
01153    printf("Parsing RESTART Msg\n");
01154 #endif
01155 
01156    {
01157       int  exclusive;
01158       dec_ie_channel_id(restart->CHANNEL_ID, (Q931_info_t *)restart, &exclusive, &bc->restart_channel, nt,bc);
01159       cb_log(3, stack->port, "CC_RESTART Request on channel:%d on this port.\n", bc->restart_channel);
01160    }
01161 
01162 }
01163 
01164 static msg_t *build_restart (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
01165 {
01166    int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
01167    RESTART_t *restart;
01168    msg_t *msg =(msg_t*)create_l3msg(CC_RESTART | REQUEST, MT_RESTART,  bc?bc->l3_id:-1, sizeof(RESTART_t) ,nt);
01169 
01170    restart=(RESTART_t*)((msg->data+HEADER_LEN));
01171 
01172 #ifdef DEBUG
01173    printf("Building RESTART Msg\n");
01174 #endif
01175 
01176    if (bc->channel > 0) {
01177       enc_ie_channel_id(&restart->CHANNEL_ID, msg, 1,bc->channel, nt,bc);
01178       enc_ie_restart_ind(&restart->RESTART_IND, msg, 0x80, nt, bc);
01179    } else {
01180       enc_ie_restart_ind(&restart->RESTART_IND, msg, 0x87, nt, bc);
01181    }
01182 
01183    cb_log(0,bc->port, "Restarting channel %d\n", bc->channel);
01184    return msg;
01185 }
01186 
01187 static void parse_release (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
01188 {
01189    int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
01190    RELEASE_t *release = (RELEASE_t *) (msg->data + HEADER_LEN);
01191    int location;
01192    int cause;
01193 
01194    dec_ie_cause(release->CAUSE, (Q931_info_t *)(release), &location, &cause, nt,bc);
01195    if (cause>0) bc->cause=cause;
01196 
01197    dec_ie_facility(release->FACILITY, (Q931_info_t *) release, &bc->fac_in, nt, bc);
01198 
01199 #ifdef DEBUG
01200    printf("Parsing RELEASE Msg\n");
01201 #endif
01202 
01203 
01204 }
01205 
01206 static msg_t *build_release (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
01207 {
01208    int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
01209    RELEASE_t *release;
01210    msg_t *msg =(msg_t*)create_l3msg(CC_RELEASE | REQUEST, MT_RELEASE,  bc?bc->l3_id:-1, sizeof(RELEASE_t) ,nt);
01211 
01212    release=(RELEASE_t*)((msg->data+HEADER_LEN));
01213 
01214    if (bc->out_cause>= 0)
01215       enc_ie_cause(&release->CAUSE, msg, nt?1:0, bc->out_cause, nt,bc);
01216 
01217    if (bc->fac_out.Function != Fac_None) {
01218       enc_ie_facility(&release->FACILITY, msg, &bc->fac_out, nt);
01219    }
01220 
01221    if (bc->uulen) {
01222       int  protocol=4;
01223       enc_ie_useruser(&release->USER_USER, msg, protocol, bc->uu, bc->uulen, nt,bc);
01224       cb_log(1,bc->port,"ENCODING USERUESRINFO:%s\n",bc->uu);
01225    }
01226 
01227 #ifdef DEBUG
01228    printf("Building RELEASE Msg\n");
01229 #endif
01230    return msg;
01231 }
01232 
01233 static void parse_release_complete (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
01234 {
01235    int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
01236    RELEASE_COMPLETE_t *release_complete = (RELEASE_COMPLETE_t *) (msg->data + HEADER_LEN);
01237    int location;
01238    int cause;
01239    iframe_t *frm = (iframe_t*) msg->data;
01240 
01241    struct misdn_stack *stack=get_stack_by_bc(bc);
01242    mISDNuser_head_t *hh;
01243    hh=(mISDNuser_head_t*)msg->data;
01244 
01245    /*hh=(mISDN_head_t*)msg->data;
01246    mISDN_head_t *hh;*/
01247 
01248    if (nt) {
01249       if (hh->prim == (CC_RELEASE_COMPLETE|CONFIRM)) {
01250          cb_log(0, stack->port, "CC_RELEASE_COMPLETE|CONFIRM [NT] \n");
01251          return;
01252       }
01253    } else {
01254       if (frm->prim == (CC_RELEASE_COMPLETE|CONFIRM)) {
01255          cb_log(0, stack->port, "CC_RELEASE_COMPLETE|CONFIRM [TE] \n");
01256          return;
01257       }
01258    }
01259    dec_ie_cause(release_complete->CAUSE, (Q931_info_t *)(release_complete), &location, &cause, nt,bc);
01260    if (cause>0) bc->cause=cause;
01261 
01262    dec_ie_facility(release_complete->FACILITY, (Q931_info_t *) release_complete, &bc->fac_in, nt, bc);
01263 
01264 #ifdef DEBUG
01265    printf("Parsing RELEASE_COMPLETE Msg\n");
01266 #endif
01267 }
01268 
01269 static msg_t *build_release_complete (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
01270 {
01271    int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
01272    RELEASE_COMPLETE_t *release_complete;
01273    msg_t *msg =(msg_t*)create_l3msg(CC_RELEASE_COMPLETE | REQUEST, MT_RELEASE_COMPLETE,  bc?bc->l3_id:-1, sizeof(RELEASE_COMPLETE_t) ,nt);
01274 
01275    release_complete=(RELEASE_COMPLETE_t*)((msg->data+HEADER_LEN));
01276 
01277    enc_ie_cause(&release_complete->CAUSE, msg, nt?1:0, bc->out_cause, nt,bc);
01278 
01279    if (bc->fac_out.Function != Fac_None) {
01280       enc_ie_facility(&release_complete->FACILITY, msg, &bc->fac_out, nt);
01281    }
01282 
01283    if (bc->uulen) {
01284       int  protocol=4;
01285       enc_ie_useruser(&release_complete->USER_USER, msg, protocol, bc->uu, bc->uulen, nt,bc);
01286       cb_log(1,bc->port,"ENCODING USERUESRINFO:%s\n",bc->uu);
01287    }
01288 
01289 #ifdef DEBUG
01290    printf("Building RELEASE_COMPLETE Msg\n");
01291 #endif
01292    return msg;
01293 }
01294 
01295 static void parse_facility (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
01296 {
01297    int HEADER_LEN = nt ? mISDNUSER_HEAD_SIZE : mISDN_HEADER_LEN;
01298    FACILITY_t *facility = (FACILITY_t*)(msg->data+HEADER_LEN);
01299    Q931_info_t *qi = (Q931_info_t*)(msg->data+HEADER_LEN);
01300    unsigned char *p = NULL;
01301 #if defined(AST_MISDN_ENHANCEMENTS)
01302    int description_code;
01303    int type;
01304    int plan;
01305    int present;
01306    char number[sizeof(bc->redirecting.to.number)];
01307 #endif   /* defined(AST_MISDN_ENHANCEMENTS) */
01308 
01309 #ifdef DEBUG
01310    printf("Parsing FACILITY Msg\n");
01311 #endif
01312 
01313    bc->fac_in.Function = Fac_None;
01314 
01315    if (!bc->nt) {
01316       if (qi->QI_ELEMENT(facility))
01317          p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(facility) + 1;
01318    } else {
01319       p = facility->FACILITY;
01320    }
01321    if (!p)
01322       return;
01323 
01324    if (decodeFac(p, &bc->fac_in)) {
01325       cb_log(3, bc->port, "Decoding facility ie failed! Unrecognized facility message?\n");
01326    }
01327 
01328 #if defined(AST_MISDN_ENHANCEMENTS)
01329    dec_ie_notify(facility->NOTIFY, qi, &description_code, nt, bc);
01330    if (description_code < 0) {
01331       bc->notify_description_code = mISDN_NOTIFY_CODE_INVALID;
01332    } else {
01333       bc->notify_description_code = description_code;
01334    }
01335 
01336    dec_ie_redir_dn(facility->REDIR_DN, qi, &type, &plan, &present, number, sizeof(number), nt, bc);
01337    if (0 <= type) {
01338       bc->redirecting.to_changed = 1;
01339 
01340       bc->redirecting.to.number_type = type;
01341       bc->redirecting.to.number_plan = plan;
01342       switch (present) {
01343       default:
01344       case 0:
01345          bc->redirecting.to.presentation = 0;   /* presentation allowed */
01346          break;
01347       case 1:
01348          bc->redirecting.to.presentation = 1;   /* presentation restricted */
01349          break;
01350       case 2:
01351          bc->redirecting.to.presentation = 2;   /* Number not available */
01352          break;
01353       }
01354       bc->redirecting.to.screening = 0;   /* Unscreened */
01355       strcpy(bc->redirecting.to.number, number);
01356    }
01357 #endif   /* defined(AST_MISDN_ENHANCEMENTS) */
01358 }
01359 
01360 static msg_t *build_facility (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
01361 {
01362    int len;
01363    int HEADER_LEN;
01364    unsigned char *ie_fac;
01365    unsigned char fac_tmp[256];
01366    msg_t *msg;
01367    FACILITY_t *facility;
01368    Q931_info_t *qi;
01369 
01370 #ifdef DEBUG
01371    printf("Building FACILITY Msg\n");
01372 #endif
01373 
01374    len = encodeFac(fac_tmp, &(bc->fac_out));
01375    if (len <= 0) {
01376       /*
01377        * mISDN does not know how to build the requested facility structure
01378        * Clear facility information
01379        */
01380       bc->fac_out.Function = Fac_None;
01381 
01382 #if defined(AST_MISDN_ENHANCEMENTS)
01383       /* Clear other one shot information. */
01384       bc->notify_description_code = mISDN_NOTIFY_CODE_INVALID;
01385       bc->redirecting.to_changed = 0;
01386 #endif   /* defined(AST_MISDN_ENHANCEMENTS) */
01387       return NULL;
01388    }
01389 
01390    msg = (msg_t *) create_l3msg(CC_FACILITY | REQUEST, MT_FACILITY, bc ? bc->l3_id : -1, sizeof(FACILITY_t), nt);
01391    HEADER_LEN = nt ? mISDNUSER_HEAD_SIZE : mISDN_HEADER_LEN;
01392    facility = (FACILITY_t *) (msg->data + HEADER_LEN);
01393 
01394    ie_fac = msg_put(msg, len);
01395    if (bc->nt) {
01396       facility->FACILITY = ie_fac + 1;
01397    } else {
01398       qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
01399       qi->QI_ELEMENT(facility) = ie_fac - (unsigned char *)qi - sizeof(Q931_info_t);
01400    }
01401 
01402    memcpy(ie_fac, fac_tmp, len);
01403 
01404    /* Clear facility information */
01405    bc->fac_out.Function = Fac_None;
01406 
01407    if (*bc->display) {
01408 #ifdef DEBUG
01409       printf("Sending %s as Display\n", bc->display);
01410 #endif
01411       enc_ie_display(&facility->DISPLAY, msg, bc->display, nt,bc);
01412    }
01413 
01414 #if defined(AST_MISDN_ENHANCEMENTS)
01415    if (bc->notify_description_code != mISDN_NOTIFY_CODE_INVALID) {
01416       enc_ie_notify(&facility->NOTIFY, msg, bc->notify_description_code, nt, bc);
01417       bc->notify_description_code = mISDN_NOTIFY_CODE_INVALID;
01418    }
01419 
01420    if (bc->redirecting.to_changed) {
01421       bc->redirecting.to_changed = 0;
01422       switch (bc->outgoing_colp) {
01423       case 0:/* pass */
01424       case 1:/* restricted */
01425          enc_ie_redir_dn(&facility->REDIR_DN, msg, bc->redirecting.to.number_type,
01426             bc->redirecting.to.number_plan, bc->redirecting.to.presentation,
01427             bc->redirecting.to.number, nt, bc);
01428          break;
01429       default:
01430          break;
01431       }
01432    }
01433 #endif   /* defined(AST_MISDN_ENHANCEMENTS) */
01434 
01435    return msg;
01436 }
01437 
01438 #if defined(AST_MISDN_ENHANCEMENTS)
01439 /*!
01440  * \internal
01441  * \brief Parse a received REGISTER message
01442  *
01443  * \param msgs Search table entry that called us.
01444  * \param msg Received message contents
01445  * \param bc Associated B channel
01446  * \param nt TRUE if in NT mode.
01447  *
01448  * \return Nothing
01449  */
01450 static void parse_register(struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
01451 {
01452    int HEADER_LEN;
01453    REGISTER_t *reg;
01454 
01455    HEADER_LEN = nt ? mISDNUSER_HEAD_SIZE : mISDN_HEADER_LEN;
01456    reg = (REGISTER_t *) (msg->data + HEADER_LEN);
01457 
01458    /*
01459     * A facility ie is optional.
01460     * The peer may just be establishing a connection to send
01461     * messages later.
01462     */
01463    dec_ie_facility(reg->FACILITY, (Q931_info_t *) reg, &bc->fac_in, nt, bc);
01464 }
01465 #endif   /* defined(AST_MISDN_ENHANCEMENTS) */
01466 
01467 #if defined(AST_MISDN_ENHANCEMENTS)
01468 /*!
01469  * \internal
01470  * \brief Construct a REGISTER message
01471  *
01472  * \param msgs Search table entry that called us.
01473  * \param bc Associated B channel
01474  * \param nt TRUE if in NT mode.
01475  *
01476  * \return Allocated built message
01477  */
01478 static msg_t *build_register(struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
01479 {
01480    int HEADER_LEN;
01481    REGISTER_t *reg;
01482    msg_t *msg;
01483 
01484    msg = (msg_t *) create_l3msg(CC_REGISTER | REQUEST, MT_REGISTER,  bc ? bc->l3_id : -1, sizeof(REGISTER_t), nt);
01485    HEADER_LEN = nt ? mISDNUSER_HEAD_SIZE : mISDN_HEADER_LEN;
01486    reg = (REGISTER_t *) (msg->data + HEADER_LEN);
01487 
01488    if (bc->fac_out.Function != Fac_None) {
01489       enc_ie_facility(&reg->FACILITY, msg, &bc->fac_out, nt);
01490    }
01491 
01492    return msg;
01493 }
01494 #endif   /* defined(AST_MISDN_ENHANCEMENTS) */
01495 
01496 static void parse_notify (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
01497 {
01498    int HEADER_LEN = nt ? mISDNUSER_HEAD_SIZE : mISDN_HEADER_LEN;
01499    NOTIFY_t *notify = (NOTIFY_t *) (msg->data + HEADER_LEN);
01500    int description_code;
01501    int type;
01502    int plan;
01503    int present;
01504    char number[sizeof(bc->redirecting.to.number)];
01505 
01506 #ifdef DEBUG
01507    printf("Parsing NOTIFY Msg\n");
01508 #endif
01509 
01510    dec_ie_notify(notify->NOTIFY, (Q931_info_t *) notify, &description_code, nt, bc);
01511    if (description_code < 0) {
01512       bc->notify_description_code = mISDN_NOTIFY_CODE_INVALID;
01513    } else {
01514       bc->notify_description_code = description_code;
01515    }
01516 
01517    dec_ie_redir_dn(notify->REDIR_DN, (Q931_info_t *) notify, &type, &plan, &present, number, sizeof(number), nt, bc);
01518    if (0 <= type) {
01519       bc->redirecting.to_changed = 1;
01520 
01521       bc->redirecting.to.number_type = type;
01522       bc->redirecting.to.number_plan = plan;
01523       switch (present) {
01524       default:
01525       case 0:
01526          bc->redirecting.to.presentation = 0;   /* presentation allowed */
01527          break;
01528       case 1:
01529          bc->redirecting.to.presentation = 1;   /* presentation restricted */
01530          break;
01531       case 2:
01532          bc->redirecting.to.presentation = 2;   /* Number not available */
01533          break;
01534       }
01535       bc->redirecting.to.screening = 0;   /* Unscreened */
01536       strcpy(bc->redirecting.to.number, number);
01537    }
01538 }
01539 
01540 static msg_t *build_notify (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
01541 {
01542    int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
01543    NOTIFY_t *notify;
01544    msg_t *msg =(msg_t*)create_l3msg(CC_NOTIFY | REQUEST, MT_NOTIFY,  bc?bc->l3_id:-1, sizeof(NOTIFY_t) ,nt);
01545 
01546 #ifdef DEBUG
01547    printf("Building NOTIFY Msg\n");
01548 #endif
01549 
01550    notify = (NOTIFY_t *) (msg->data + HEADER_LEN);
01551 
01552    enc_ie_notify(&notify->NOTIFY, msg, bc->notify_description_code, nt, bc);
01553    bc->notify_description_code = mISDN_NOTIFY_CODE_INVALID;
01554 
01555    if (bc->redirecting.to_changed) {
01556       bc->redirecting.to_changed = 0;
01557       switch (bc->outgoing_colp) {
01558       case 0:/* pass */
01559       case 1:/* restricted */
01560          enc_ie_redir_dn(&notify->REDIR_DN, msg, bc->redirecting.to.number_type,
01561             bc->redirecting.to.number_plan, bc->redirecting.to.presentation,
01562             bc->redirecting.to.number, nt, bc);
01563          break;
01564       default:
01565          break;
01566       }
01567    }
01568    return msg;
01569 }
01570 
01571 static void parse_status_enquiry (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
01572 {
01573 #ifdef DEBUG
01574    printf("Parsing STATUS_ENQUIRY Msg\n");
01575 #endif
01576 }
01577 
01578 static msg_t *build_status_enquiry (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
01579 {
01580    int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
01581    STATUS_ENQUIRY_t *status_enquiry;
01582    msg_t *msg =(msg_t*)create_l3msg(CC_STATUS_ENQUIRY | REQUEST, MT_STATUS_ENQUIRY,  bc?bc->l3_id:-1, sizeof(STATUS_ENQUIRY_t) ,nt);
01583 
01584    status_enquiry=(STATUS_ENQUIRY_t*)((msg->data+HEADER_LEN));
01585 
01586 #ifdef DEBUG
01587    printf("Building STATUS_ENQUIRY Msg\n");
01588 #endif
01589    return msg;
01590 }
01591 
01592 static void parse_information (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
01593 {
01594    int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
01595    INFORMATION_t *information = (INFORMATION_t *) (msg->data + HEADER_LEN);
01596    int type, plan;
01597 
01598    dec_ie_called_pn(information->CALLED_PN, (Q931_info_t *) information, &type, &plan, bc->info_dad, sizeof(bc->info_dad), nt, bc);
01599    dec_ie_keypad(information->KEYPAD, (Q931_info_t *) information, bc->keypad, sizeof(bc->keypad), nt, bc);
01600 
01601 #ifdef DEBUG
01602    printf("Parsing INFORMATION Msg\n");
01603 #endif
01604 }
01605 
01606 static msg_t *build_information (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
01607 {
01608    int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
01609    INFORMATION_t *information;
01610    msg_t *msg =(msg_t*)create_l3msg(CC_INFORMATION | REQUEST, MT_INFORMATION,  bc?bc->l3_id:-1, sizeof(INFORMATION_t) ,nt);
01611 
01612    information=(INFORMATION_t*)((msg->data+HEADER_LEN));
01613 
01614    enc_ie_called_pn(&information->CALLED_PN, msg, 0, 1, bc->info_dad, nt,bc);
01615 
01616    {
01617       if (*bc->display) {
01618 #ifdef DEBUG
01619          printf("Sending %s as Display\n", bc->display);
01620 #endif
01621          enc_ie_display(&information->DISPLAY, msg, bc->display, nt,bc);
01622       }
01623    }
01624 
01625 #ifdef DEBUG
01626    printf("Building INFORMATION Msg\n");
01627 #endif
01628    return msg;
01629 }
01630 
01631 static void parse_status (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
01632 {
01633    int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
01634    STATUS_t *status = (STATUS_t *) (msg->data + HEADER_LEN);
01635    int location;
01636    int cause;
01637 
01638    dec_ie_cause(status->CAUSE, (Q931_info_t *)(status), &location, &cause, nt,bc);
01639    if (cause>0) bc->cause=cause;
01640 
01641 #ifdef DEBUG
01642    printf("Parsing STATUS Msg\n");
01643 #endif
01644 }
01645 
01646 static msg_t *build_status (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
01647 {
01648    int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
01649    STATUS_t *status;
01650    msg_t *msg =(msg_t*)create_l3msg(CC_STATUS | REQUEST, MT_STATUS,  bc?bc->l3_id:-1, sizeof(STATUS_t) ,nt);
01651 
01652    status=(STATUS_t*)((msg->data+HEADER_LEN));
01653 
01654 #ifdef DEBUG
01655    printf("Building STATUS Msg\n");
01656 #endif
01657    return msg;
01658 }
01659 
01660 static void parse_timeout (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
01661 {
01662 #ifdef DEBUG
01663    printf("Parsing STATUS Msg\n");
01664 #endif
01665 }
01666 
01667 static msg_t *build_timeout (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
01668 {
01669    int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
01670    STATUS_t *status;
01671    msg_t *msg =(msg_t*)create_l3msg(CC_STATUS | REQUEST, MT_STATUS,  bc?bc->l3_id:-1, sizeof(STATUS_t) ,nt);
01672 
01673    status=(STATUS_t*)((msg->data+HEADER_LEN));
01674 
01675 #ifdef DEBUG
01676    printf("Building STATUS Msg\n");
01677 #endif
01678    return msg;
01679 }
01680 
01681 
01682 /************************************/
01683 
01684 
01685 
01686 
01687 /** Msg Array **/
01688 
01689 struct isdn_msg msgs_g[] = {
01690 /* *INDENT-OFF* */
01691    /* misdn_msg,               event,                      msg_parser,                 msg_builder,                info */
01692    { CC_PROCEEDING,            EVENT_PROCEEDING,           parse_proceeding,           build_proceeding,           "PROCEEDING" },
01693    { CC_ALERTING,              EVENT_ALERTING,             parse_alerting,             build_alerting,             "ALERTING" },
01694    { CC_PROGRESS,              EVENT_PROGRESS,             parse_progress,             build_progress,             "PROGRESS" },
01695    { CC_SETUP,                 EVENT_SETUP,                parse_setup,                build_setup,                "SETUP" },
01696 #if defined(AST_MISDN_ENHANCEMENTS)
01697    { CC_REGISTER,              EVENT_REGISTER,             parse_register,             build_register,             "REGISTER" },
01698 #endif   /* defined(AST_MISDN_ENHANCEMENTS) */
01699    { CC_CONNECT,               EVENT_CONNECT,              parse_connect,              build_connect,              "CONNECT" },
01700    { CC_SETUP_ACKNOWLEDGE,     EVENT_SETUP_ACKNOWLEDGE,    parse_setup_acknowledge,    build_setup_acknowledge,    "SETUP_ACKNOWLEDGE" },
01701    { CC_CONNECT_ACKNOWLEDGE,   EVENT_CONNECT_ACKNOWLEDGE,  parse_connect_acknowledge,  build_connect_acknowledge,  "CONNECT_ACKNOWLEDGE " },
01702    { CC_USER_INFORMATION,      EVENT_USER_INFORMATION,     parse_user_information,     build_user_information,     "USER_INFORMATION" },
01703    { CC_SUSPEND_REJECT,        EVENT_SUSPEND_REJECT,       parse_suspend_reject,       build_suspend_reject,       "SUSPEND_REJECT" },
01704    { CC_RESUME_REJECT,         EVENT_RESUME_REJECT,        parse_resume_reject,        build_resume_reject,        "RESUME_REJECT" },
01705    { CC_HOLD,                  EVENT_HOLD,                 parse_hold,                 build_hold,                 "HOLD" },
01706    { CC_SUSPEND,               EVENT_SUSPEND,              parse_suspend,              build_suspend,              "SUSPEND" },
01707    { CC_RESUME,                EVENT_RESUME,               parse_resume,               build_resume,               "RESUME" },
01708    { CC_HOLD_ACKNOWLEDGE,      EVENT_HOLD_ACKNOWLEDGE,     parse_hold_acknowledge,     build_hold_acknowledge,     "HOLD_ACKNOWLEDGE" },
01709    { CC_SUSPEND_ACKNOWLEDGE,   EVENT_SUSPEND_ACKNOWLEDGE,  parse_suspend_acknowledge,  build_suspend_acknowledge,  "SUSPEND_ACKNOWLEDGE" },
01710    { CC_RESUME_ACKNOWLEDGE,    EVENT_RESUME_ACKNOWLEDGE,   parse_resume_acknowledge,   build_resume_acknowledge,   "RESUME_ACKNOWLEDGE" },
01711    { CC_HOLD_REJECT,           EVENT_HOLD_REJECT,          parse_hold_reject,          build_hold_reject,          "HOLD_REJECT" },
01712    { CC_RETRIEVE,              EVENT_RETRIEVE,             parse_retrieve,             build_retrieve,             "RETRIEVE" },
01713    { CC_RETRIEVE_ACKNOWLEDGE,  EVENT_RETRIEVE_ACKNOWLEDGE, parse_retrieve_acknowledge, build_retrieve_acknowledge, "RETRIEVE_ACKNOWLEDGE" },
01714    { CC_RETRIEVE_REJECT,       EVENT_RETRIEVE_REJECT,      parse_retrieve_reject,      build_retrieve_reject,      "RETRIEVE_REJECT" },
01715    { CC_DISCONNECT,            EVENT_DISCONNECT,           parse_disconnect,           build_disconnect,           "DISCONNECT" },
01716    { CC_RESTART,               EVENT_RESTART,              parse_restart,              build_restart,              "RESTART" },
01717    { CC_RELEASE,               EVENT_RELEASE,              parse_release,              build_release,              "RELEASE" },
01718    { CC_RELEASE_COMPLETE,      EVENT_RELEASE_COMPLETE,     parse_release_complete,     build_release_complete,     "RELEASE_COMPLETE" },
01719    { CC_FACILITY,              EVENT_FACILITY,             parse_facility,             build_facility,             "FACILITY" },
01720    { CC_NOTIFY,                EVENT_NOTIFY,               parse_notify,               build_notify,               "NOTIFY" },
01721    { CC_STATUS_ENQUIRY,        EVENT_STATUS_ENQUIRY,       parse_status_enquiry,       build_status_enquiry,       "STATUS_ENQUIRY" },
01722    { CC_INFORMATION,           EVENT_INFORMATION,          parse_information,          build_information,          "INFORMATION" },
01723    { CC_STATUS,                EVENT_STATUS,               parse_status,               build_status,               "STATUS" },
01724    { CC_TIMEOUT,               EVENT_TIMEOUT,              parse_timeout,              build_timeout,              "TIMEOUT" },
01725    { 0, 0, NULL, NULL, NULL }
01726 /* *INDENT-ON* */
01727 };
01728 
01729 #define msgs_max (sizeof(msgs_g)/sizeof(struct isdn_msg))
01730 
01731 /** INTERFACE FCTS ***/
01732 int isdn_msg_get_index(struct isdn_msg msgs[], msg_t *msg, int nt)
01733 {
01734    int i;
01735 
01736    if (nt){
01737       mISDNuser_head_t *hh = (mISDNuser_head_t*)msg->data;
01738 
01739       for (i=0; i< msgs_max -1; i++) {
01740          if ( (hh->prim&COMMAND_MASK)==(msgs[i].misdn_msg&COMMAND_MASK)) return i;
01741       }
01742 
01743    } else {
01744       iframe_t *frm = (iframe_t*)msg->data;
01745 
01746       for (i=0; i< msgs_max -1; i++)
01747          if ( (frm->prim&COMMAND_MASK)==(msgs[i].misdn_msg&COMMAND_MASK)) return i;
01748    }
01749 
01750    return -1;
01751 }
01752 
01753 int isdn_msg_get_index_by_event(struct isdn_msg msgs[], enum event_e event, int nt)
01754 {
01755    int i;
01756    for (i=0; i< msgs_max; i++)
01757       if ( event == msgs[i].event) return i;
01758 
01759    cb_log(10,0, "get_index: event not found!\n");
01760 
01761    return -1;
01762 }
01763 
01764 enum event_e isdn_msg_get_event(struct isdn_msg msgs[], msg_t *msg, int nt)
01765 {
01766    int i=isdn_msg_get_index(msgs, msg, nt);
01767    if(i>=0) return msgs[i].event;
01768    return EVENT_UNKNOWN;
01769 }
01770 
01771 char * isdn_msg_get_info(struct isdn_msg msgs[], msg_t *msg, int nt)
01772 {
01773    int i=isdn_msg_get_index(msgs, msg, nt);
01774    if(i>=0) return msgs[i].info;
01775    return NULL;
01776 }
01777 
01778 
01779 char EVENT_CLEAN_INFO[] = "CLEAN_UP";
01780 char EVENT_DTMF_TONE_INFO[] = "DTMF_TONE";
01781 char EVENT_NEW_L3ID_INFO[] = "NEW_L3ID";
01782 char EVENT_NEW_BC_INFO[] = "NEW_BC";
01783 char EVENT_PORT_ALARM_INFO[] = "ALARM";
01784 char EVENT_NEW_CHANNEL_INFO[] = "NEW_CHANNEL";
01785 char EVENT_BCHAN_DATA_INFO[] = "BCHAN_DATA";
01786 char EVENT_BCHAN_ACTIVATED_INFO[] = "BCHAN_ACTIVATED";
01787 char EVENT_TONE_GENERATE_INFO[] = "TONE_GENERATE";
01788 char EVENT_BCHAN_ERROR_INFO[] = "BCHAN_ERROR";
01789 
01790 char * isdn_get_info(struct isdn_msg msgs[], enum event_e event, int nt)
01791 {
01792    int i=isdn_msg_get_index_by_event(msgs, event, nt);
01793 
01794    if(i>=0) return msgs[i].info;
01795 
01796    if (event == EVENT_CLEANUP) return EVENT_CLEAN_INFO;
01797    if (event == EVENT_DTMF_TONE) return EVENT_DTMF_TONE_INFO;
01798    if (event == EVENT_NEW_L3ID) return EVENT_NEW_L3ID_INFO;
01799    if (event == EVENT_NEW_BC) return EVENT_NEW_BC_INFO;
01800    if (event == EVENT_NEW_CHANNEL) return EVENT_NEW_CHANNEL_INFO;
01801    if (event == EVENT_BCHAN_DATA) return EVENT_BCHAN_DATA_INFO;
01802    if (event == EVENT_BCHAN_ACTIVATED) return EVENT_BCHAN_ACTIVATED_INFO;
01803    if (event == EVENT_TONE_GENERATE) return EVENT_TONE_GENERATE_INFO;
01804    if (event == EVENT_PORT_ALARM) return EVENT_PORT_ALARM_INFO;
01805    if (event == EVENT_BCHAN_ERROR) return EVENT_BCHAN_ERROR_INFO;
01806 
01807    return NULL;
01808 }
01809 
01810 int isdn_msg_parse_event(struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
01811 {
01812    int i=isdn_msg_get_index(msgs, msg, nt);
01813    if(i<0) return -1;
01814 
01815    msgs[i].msg_parser(msgs, msg, bc, nt);
01816    return 0;
01817 }
01818 
01819 msg_t * isdn_msg_build_event(struct isdn_msg msgs[], struct misdn_bchannel *bc, enum event_e event, int nt)
01820 {
01821    int i=isdn_msg_get_index_by_event(msgs, event, nt);
01822    if(i<0) return NULL;
01823 
01824    return  msgs[i].msg_builder(msgs, bc, nt);
01825 }

Generated on Mon Jun 27 16:50:54 2011 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7