From ab87b135488ed4d3e093dfe7a720423c65c24c2d Mon Sep 17 00:00:00 2001 From: MelwareDE Date: Fri, 20 Apr 2007 08:17:29 +0000 Subject: [PATCH] Moved more functions to use capi_sendf and changed capi_sendf to wait for the _CONF too. --- chan_capi.c | 237 ++++++++++++++-------------------------------- chan_capi_utils.c | 48 ++++++++++ chan_capi_utils.h | 5 +- 3 files changed, 121 insertions(+), 169 deletions(-) diff --git a/chan_capi.c b/chan_capi.c index 79980c0..44a6947 100644 --- a/chan_capi.c +++ b/chan_capi.c @@ -272,50 +272,6 @@ static const char * capi_command_to_string(unsigned short wCmd) return "UNDEFINED"; } -/* - * wait for a specific message - */ -static MESSAGE_EXCHANGE_ERROR capi_wait_conf(struct capi_pvt *i, unsigned short wCmd) -{ - MESSAGE_EXCHANGE_ERROR error = 0; - struct timespec abstime; - unsigned char command, subcommand; - - subcommand = wCmd & 0xff; - command = (wCmd & 0xff00) >> 8; - i->waitevent = (unsigned int)wCmd; - abstime.tv_sec = time(NULL) + 2; - abstime.tv_nsec = 0; - cc_verbose(4, 1, "%s: wait for %s (0x%x)\n", - i->vname, capi_cmd2str(command, subcommand), i->waitevent); - if (ast_cond_timedwait(&i->event_trigger, &i->lock, &abstime) != 0) { - error = -1; - cc_log(LOG_WARNING, "%s: timed out waiting for %s\n", - i->vname, capi_cmd2str(command, subcommand)); - } else { - cc_verbose(4, 1, "%s: cond signal received for %s\n", - i->vname, capi_cmd2str(command, subcommand)); - } - return error; -} - -/* - * write a capi message and wait for CONF - * i->lock must be held - */ -MESSAGE_EXCHANGE_ERROR _capi_put_cmsg_wait_conf(struct capi_pvt *i, _cmsg *CMSG) -{ - MESSAGE_EXCHANGE_ERROR error; - - error = _capi_put_cmsg(CMSG); - - if (!(error)) { - unsigned short wCmd = CAPICMD(CMSG->Command, CAPI_CONF); - error = capi_wait_conf(i, wCmd); - } - return error; -} - /* * wait for B3 up */ @@ -556,7 +512,7 @@ static void capi_echo_canceller(struct ast_channel *c, int function) i->isdnstate &= ~CAPI_ISDN_STATE_EC; } - capi_sendf(CAPI_FACILITY_REQ, i->PLCI, get_capi_MessageNumber(), + capi_sendf(i, 0, CAPI_FACILITY_REQ, i->PLCI, get_capi_MessageNumber(), "w(w(www))", i->ecSelector, function, @@ -600,7 +556,7 @@ static int capi_detect_dtmf(struct ast_channel *c, int flag) cc_verbose(3, 0, VERBOSE_PREFIX_2 "%s: Setting up DTMF detector (PLCI=%#x, flag=%d)\n", i->vname, i->PLCI, flag); - error = capi_sendf(CAPI_FACILITY_REQ, i->PLCI, get_capi_MessageNumber(), + error = capi_sendf(i, 0, CAPI_FACILITY_REQ, i->PLCI, get_capi_MessageNumber(), "w(www()())", FACILITYSELECTOR_DTMF, (flag == 1) ? 1:2, /* start/stop DTMF listen */ @@ -779,7 +735,7 @@ static int pbx_capi_send_digit(struct ast_channel *c, char digit) cc_mutex_unlock(&i->lock); return -1; } - ret = capi_sendf(CAPI_FACILITY_REQ, i->NCCI, get_capi_MessageNumber(), + ret = capi_sendf(i, 0, CAPI_FACILITY_REQ, i->NCCI, get_capi_MessageNumber(), "w(www(b)())", FACILITYSELECTOR_DTMF, 3, /* send DTMF digit */ @@ -1559,9 +1515,6 @@ static void cc_select_b(struct capi_pvt *i, _cstruct b3conf) */ static int line_interconnect(struct capi_pvt *i0, struct capi_pvt *i1, int start) { - _cmsg CMSG; - char buf[20]; - if ((i0->isdnstate & CAPI_ISDN_STATE_DISCONNECT) || (i1->isdnstate & CAPI_ISDN_STATE_DISCONNECT)) return -1; @@ -1575,41 +1528,33 @@ static int line_interconnect(struct capi_pvt *i0, struct capi_pvt *i1, int start return -1; } - FACILITY_REQ_HEADER(&CMSG, capi_ApplID, get_capi_MessageNumber(), 0); - FACILITY_REQ_PLCI(&CMSG) = i0->PLCI; - FACILITY_REQ_FACILITYSELECTOR(&CMSG) = FACILITYSELECTOR_LINE_INTERCONNECT; - - memset(buf, 0, sizeof(buf)); - if (start) { /* connect */ - buf[0] = 17; /* msg size */ - write_capi_word(&buf[1], 0x0001); - buf[3] = 14; /* struct size LI Request Parameter */ - write_capi_dword(&buf[4], 0x00000000); /* Data Path */ - buf[8] = 9; /* struct size */ - buf[9] = 8; /* struct size LI Request Connect Participant */ - write_capi_dword(&buf[10], i1->PLCI); - write_capi_dword(&buf[14], 0x00000003); /* Data Path Participant */ - } else { - /* disconnect */ - buf[0] = 7; /* msg size */ - write_capi_word(&buf[1], 0x0002); - buf[3] = 4; /* struct size */ - write_capi_dword(&buf[4], i1->PLCI); - } - - FACILITY_REQ_FACILITYREQUESTPARAMETER(&CMSG) = (_cstruct)buf; - - _capi_put_cmsg(&CMSG); - - if (start) { + capi_sendf(i1, 0, CAPI_FACILITY_REQ, i0->PLCI, get_capi_MessageNumber(), + "w(w(d((dd))))", + FACILITYSELECTOR_LINE_INTERCONNECT, + 0x0001, + /* struct LI Request Parameter */ + 0x00000000, /* Data Path */ + /* struct */ + /* struct LI Request Connect Participant */ + i1->PLCI, + 0x00000003 /* Data Path Participant */ + ); i0->isdnstate |= CAPI_ISDN_STATE_LI; i1->isdnstate |= CAPI_ISDN_STATE_LI; } else { + /* disconnect */ + capi_sendf(i1, 0, CAPI_FACILITY_REQ, i0->PLCI, get_capi_MessageNumber(), + "w(w(d))", + FACILITYSELECTOR_LINE_INTERCONNECT, + 0x0002, + i1->PLCI + ); i0->isdnstate &= ~CAPI_ISDN_STATE_LI; i1->isdnstate &= ~CAPI_ISDN_STATE_LI; } + return 0; } @@ -3919,11 +3864,9 @@ static void capidev_handle_msg(_cmsg *CMSG) static int pbx_capi_call_deflect(struct ast_channel *c, char *param) { struct capi_pvt *i = CC_CHANNEL_PVT(c); - _cmsg CMSG; - char fac[64]; - int res = 0; char *number; int numberlen; + char facnumber[32]; if (!param) { cc_log(LOG_WARNING, "capi deflection requires an argument (destination phone number)\n"); @@ -3958,34 +3901,27 @@ static int pbx_capi_call_deflect(struct ast_channel *c, char *param) if (i->state != CAPI_STATE_ALERTING) { pbx_capi_alert(c); } - - fac[0] = 0x0a + numberlen; /* length */ - fac[1] = 0x0d; /* call deflection */ - fac[2] = 0x00; - fac[3] = 0x07 + numberlen; /* struct len */ - fac[4] = 0x01; /* display of own address allowed */ - fac[5] = 0x00; - fac[6] = 0x03 + numberlen; - fac[7] = 0x00; /* type of facility number */ - fac[8] = 0x00; /* number plan */ - fac[9] = 0x00; /* presentation allowed */ - fac[10 + numberlen] = 0x00; /* subaddress len */ - memcpy((unsigned char *)fac + 10, number, numberlen); - - FACILITY_REQ_HEADER(&CMSG, capi_ApplID, get_capi_MessageNumber(),0); - FACILITY_REQ_PLCI(&CMSG) = i->PLCI; - FACILITY_REQ_FACILITYSELECTOR(&CMSG) = FACILITYSELECTOR_SUPPLEMENTARY; - FACILITY_REQ_FACILITYREQUESTPARAMETER(&CMSG) = (_cstruct)&fac; + facnumber[0] = 0x03 + numberlen; + facnumber[1] = 0x00; /* type of facility number */ + facnumber[2] = 0x00; /* number plan */ + facnumber[3] = 0x00; /* presentation allowed */ + memcpy(&facnumber[4], number, numberlen); - _capi_put_cmsg_wait_conf(i, &CMSG); + capi_sendf(i, 1, CAPI_FACILITY_REQ, i->PLCI, get_capi_MessageNumber(), + "w(w(ws()))", + FACILITYSELECTOR_SUPPLEMENTARY, + 0x000d, /* call deflection */ + 0x0001, /* display of own address allowed */ + &facnumber[0] + ); cc_mutex_unlock(&i->lock); cc_verbose(2, 1, VERBOSE_PREFIX_3 "%s: sent FACILITY_REQ for CD PLCI = %#x\n", i->vname, i->PLCI); - return(res); + return 0; } /* @@ -4015,8 +3951,6 @@ static int pbx_capi_peer_link(struct ast_channel *c, char *param) static int pbx_capi_retrieve(struct ast_channel *c, char *param) { struct capi_pvt *i = CC_CHANNEL_PVT(c); - _cmsg CMSG; - char fac[4]; unsigned int plci = 0; if (c->tech == &capi_tech) { @@ -4067,17 +4001,12 @@ static int pbx_capi_retrieve(struct ast_channel *c, char *param) return -1; } - fac[0] = 3; /* len */ - fac[1] = 0x03; /* retrieve */ - fac[2] = 0x00; - fac[3] = 0; + capi_sendf(i, 0, CAPI_FACILITY_REQ, plci, get_capi_MessageNumber(), + "w(w())", + FACILITYSELECTOR_SUPPLEMENTARY, + 0x0003 /* retrieve */ + ); - FACILITY_REQ_HEADER(&CMSG, capi_ApplID, get_capi_MessageNumber(),0); - FACILITY_REQ_PLCI(&CMSG) = plci; - FACILITY_REQ_FACILITYSELECTOR(&CMSG) = FACILITYSELECTOR_SUPPLEMENTARY; - FACILITY_REQ_FACILITYREQUESTPARAMETER(&CMSG) = (_cstruct)&fac; - - _capi_put_cmsg(&CMSG); cc_verbose(2, 1, VERBOSE_PREFIX_4 "%s: sent RETRIEVE for PLCI=%#x\n", i->vname, plci); @@ -4094,8 +4023,6 @@ static int pbx_capi_ect(struct ast_channel *c, char *param) { struct capi_pvt *i = CC_CHANNEL_PVT(c); struct capi_pvt *ii = NULL; - _cmsg CMSG; - char fac[8]; const char *id; unsigned int plci = 0; @@ -4148,21 +4075,16 @@ static int pbx_capi_ect(struct ast_channel *c, char *param) return -1; } - fac[0] = 7; /* len */ - fac[1] = 0x06; /* ECT (function) */ - fac[2] = 0x00; - fac[3] = 4; /* len / sservice specific parameter , cstruct */ - write_capi_dword(&(fac[4]), plci); - - FACILITY_REQ_HEADER(&CMSG, capi_ApplID, get_capi_MessageNumber(), 0); - FACILITY_REQ_CONTROLLER(&CMSG) = i->controller; - FACILITY_REQ_PLCI(&CMSG) = plci; /* implicit ECT */ - FACILITY_REQ_FACILITYSELECTOR(&CMSG) = FACILITYSELECTOR_SUPPLEMENTARY; - FACILITY_REQ_FACILITYREQUESTPARAMETER(&CMSG) = (_cstruct)&fac; - cc_mutex_lock(&ii->lock); - _capi_put_cmsg_wait_conf(ii, &CMSG); - + + /* implicit ECT */ + capi_sendf(ii, 1, CAPI_FACILITY_REQ, plci, get_capi_MessageNumber(), + "w(w(d))", + FACILITYSELECTOR_SUPPLEMENTARY, + 0x0006, /* ECT */ + plci + ); + ii->isdnstate &= ~CAPI_ISDN_STATE_HOLD; ii->isdnstate |= CAPI_ISDN_STATE_ECT; i->isdnstate |= CAPI_ISDN_STATE_ECT; @@ -4181,9 +4103,7 @@ static int pbx_capi_ect(struct ast_channel *c, char *param) static int pbx_capi_hold(struct ast_channel *c, char *param) { struct capi_pvt *i = CC_CHANNEL_PVT(c); - _cmsg CMSG; char buffer[16]; - char fac[4]; /* TODO: support holdtype notify */ @@ -4204,17 +4124,12 @@ static int pbx_capi_hold(struct ast_channel *c, char *param) return 0; } - fac[0] = 3; /* len */ - fac[1] = 0x02; /* this is a HOLD up */ - fac[2] = 0x00; - fac[3] = 0; + capi_sendf(i, 0, CAPI_FACILITY_REQ, i->PLCI, get_capi_MessageNumber(), + "w(w())", + FACILITYSELECTOR_SUPPLEMENTARY, + 0x0002 /* hold */ + ); - FACILITY_REQ_HEADER(&CMSG, capi_ApplID, get_capi_MessageNumber(),0); - FACILITY_REQ_PLCI(&CMSG) = i->PLCI; - FACILITY_REQ_FACILITYSELECTOR(&CMSG) = FACILITYSELECTOR_SUPPLEMENTARY; - FACILITY_REQ_FACILITYREQUESTPARAMETER(&CMSG) = (_cstruct)&fac; - - _capi_put_cmsg(&CMSG); cc_verbose(2, 1, VERBOSE_PREFIX_4 "%s: sent HOLD for PLCI=%#x\n", i->vname, i->PLCI); @@ -4236,8 +4151,6 @@ static int pbx_capi_hold(struct ast_channel *c, char *param) static int pbx_capi_malicious(struct ast_channel *c, char *param) { struct capi_pvt *i = CC_CHANNEL_PVT(c); - _cmsg CMSG; - char fac[4]; if (!(capi_controllers[i->controller]->MCID)) { cc_log(LOG_NOTICE, "%s: MCID for %s not supported by controller.\n", @@ -4245,18 +4158,14 @@ static int pbx_capi_malicious(struct ast_channel *c, char *param) return -1; } - fac[0] = 3; /* len */ - fac[1] = 0x0e; /* MCID */ - fac[2] = 0x00; - fac[3] = 0; - - FACILITY_REQ_HEADER(&CMSG, capi_ApplID, get_capi_MessageNumber(),0); - FACILITY_REQ_PLCI(&CMSG) = i->PLCI; - FACILITY_REQ_FACILITYSELECTOR(&CMSG) = FACILITYSELECTOR_SUPPLEMENTARY; - FACILITY_REQ_FACILITYREQUESTPARAMETER(&CMSG) = (_cstruct)&fac; - cc_mutex_lock(&i->lock); - _capi_put_cmsg_wait_conf(i, &CMSG); + + capi_sendf(i, 1, CAPI_FACILITY_REQ, i->PLCI, get_capi_MessageNumber(), + "w(w())", + FACILITYSELECTOR_SUPPLEMENTARY, + 0x000e /* MCID */ + ); + cc_mutex_unlock(&i->lock); cc_verbose(2, 1, VERBOSE_PREFIX_4 "%s: sent MCID for PLCI=%#x\n", @@ -4382,8 +4291,6 @@ static int pbx_capi_3pty_begin(struct ast_channel *c, char *param) { struct capi_pvt *i = CC_CHANNEL_PVT(c); struct capi_pvt *ii = NULL; - _cmsg CMSG; - char fac[8]; const char *id; unsigned int plci = 0; @@ -4432,20 +4339,14 @@ static int pbx_capi_3pty_begin(struct ast_channel *c, char *param) return 0; } - fac[0] = 7; /* len */ - fac[1] = 0x07; /* this is a 3PTY Begin */ - fac[2] = 0x00; - fac[3] = 4; /* length of PLCI parameter (DWORD) */ - write_capi_dword(&(fac[4]), plci); - - FACILITY_REQ_HEADER(&CMSG, capi_ApplID, get_capi_MessageNumber(), 0); - FACILITY_REQ_CONTROLLER(&CMSG) = i->controller; - FACILITY_REQ_PLCI(&CMSG) = plci; /* implicit 3PTY */ - FACILITY_REQ_FACILITYSELECTOR(&CMSG) = FACILITYSELECTOR_SUPPLEMENTARY; - FACILITY_REQ_FACILITYREQUESTPARAMETER(&CMSG) = (_cstruct)&fac; - cc_mutex_lock(&ii->lock); - _capi_put_cmsg_wait_conf(ii, &CMSG); + + capi_sendf(ii, 1, CAPI_FACILITY_REQ, plci, get_capi_MessageNumber(), + "w(w(d))", + FACILITYSELECTOR_SUPPLEMENTARY, + 0x0007, /* 3PTY begin */ + plci + ); ii->isdnstate &= ~CAPI_ISDN_STATE_HOLD; ii->isdnstate |= CAPI_ISDN_STATE_3PTY; diff --git a/chan_capi_utils.c b/chan_capi_utils.c index d689bc1..057c0f4 100644 --- a/chan_capi_utils.c +++ b/chan_capi_utils.c @@ -111,6 +111,33 @@ struct capi_pvt *find_interface_by_msgnum(unsigned short msgnum) return i; } +/* + * wait for a specific message + */ +MESSAGE_EXCHANGE_ERROR capi_wait_conf(struct capi_pvt *i, unsigned short wCmd) +{ + MESSAGE_EXCHANGE_ERROR error = 0; + struct timespec abstime; + unsigned char command, subcommand; + + subcommand = wCmd & 0xff; + command = (wCmd & 0xff00) >> 8; + i->waitevent = (unsigned int)wCmd; + abstime.tv_sec = time(NULL) + 2; + abstime.tv_nsec = 0; + cc_verbose(4, 1, "%s: wait for %s (0x%x)\n", + i->vname, capi_cmd2str(command, subcommand), i->waitevent); + if (ast_cond_timedwait(&i->event_trigger, &i->lock, &abstime) != 0) { + error = -1; + cc_log(LOG_WARNING, "%s: timed out waiting for %s\n", + i->vname, capi_cmd2str(command, subcommand)); + } else { + cc_verbose(4, 1, "%s: cond signal received for %s\n", + i->vname, capi_cmd2str(command, subcommand)); + } + return error; +} + /* * log verbose a capi message */ @@ -225,12 +252,30 @@ MESSAGE_EXCHANGE_ERROR capidev_check_wait_get_cmsg(_cmsg *CMSG) return Info; } +/* + * write a capi cmessage and wait for CONF + * i->lock must be held + */ +MESSAGE_EXCHANGE_ERROR _capi_put_cmsg_wait_conf(struct capi_pvt *i, _cmsg *CMSG) +{ + MESSAGE_EXCHANGE_ERROR error; + + error = _capi_put_cmsg(CMSG); + + if (!(error)) { + unsigned short wCmd = CAPICMD(CMSG->Command, CAPI_CONF); + error = capi_wait_conf(i, wCmd); + } + return error; +} + /* * Eicon's capi_sendf() function to create capi messages easily * and send this message. * Copyright by Eicon Networks / Dialogic */ MESSAGE_EXCHANGE_ERROR capi_sendf( + struct capi_pvt *capii, int waitconf, _cword command, _cdword Id, _cword Number, char * format, ...) { MESSAGE_EXCHANGE_ERROR ret; @@ -324,6 +369,9 @@ MESSAGE_EXCHANGE_ERROR capi_sendf( write_capi_word(&msg[0], (unsigned short)(p - (&msg[0]))); ret = _capi_put_msg(&msg[0]); + if ((!(ret)) && (waitconf)) { + ret = capi_wait_conf(capii, (command & 0xff00) | CAPI_CONF); + } return (ret); } diff --git a/chan_capi_utils.h b/chan_capi_utils.h index b841220..eb3ec5f 100644 --- a/chan_capi_utils.h +++ b/chan_capi_utils.h @@ -24,8 +24,10 @@ extern void cc_verbose(int o_v, int c_d, char *text, ...); extern _cword get_capi_MessageNumber(void); extern struct capi_pvt *find_interface_by_msgnum(unsigned short msgnum); extern struct capi_pvt *find_interface_by_plci(unsigned int plci); +extern MESSAGE_EXCHANGE_ERROR capi_wait_conf(struct capi_pvt *i, unsigned short wCmd); extern MESSAGE_EXCHANGE_ERROR _capi_put_cmsg(_cmsg *CMSG); extern MESSAGE_EXCHANGE_ERROR capidev_check_wait_get_cmsg(_cmsg *CMSG); +extern MESSAGE_EXCHANGE_ERROR _capi_put_cmsg_wait_conf(struct capi_pvt *i, _cmsg *CMSG); extern char *capi_info_string(unsigned int info); extern void show_capi_info(struct capi_pvt *i, _cword info); extern unsigned ListenOnController(unsigned long CIPmask, unsigned controller); @@ -48,6 +50,7 @@ typedef struct capi_prestruct_s { * Copyright by Eicon Networks / Dialogic */ extern MESSAGE_EXCHANGE_ERROR capi_sendf( - _cword command, _cdword Id, _cword Number, char * format, ...); + struct capi_pvt *capii, int waitconf, + _cword command, _cdword Id, _cword Number, char * format, ...); #endif