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

Generated on Thu Apr 16 06:27:37 2015 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6