extractedLnx/linux-2.6.9/drivers/isdn/hardware/eicon/message.c_add_b1.c
word add_b1(PLCI * plci, API_PARSE * bp, word b_channel_info, word b1_facilities)
{
API_PARSE bp_parms[8];
API_PARSE mdm_cfg[9];
API_PARSE global_config[2];
byte cai[256];
byte resource[] = {5,9,13,12,16,39,9,17,17,18};
byte voice_cai[] = "\x06\x14\x00\x00\x00\x00\x08";
word i;
API_PARSE mdm_cfg_v18[4];
word j, n, w;
dword d;
for(i=0;i<8;i++) bp_parms[i].length = 0;
for(i=0;i<2;i++) global_config[i].length = 0;
dbug(1,dprintf("add_b1"));
api_save_msg(bp, "s", &plci->B_protocol);
if(b_channel_info==2){
plci->B1_resource = 0;
adjust_b1_facilities (plci, plci->B1_resource, b1_facilities);
add_p(plci, CAI, "\x01\x00");
dbug(1,dprintf("Cai=1,0 (no resource)"));
return 0;
}
if(plci->tel == CODEC_PERMANENT) return 0;
else if(plci->tel == CODEC){
plci->B1_resource = 1;
adjust_b1_facilities (plci, plci->B1_resource, b1_facilities);
add_p(plci, CAI, "\x01\x01");
dbug(1,dprintf("Cai=1,1 (Codec)"));
return 0;
}
else if(plci->tel == ADV_VOICE){
plci->B1_resource = add_b1_facilities (plci, 9, (word)(b1_facilities | B1_FACILITY_VOICE));
adjust_b1_facilities (plci, plci->B1_resource, (word)(b1_facilities | B1_FACILITY_VOICE));
voice_cai[1] = plci->B1_resource;
WRITE_WORD (&voice_cai[5], plci->appl->MaxDataLength);
add_p(plci, CAI, voice_cai);
dbug(1,dprintf("Cai=1,0x%x (AdvVoice)",voice_cai[1]));
return 0;
}
plci->call_dir &= ~(CALL_DIR_ORIGINATE | CALL_DIR_ANSWER);
if (plci->call_dir & CALL_DIR_OUT)
plci->call_dir |= CALL_DIR_ORIGINATE;
else if (plci->call_dir & CALL_DIR_IN)
plci->call_dir |= CALL_DIR_ANSWER;
if(!bp->length){
plci->B1_resource = 0x5;
adjust_b1_facilities (plci, plci->B1_resource, b1_facilities);
add_p(plci, CAI, "\x01\x05");
return 0;
}
dbug(1,dprintf("b_prot_len=%d",(word)bp->length));
if(bp->length>256) return _WRONG_MESSAGE_FORMAT;
if(api_parse(&bp->info[1], (word)bp->length, "wwwsssb", bp_parms))
{
bp_parms[6].length = 0;
if(api_parse(&bp->info[1], (word)bp->length, "wwwsss", bp_parms))
{
dbug(1,dprintf("b-form.!"));
return _WRONG_MESSAGE_FORMAT;
}
}
else if (api_parse(&bp->info[1], (word)bp->length, "wwwssss", bp_parms))
{
dbug(1,dprintf("b-form.!"));
return _WRONG_MESSAGE_FORMAT;
}
if(bp_parms[6].length)
{
if(api_parse(&bp_parms[6].info[1], (word)bp_parms[6].length, "w", global_config))
{
return _WRONG_MESSAGE_FORMAT;
}
switch(READ_WORD(global_config[0].info))
{
case 1:
plci->call_dir = (plci->call_dir & ~CALL_DIR_ANSWER) | CALL_DIR_ORIGINATE;
break;
case 2:
plci->call_dir = (plci->call_dir & ~CALL_DIR_ORIGINATE) | CALL_DIR_ANSWER;
break;
}
}
dbug(1,dprintf("call_dir=%04x", plci->call_dir));
if ((READ_WORD(bp_parms[0].info) == B1_RTP)
&& (plci->adapter->man_profile.private_options & (1L << PRIVATE_RTP)))
{
plci->B1_resource = add_b1_facilities (plci, 31, (word)(b1_facilities & ~B1_FACILITY_VOICE));
adjust_b1_facilities (plci, plci->B1_resource, (word)(b1_facilities & ~B1_FACILITY_VOICE));
cai[1] = plci->B1_resource;
cai[2] = 0;
cai[3] = 0;
cai[4] = 0;
WRITE_WORD(&cai[5],plci->appl->MaxDataLength);
for (i = 0; i < bp_parms[3].length; i++)
cai[7+i] = bp_parms[3].info[1+i];
cai[0] = 6 + bp_parms[3].length;
add_p(plci, CAI, cai);
return 0;
}
if ((READ_WORD(bp_parms[0].info) == B1_PIAFS)
&& (plci->adapter->man_profile.private_options & (1L << PRIVATE_PIAFS)))
{
plci->B1_resource = add_b1_facilities (plci, 35/* PIAFS HARDWARE FACILITY */, (word)(b1_facilities & ~B1_FACILITY_VOICE));
adjust_b1_facilities (plci, plci->B1_resource, (word)(b1_facilities & ~B1_FACILITY_VOICE));
cai[1] = plci->B1_resource;
cai[2] = 0;
cai[3] = 0;
cai[4] = 0;
WRITE_WORD(&cai[5],plci->appl->MaxDataLength);
cai[0] = 6;
add_p(plci, CAI, cai);
return 0;
}
if ((READ_WORD(bp_parms[0].info) >= 32)
|| (!((1L << READ_WORD(bp_parms[0].info)) & plci->adapter->profile.B1_Protocols)
&& ((READ_WORD(bp_parms[0].info) != 3)
|| !((1L << B1_HDLC) & plci->adapter->profile.B1_Protocols)
|| ((bp_parms[3].length != 0) && (READ_WORD(&bp_parms[3].info[1]) != 0) && (READ_WORD(&bp_parms[3].info[1]) != 56000)))))
{
return _B1_NOT_SUPPORTED;
}
plci->B1_resource = add_b1_facilities (plci, resource[READ_WORD(bp_parms[0].info)],
(word)(b1_facilities & ~B1_FACILITY_VOICE));
adjust_b1_facilities (plci, plci->B1_resource, (word)(b1_facilities & ~B1_FACILITY_VOICE));
cai[0] = 6;
cai[1] = plci->B1_resource;
for (i=2;i<sizeof(cai);i++) cai[i] = 0;
if ((READ_WORD(bp_parms[0].info) == B1_MODEM_ALL_NEGOTIATE)
|| (READ_WORD(bp_parms[0].info) == B1_MODEM_ASYNC)
|| (READ_WORD(bp_parms[0].info) == B1_MODEM_SYNC_HDLC))
{ /* B1 - modem */
for (i=0;i<7;i++) mdm_cfg[i].length = 0;
if (bp_parms[3].length)
{
if(api_parse(&bp_parms[3].info[1],(word)bp_parms[3].length,"wwwwww", mdm_cfg))
{
return (_WRONG_MESSAGE_FORMAT);
}
cai[2] = 0; /* Bit rate for adaptation */
dbug(1,dprintf("MDM Max Bit Rate:<%d>", READ_WORD(mdm_cfg[0].info)));
WRITE_WORD (&cai[13], 0); /* Min Tx speed */
WRITE_WORD (&cai[15], READ_WORD(mdm_cfg[0].info)); /* Max Tx speed */
WRITE_WORD (&cai[17], 0); /* Min Rx speed */
WRITE_WORD (&cai[19], READ_WORD(mdm_cfg[0].info)); /* Max Rx speed */
cai[3] = 0; /* Async framing parameters */
switch (READ_WORD (mdm_cfg[2].info))
{ /* Parity */
case 1: /* odd parity */
cai[3] |= (DSP_CAI_ASYNC_PARITY_ENABLE | DSP_CAI_ASYNC_PARITY_ODD);
dbug(1,dprintf("MDM: odd parity"));
break;
case 2: /* even parity */
cai[3] |= (DSP_CAI_ASYNC_PARITY_ENABLE | DSP_CAI_ASYNC_PARITY_EVEN);
dbug(1,dprintf("MDM: even parity"));
break;
default:
dbug(1,dprintf("MDM: no parity"));
break;
}
switch (READ_WORD (mdm_cfg[3].info))
{ /* stop bits */
case 1: /* 2 stop bits */
cai[3] |= DSP_CAI_ASYNC_TWO_STOP_BITS;
dbug(1,dprintf("MDM: 2 stop bits"));
break;
default:
dbug(1,dprintf("MDM: 1 stop bit"));
break;
}
switch (READ_WORD (mdm_cfg[1].info))
{ /* char length */
case 5:
cai[3] |= DSP_CAI_ASYNC_CHAR_LENGTH_5;
dbug(1,dprintf("MDM: 5 bits"));
break;
case 6:
cai[3] |= DSP_CAI_ASYNC_CHAR_LENGTH_6;
dbug(1,dprintf("MDM: 6 bits"));
break;
case 7:
cai[3] |= DSP_CAI_ASYNC_CHAR_LENGTH_7;
dbug(1,dprintf("MDM: 7 bits"));
break;
default:
dbug(1,dprintf("MDM: 8 bits"));
break;
}
cai[7] = 0; /* Line taking options */
cai[8] = 0; /* Modulation negotiation options */
cai[9] = 0; /* Modulation options */
if (((plci->call_dir & CALL_DIR_ORIGINATE) != 0) ^ ((plci->call_dir & CALL_DIR_OUT) != 0))
{
cai[9] |= DSP_CAI_MODEM_REVERSE_DIRECTION;
dbug(1, dprintf("MDM: Reverse direction"));
}
if (READ_WORD (mdm_cfg[4].info) & MDM_CAPI_DISABLE_RETRAIN)
{
cai[9] |= DSP_CAI_MODEM_DISABLE_RETRAIN;
dbug(1, dprintf("MDM: Disable retrain"));
}
if (READ_WORD (mdm_cfg[4].info) & MDM_CAPI_DISABLE_RING_TONE)
{
cai[7] |= DSP_CAI_MODEM_DISABLE_CALLING_TONE | DSP_CAI_MODEM_DISABLE_ANSWER_TONE;
dbug(1, dprintf("MDM: Disable ring tone"));
}
if (READ_WORD (mdm_cfg[4].info) & MDM_CAPI_GUARD_1800)
{
cai[8] |= DSP_CAI_MODEM_GUARD_TONE_1800HZ;
dbug(1, dprintf("MDM: 1800 guard tone"));
}
else if (READ_WORD (mdm_cfg[4].info) & MDM_CAPI_GUARD_550 )
{
cai[8] |= DSP_CAI_MODEM_GUARD_TONE_550HZ;
dbug(1, dprintf("MDM: 550 guard tone"));
}
if ((READ_WORD (mdm_cfg[5].info) & 0x00ff) == MDM_CAPI_NEG_V100)
{
cai[8] |= DSP_CAI_MODEM_NEGOTIATE_V100;
dbug(1, dprintf("MDM: V100"));
}
else if ((READ_WORD (mdm_cfg[5].info) & 0x00ff) == MDM_CAPI_NEG_MOD_CLASS)
{
cai[8] |= DSP_CAI_MODEM_NEGOTIATE_IN_CLASS;
dbug(1, dprintf("MDM: IN CLASS"));
}
else if ((READ_WORD (mdm_cfg[5].info) & 0x00ff) == MDM_CAPI_NEG_DISABLED)
{
cai[8] |= DSP_CAI_MODEM_NEGOTIATE_DISABLED;
dbug(1, dprintf("MDM: DISABLED"));
}
cai[0] = 20;
if ((plci->adapter->man_profile.private_options & (1L << PRIVATE_V18))
&& (READ_WORD(mdm_cfg[5].info) & 0x8000)) /* Private V.18 enable */
{
plci->requested_options |= 1L << PRIVATE_V18;
}
if (READ_WORD(mdm_cfg[5].info) & 0x4000) /* Private VOWN enable */
plci->requested_options |= 1L << PRIVATE_VOWN;
if ((plci->requested_options_conn | plci->requested_options | plci->adapter->requested_options_table[plci->appl->Id-1])
& ((1L << PRIVATE_V18) | (1L << PRIVATE_VOWN)))
{
if (!api_parse(&bp_parms[3].info[1],(word)bp_parms[3].length,"wwwwwws", mdm_cfg))
{
i = 27;
if (mdm_cfg[6].length >= 4)
{
d = READ_DWORD(&mdm_cfg[6].info[1]);
cai[7] |= (byte) d; /* line taking options */
cai[9] |= (byte)(d >> 8); /* modulation options */
cai[++i] = (byte)(d >> 16); /* vown modulation options */
cai[++i] = (byte)(d >> 24);
if (mdm_cfg[6].length >= 8)
{
d = READ_DWORD(&mdm_cfg[6].info[5]);
cai[10] |= (byte) d; /* disabled modulations mask */
cai[11] |= (byte)(d >> 8);
if (mdm_cfg[6].length >= 12)
{
d = READ_DWORD(&mdm_cfg[6].info[9]);
cai[12] = (byte) d; /* enabled modulations mask */
cai[++i] = (byte)(d >> 8); /* vown enabled modulations */
cai[++i] = (byte)(d >> 16);
cai[++i] = (byte)(d >> 24);
cai[++i] = 0;
if (mdm_cfg[6].length >= 14)
{
w = READ_WORD(&mdm_cfg[6].info[13]);
if (w != 0)
WRITE_WORD(&cai[13], w); /* min tx speed */
if (mdm_cfg[6].length >= 16)
{
w = READ_WORD(&mdm_cfg[6].info[15]);
if (w != 0)
WRITE_WORD(&cai[15], w); /* max tx speed */
if (mdm_cfg[6].length >= 18)
{
w = READ_WORD(&mdm_cfg[6].info[17]);
if (w != 0)
WRITE_WORD(&cai[17], w); /* min rx speed */
if (mdm_cfg[6].length >= 20)
{
w = READ_WORD(&mdm_cfg[6].info[19]);
if (w != 0)
WRITE_WORD(&cai[19], w); /* max rx speed */
if (mdm_cfg[6].length >= 22)
{
w = READ_WORD(&mdm_cfg[6].info[21]);
cai[23] = (byte)(-((short) w)); /* transmit level */
if (mdm_cfg[6].length >= 24)
{
w = READ_WORD(&mdm_cfg[6].info[23]);
cai[22] |= (byte) w; /* info options mask */
cai[21] |= (byte)(w >> 8); /* disabled symbol rates */
}
}
}
}
}
}
}
}
}
cai[27] = i - 27;
i++;
if (!api_parse(&bp_parms[3].info[1],(word)bp_parms[3].length,"wwwwwwss", mdm_cfg))
{
if (!api_parse(&mdm_cfg[7].info[1],(word)mdm_cfg[7].length,"sss", mdm_cfg_v18))
{
for (n = 0; n < 3; n++)
{
cai[i] = (byte)(mdm_cfg_v18[n].length);
for (j = 1; j < ((word)(cai[i] + 1)); j++)
cai[i+j] = mdm_cfg_v18[n].info[j];
i += cai[i] + 1;
}
}
}
cai[0] = (byte)(i - 1);
}
}
}
}
if(READ_WORD(bp_parms[0].info)==2 || /* V.110 async */
READ_WORD(bp_parms[0].info)==3 ) /* V.110 sync */
{
if(bp_parms[3].length){
dbug(1,dprintf("V.110,%d",READ_WORD(&bp_parms[3].info[1])));
switch(READ_WORD(&bp_parms[3].info[1])){ /* Rate */
case 0:
case 56000:
if(READ_WORD(bp_parms[0].info)==3){ /* V.110 sync 56k */
dbug(1,dprintf("56k sync HSCX"));
cai[1] = 8;
cai[2] = 0;
cai[3] = 0;
}
else if(READ_WORD(bp_parms[0].info)==2){
dbug(1,dprintf("56k async DSP"));
cai[2] = 9;
}
break;
case 50: cai[2] = 1; break;
case 75: cai[2] = 1; break;
case 110: cai[2] = 1; break;
case 150: cai[2] = 1; break;
case 200: cai[2] = 1; break;
case 300: cai[2] = 1; break;
case 600: cai[2] = 1; break;
case 1200: cai[2] = 2; break;
case 2400: cai[2] = 3; break;
case 4800: cai[2] = 4; break;
case 7200: cai[2] = 10; break;
case 9600: cai[2] = 5; break;
case 12000: cai[2] = 13; break;
case 24000: cai[2] = 0; break;
case 14400: cai[2] = 11; break;
case 19200: cai[2] = 6; break;
case 28800: cai[2] = 12; break;
case 38400: cai[2] = 7; break;
case 48000: cai[2] = 8; break;
case 76: cai[2] = 15; break; /* 75/1200 */
case 1201: cai[2] = 14; break; /* 1200/75 */
case 56001: cai[2] = 9; break; /* V.110 56000 */
default:
return _B1_PARM_NOT_SUPPORTED;
}
cai[3] = 0;
if (cai[1] == 13) /* v.110 async */
{
if (bp_parms[3].length >= 8)
{
switch (READ_WORD (&bp_parms[3].info[3]))
{ /* char length */
case 5:
cai[3] |= DSP_CAI_ASYNC_CHAR_LENGTH_5;
break;
case 6:
cai[3] |= DSP_CAI_ASYNC_CHAR_LENGTH_6;
break;
case 7:
cai[3] |= DSP_CAI_ASYNC_CHAR_LENGTH_7;
break;
}
switch (READ_WORD (&bp_parms[3].info[5]))
{ /* Parity */
case 1: /* odd parity */
cai[3] |= (DSP_CAI_ASYNC_PARITY_ENABLE | DSP_CAI_ASYNC_PARITY_ODD);
break;
case 2: /* even parity */
cai[3] |= (DSP_CAI_ASYNC_PARITY_ENABLE | DSP_CAI_ASYNC_PARITY_EVEN);
break;
}
switch (READ_WORD (&bp_parms[3].info[7]))
{ /* stop bits */
case 1: /* 2 stop bits */
cai[3] |= DSP_CAI_ASYNC_TWO_STOP_BITS;
break;
}
}
}
}
else if(cai[1]==8 || READ_WORD(bp_parms[0].info)==3 ){
dbug(1,dprintf("V.110 default 56k sync"));
cai[1] = 8;
cai[2] = 0;
cai[3] = 0;
}
else {
dbug(1,dprintf("V.110 default 9600 async"));
cai[2] = 5;
}
}
WRITE_WORD(&cai[5],plci->appl->MaxDataLength);
dbug(1,dprintf("CAI[%d]=%x,%x,%x,%x,%x,%x", cai[0], cai[1], cai[2], cai[3], cai[4], cai[5], cai[6]));
/* HexDump ("CAI", sizeof(cai), &cai[0]); */
add_p(plci, CAI, cai);
return 0;
}
Generated by GNU enscript 1.6.4.