add strict state parsing and configurable suggest mode

git-svn-id: http://svn.openzap.org/svn/openzap/trunk@482 a93c3328-9c30-0410-af19-c9cd2b2d52af
This commit is contained in:
Michael Jerris 2008-05-21 18:58:14 +00:00
parent 219812a90f
commit b015d7b8d3
5 changed files with 243 additions and 50 deletions

View File

@ -1593,7 +1593,8 @@ static switch_status_t load_config(void)
uint32_t span_id = 0;
zap_span_t *span = NULL;
char *tonegroup = NULL;
zap_isdn_opts_t opts = ZAP_ISDN_OPT_NONE;
for (param = switch_xml_child(myspan, "param"); param; param = param->next) {
char *var = (char *) switch_xml_attr_soft(param, "name");
char *val = (char *) switch_xml_attr_soft(param, "value");
@ -1609,6 +1610,8 @@ static switch_status_t load_config(void)
}
} else if (!strcasecmp(var, "context")) {
context = val;
} else if (!strcasecmp(var, "suggest-channel") && switch_true(val)) {
opts |= ZAP_ISDN_OPT_SUGGEST_CHANNEL;
} else if (!strcasecmp(var, "dialplan")) {
dialplan = val;
}
@ -1630,7 +1633,7 @@ static switch_status_t load_config(void)
continue;
}
if (zap_isdn_configure_span(span, mode, dialect, on_clear_channel_signal) != ZAP_SUCCESS) {
if (zap_isdn_configure_span(span, mode, dialect, opts, on_clear_channel_signal) != ZAP_SUCCESS) {
zap_log(ZAP_LOG_ERROR, "Error starting OpenZAP span %d mode: %d dialect: %d error: %s\n", span_id, mode, dialect, span->last_error);
continue;
}

View File

@ -438,19 +438,6 @@ struct zap_sigmsg {
};
struct zap_isdn_data {
Q921Data_t q921;
Q931_TrunkInfo_t q931;
zap_channel_t *dchan;
zap_channel_t *dchans[2];
struct zap_sigmsg sigmsg;
zio_signal_cb_t sig_cb;
uint32_t flags;
zap_caller_data_t *outbound_crv[32768];
zap_channel_t *channels_local_crv[32768];
zap_channel_t *channels_remote_crv[32768];
};
struct zap_analog_data {
uint32_t flags;
uint32_t max_dialstr;

View File

@ -35,16 +35,37 @@
#define ZAP_ISDN_H
#include "openzap.h"
typedef enum {
ZAP_ISDN_OPT_NONE = 0,
ZAP_ISDN_OPT_SUGGEST_CHANNEL = (1 << 0)
} zap_isdn_opts_t;
typedef enum {
ZAP_ISDN_RUNNING = (1 << 0)
} zap_isdn_flag_t;
struct zap_isdn_data {
Q921Data_t q921;
Q931_TrunkInfo_t q931;
zap_channel_t *dchan;
zap_channel_t *dchans[2];
struct zap_sigmsg sigmsg;
zio_signal_cb_t sig_cb;
uint32_t flags;
zap_caller_data_t *outbound_crv[32768];
zap_channel_t *channels_local_crv[32768];
zap_channel_t *channels_remote_crv[32768];
zap_isdn_opts_t opts;
};
typedef struct zap_isdn_data zap_isdn_data_t;
zap_status_t zap_isdn_start(zap_span_t *span);
zap_status_t zap_isdn_init(void);
zap_status_t zap_isdn_configure_span(zap_span_t *span, Q921NetUser_t mode, Q931Dialect_t dialect, zio_signal_cb_t sig_cb);
zap_status_t zap_isdn_configure_span(zap_span_t *span, Q921NetUser_t mode, Q931Dialect_t dialect, zap_isdn_opts_t opts, zio_signal_cb_t sig_cb);
#endif

View File

@ -31,7 +31,7 @@ int main(int argc, char *argv[])
}
if (zap_isdn_configure_span(span, Q931_TE, Q931_Dialect_National, on_signal) == ZAP_SUCCESS) {
if (zap_isdn_configure_span(span, Q931_TE, Q931_Dialect_National, 0, on_signal) == ZAP_SUCCESS) {
data = span->signal_data;
zap_isdn_start(span);
} else {

View File

@ -52,6 +52,7 @@ static L2ULONG zap_time_now(void)
static ZIO_CHANNEL_OUTGOING_CALL_FUNCTION(isdn_outgoing_call)
{
zap_status_t status = ZAP_SUCCESS;
zap_set_flag(zchan, ZAP_CHANNEL_OUTBOUND);
zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_DIALING);
return status;
}
@ -85,37 +86,11 @@ static ZIO_CHANNEL_REQUEST_FUNCTION(isdn_channel_request)
BearerCap.ITR = 16; /* 64k */
BearerCap.Layer1Ident = 1;
BearerCap.UIL1Prot = 2; /* U-law (a-law = 3)*/
#if 0
BearerCap.SyncAsync = ;
BearerCap.Negot = ;
BearerCap.UserRate = ;
BearerCap.InterRate = ;
BearerCap.NIConTx = ;
BearerCap.FlowCtlTx = ;
BearerCap.HDR = ;
BearerCap.MultiFrame = ;
BearerCap.Mode = ;
BearerCap.LLInegot = ;
BearerCap.Assignor = ;
BearerCap.InBandNeg = ;
BearerCap.NumStopBits = ;
BearerCap.NumDataBits = ;
BearerCap.Parity = ;
BearerCap.DuplexMode = ;
BearerCap.ModemType = ;
BearerCap.Layer2Ident = ;
BearerCap.UIL2Prot = ;
BearerCap.Layer3Ident = ;
BearerCap.UIL3Prot = ;
BearerCap.AL3Info1 = ;
BearerCap.AL3Info2 = ;
#endif
gen->BearerCap = Q931AppendIE((L3UCHAR *) gen, (L3UCHAR *) &BearerCap);
//is cast right here?
ChanID.IntType = 1; /* PRI = 1, BRI = 0 */
ChanID.PrefExcl = 0; /* 0 = preferred, 1 exclusive */
ChanID.PrefExcl = (isdn_data->opts & ZAP_ISDN_OPT_SUGGEST_CHANNEL) ? 0 : 1; /* 0 = preferred, 1 exclusive */
ChanID.InfoChanSel = 1;
ChanID.ChanMapType = 3; /* B-Chan */
ChanID.ChanSlot = chan_id;
@ -230,7 +205,8 @@ static ZIO_CHANNEL_REQUEST_FUNCTION(isdn_channel_request)
if (new_chan && new_chan->state == ZAP_CHANNEL_STATE_DOWN) {
isdn_data->channels_local_crv[gen->CRV] = new_chan;
memset(&new_chan->caller_data, 0, sizeof(new_chan->caller_data));
zap_set_flag(new_chan, ZAP_CHANNEL_OUTBOUND);
zap_set_state_locked(new_chan, ZAP_CHANNEL_STATE_DIALING);
switch(gen->MesType) {
case Q931mes_ALERTING:
new_chan->init_state = ZAP_CHANNEL_STATE_PROGRESS_MEDIA;
@ -400,7 +376,7 @@ static L3INT zap_isdn_931_34(void *pvt, L2UCHAR *msg, L2INT mlen)
const char *what = gen->MesType == Q931mes_RELEASE ? "Release" : "Release Complete";
if (zchan) {
if (zchan->state == ZAP_CHANNEL_STATE_TERMINATING || zchan->state == ZAP_CHANNEL_STATE_HANGUP) {
zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_DOWN);
zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_HANGUP_COMPLETE);
} else {
zap_log(ZAP_LOG_DEBUG, "Ignoring %s on channel %d\n", what, chan_id);
}
@ -660,8 +636,102 @@ static __inline__ void state_advance(zap_channel_t *zchan)
}
break;
case ZAP_CHANNEL_STATE_DIALING:
{
if (!(isdn_data->opts & ZAP_ISDN_OPT_SUGGEST_CHANNEL)) {
Q931ie_BearerCap BearerCap;
Q931ie_ChanID ChanID;
Q931ie_CallingNum CallingNum;
Q931ie_CallingNum *ptrCallingNum;
Q931ie_CalledNum CalledNum;
Q931ie_CalledNum *ptrCalledNum;
Q931ie_Display Display, *ptrDisplay;
Q931InitIEBearerCap(&BearerCap);
Q931InitIEChanID(&ChanID);
Q931InitIECallingNum(&CallingNum);
Q931InitIECalledNum(&CalledNum);
Q931InitIEDisplay(&Display);
Q931InitMesGeneric(gen);
gen->MesType = Q931mes_SETUP;
BearerCap.CodStand = 0; /* ITU-T = 0, ISO/IEC = 1, National = 2, Network = 3 */
BearerCap.ITC = 0; /* Speech */
BearerCap.TransMode = 0; /* Circuit = 0, Packet = 1 */
BearerCap.ITR = 16; /* 64k */
BearerCap.Layer1Ident = 1;
BearerCap.UIL1Prot = 2; /* U-law (a-law = 3)*/
gen->BearerCap = Q931AppendIE((L3UCHAR *) gen, (L3UCHAR *) &BearerCap);
//is cast right here?
ChanID.IntType = 1; /* PRI = 1, BRI = 0 */
ChanID.InfoChanSel = 1;
ChanID.ChanMapType = 3; /* B-Chan */
ChanID.ChanSlot = (unsigned char)zchan->chan_id;
gen->ChanID = Q931AppendIE((L3UCHAR *) gen, (L3UCHAR *) &ChanID);
Display.Size = Display.Size + (unsigned char)strlen(zchan->caller_data.cid_name);
gen->Display = Q931AppendIE((L3UCHAR *) gen, (L3UCHAR *) &Display);
ptrDisplay = Q931GetIEPtr(gen->Display, gen->buf);
zap_copy_string((char *)ptrDisplay->Display, zchan->caller_data.cid_name, strlen(zchan->caller_data.cid_name)+1);
/* TypNum: Type of number*/
/* Bits 7 6 5*/
/* 000Unknown*/
/* 001International number*/
/* 010National number*/
/* 011Network Specific number */
/* 100Subscriber mumber*/
/* 110Abbreviated number*/
/* 111Reserved for extension*/
/* All other values are reserved */
CallingNum.TypNum = 2;
/* NumPlanID*/
/* Bits 4 3 2 1*/
/* 0000Unknown*/
/* 0001ISDN/telephony numbering plan (E.164)*/
/* 0011Data numbering plan (X.121)*/
/* 0100Telex numbering plan (F.69)*/
/* 1000National standard numbering plan*/
/* 1001Private numbering plan*/
/* 1111Reserved for extension*/
/* All other valures are reserved*/
CallingNum.NumPlanID = 1;
/* Presentation indicator*/
/* Bits 7 6*/
/* 00Presenation Allowed*/
/* 01Presentation Restricted*/
/* 10Number not available due to internetworking*/
/* 11Reserved*/
CallingNum.PresInd = 0;
/* Screening Indicator*/
/* Bits 2 1*/
/* 00User-provided, not screened*/
/* 01User-provided, verified and passed*/
/* 10User-provided, verified and failed*/
/* 11Network provided*/
CallingNum.ScreenInd = 0;
CallingNum.Size = CallingNum.Size + (unsigned char)strlen(zchan->caller_data.cid_num.digits);
gen->CallingNum = Q931AppendIE((L3UCHAR *) gen, (L3UCHAR *) &CallingNum);
ptrCallingNum = Q931GetIEPtr(gen->CallingNum, gen->buf);
zap_copy_string((char *)ptrCallingNum->Digit, zchan->caller_data.cid_num.digits, strlen(zchan->caller_data.cid_num.digits)+1);
CalledNum.TypNum = 2;
CalledNum.NumPlanID = 1;
CalledNum.Size = CalledNum.Size + (unsigned char)strlen(zchan->caller_data.ani.digits);
gen->CalledNum = Q931AppendIE((L3UCHAR *) gen, (L3UCHAR *) &CalledNum);
ptrCalledNum = Q931GetIEPtr(gen->CalledNum, gen->buf);
zap_copy_string((char *)ptrCalledNum->Digit, zchan->caller_data.ani.digits, strlen(zchan->caller_data.ani.digits)+1);
Q931Rx43(&isdn_data->q931, (L3UCHAR *) gen, gen->Size);
isdn_data->channels_local_crv[gen->CRV] = zchan;
}
break;
case ZAP_CHANNEL_STATE_HANGUP_COMPLETE:
{
zap_set_state_locked(zchan, ZAP_CHANNEL_STATE_DOWN);
}
break;
case ZAP_CHANNEL_STATE_HANGUP:
@ -891,7 +961,113 @@ static int q931_rx_32(void *pvt,L3UCHAR *msg, L3INT mlen)
return ret;
}
zap_status_t zap_isdn_configure_span(zap_span_t *span, Q921NetUser_t mode, Q931Dialect_t dialect, zio_signal_cb_t sig_cb)
static zap_state_map_t isdn_state_map = {
{
{
ZSD_OUTBOUND,
ZSM_UNACCEPTABLE,
{ZAP_ANY_STATE},
{ZAP_CHANNEL_STATE_RESTART, ZAP_END}
},
{
ZSD_OUTBOUND,
ZSM_UNACCEPTABLE,
{ZAP_CHANNEL_STATE_RESTART, ZAP_END},
{ZAP_CHANNEL_STATE_DOWN, ZAP_END}
},
{
ZSD_OUTBOUND,
ZSM_UNACCEPTABLE,
{ZAP_CHANNEL_STATE_DOWN, ZAP_END},
{ZAP_CHANNEL_STATE_DIALING, ZAP_END}
},
{
ZSD_OUTBOUND,
ZSM_UNACCEPTABLE,
{ZAP_CHANNEL_STATE_DIALING, ZAP_END},
{ZAP_CHANNEL_STATE_PROGRESS_MEDIA, ZAP_CHANNEL_STATE_PROGRESS, ZAP_CHANNEL_STATE_UP, ZAP_CHANNEL_STATE_HANGUP, ZAP_CHANNEL_STATE_TERMINATING, ZAP_END}
},
{
ZSD_OUTBOUND,
ZSM_UNACCEPTABLE,
{ZAP_CHANNEL_STATE_PROGRESS_MEDIA, ZAP_CHANNEL_STATE_PROGRESS, ZAP_END},
{ZAP_CHANNEL_STATE_HANGUP, ZAP_CHANNEL_STATE_PROGRESS_MEDIA, ZAP_CHANNEL_STATE_TERMINATING, ZAP_CHANNEL_STATE_UP, ZAP_END}
},
{
ZSD_OUTBOUND,
ZSM_UNACCEPTABLE,
{ZAP_CHANNEL_STATE_HANGUP, ZAP_CHANNEL_STATE_TERMINATING, ZAP_END},
{ZAP_CHANNEL_STATE_HANGUP_COMPLETE, ZAP_END}
},
{
ZSD_OUTBOUND,
ZSM_UNACCEPTABLE,
{ZAP_CHANNEL_STATE_HANGUP_COMPLETE, ZAP_END},
{ZAP_CHANNEL_STATE_DOWN, ZAP_END},
},
{
ZSD_OUTBOUND,
ZSM_UNACCEPTABLE,
{ZAP_CHANNEL_STATE_UP, ZAP_END},
{ZAP_CHANNEL_STATE_HANGUP, ZAP_CHANNEL_STATE_TERMINATING, ZAP_END}
},
/****************************************/
{
ZSD_INBOUND,
ZSM_UNACCEPTABLE,
{ZAP_ANY_STATE},
{ZAP_CHANNEL_STATE_RESTART, ZAP_END}
},
{
ZSD_INBOUND,
ZSM_UNACCEPTABLE,
{ZAP_CHANNEL_STATE_RESTART, ZAP_END},
{ZAP_CHANNEL_STATE_DOWN, ZAP_END}
},
{
ZSD_INBOUND,
ZSM_UNACCEPTABLE,
{ZAP_CHANNEL_STATE_DOWN, ZAP_END},
{ZAP_CHANNEL_STATE_RING, ZAP_END}
},
{
ZSD_INBOUND,
ZSM_UNACCEPTABLE,
{ZAP_CHANNEL_STATE_RING, ZAP_END},
{ZAP_CHANNEL_STATE_HANGUP, ZAP_CHANNEL_STATE_TERMINATING, ZAP_CHANNEL_STATE_PROGRESS, ZAP_CHANNEL_STATE_PROGRESS_MEDIA, ZAP_CHANNEL_STATE_UP, ZAP_END}
},
{
ZSD_INBOUND,
ZSM_UNACCEPTABLE,
{ZAP_CHANNEL_STATE_HANGUP, ZAP_CHANNEL_STATE_TERMINATING, ZAP_END},
{ZAP_CHANNEL_STATE_HANGUP_COMPLETE, ZAP_END},
},
{
ZSD_INBOUND,
ZSM_UNACCEPTABLE,
{ZAP_CHANNEL_STATE_HANGUP_COMPLETE, ZAP_END},
{ZAP_CHANNEL_STATE_DOWN, ZAP_END},
},
{
ZSD_INBOUND,
ZSM_UNACCEPTABLE,
{ZAP_CHANNEL_STATE_PROGRESS, ZAP_CHANNEL_STATE_PROGRESS_MEDIA, ZAP_END},
{ZAP_CHANNEL_STATE_HANGUP, ZAP_CHANNEL_STATE_PROGRESS_MEDIA, ZAP_CHANNEL_STATE_CANCEL, ZAP_CHANNEL_STATE_UP, ZAP_END},
},
{
ZSD_INBOUND,
ZSM_UNACCEPTABLE,
{ZAP_CHANNEL_STATE_UP, ZAP_END},
{ZAP_CHANNEL_STATE_HANGUP, ZAP_CHANNEL_STATE_TERMINATING, ZAP_END},
},
}
};
zap_status_t zap_isdn_configure_span(zap_span_t *span, Q921NetUser_t mode, Q931Dialect_t dialect, zap_isdn_opts_t opts, zio_signal_cb_t sig_cb)
{
uint32_t i, x = 0;
zap_channel_t *dchans[2] = {0};
@ -962,8 +1138,14 @@ zap_status_t zap_isdn_configure_span(zap_span_t *span, Q921NetUser_t mode, Q931D
span->signal_data = isdn_data;
span->signal_type = ZAP_SIGTYPE_ISDN;
span->outgoing_call = isdn_outgoing_call;
span->channel_request = isdn_channel_request;
span->suggest_chan_id = 1;
isdn_data->opts = opts;
if ((opts & ZAP_ISDN_OPT_SUGGEST_CHANNEL)) {
span->channel_request = isdn_channel_request;
span->suggest_chan_id = 1;
}
span->state_map = &isdn_state_map;
return ZAP_SUCCESS;
}