📄 dlcs.c
字号:
/****************************************************************
** *
** FILE : DLCS.C *
** COPYRIGHT : (c) 2001 .Xiamen Yaxon NetWork CO.LTD *
** *
** *
** By : CCH 2002.11.26 *
****************************************************************/
#include "includes.h"
#include "bsp.h"
#include "errtask.h"
#include "message.h"
#include "timetask.h"
#include "list.h"
#include "roundbuf.h"
#include "crc.h"
#include "dlcrecv.h"
#include "dlccmd.h"
#include "dlcs.h"
#include "gsmtask.h"
#include "ZPrint.h"
#define DLCSSEND_DEBUG 0
#define IO_DEBUG 0
#if DEBUG_DLC_IO > 0
#undef WriteDLCIO
#define WriteDLCIO(ch) { uarts_write(UART_GSMIO, ch); \
SendFromUART_HEX(DEBUG_UARTNo_DLC, ch); }
#endif
/*
********************************************************************************
* DEFINE CONFIG PARAMETERS
********************************************************************************
*/
#define S_BUFSIZE0 256
#define R_BUFSIZE0 256
#define S_BUFSIZE1 2248
#define R_BUFSIZE1 2048
#define S_BUFSIZE2 512
#define R_BUFSIZE2 512
#define S_BUFSIZE3 256
#define R_BUFSIZE3 256
#define MAX_SENDRDY 128
#define MAX_DLCS 4
#define PERIOD_SCAN MILTICK, 1
/*
********************************************************************************
* DEFINE DLCS STATUS
********************************************************************************
*/
#define DLC_CLOSED 0x00 /* for all channels */
#define DLC_CLOSING 0x01 /* for all channels */
#define DLC_OPENING 0x02 /* for all channels */
#define DLC_OPENED 0x03 /* for all channels */
#define DLC_MASK 0x0F /* mask bits */
#define DLC_DATAMODE 0x40 /* for channel 1,2,3 */
#define DLC_SHIELD 0x80 /* for all channels */
/*
********************************************************************************
* DEFINE DLCS_STRUCT
********************************************************************************
*/
typedef struct {
INT8U status; /* DLC status */
INT8U signal; /* V.24 siganls */
LIST cmdlist; /* current command list */
INT8U prechar; /* previous character */
ROUNDBUF_STRUCT s_round; /* send round */
ROUNDBUF_STRUCT r_round; /* receive round */
INT8U *s_buf; /* send buffer */
INT16U s_bufsize; /* send buffer size */
INT8U *r_buf; /* receive buffer */
INT16U r_bufsize; /* receive buffer size */
} DLCS_STRUCT;
/*
********************************************************************************
* DEFINE MODULE VARIANT
********************************************************************************
*/
static DLCS_STRUCT dlcs[MAX_DLCS];
static TMR_TSK *scantmr;
static INT8U s_buf0[S_BUFSIZE0], r_buf0[R_BUFSIZE0];
static INT8U s_buf1[S_BUFSIZE1], r_buf1[R_BUFSIZE1];
static INT8U s_buf2[S_BUFSIZE2], r_buf2[R_BUFSIZE2];
static INT8U s_buf3[S_BUFSIZE3], r_buf3[R_BUFSIZE3];
static void ClearDLCS(void)
{
INT8U i;
for (i = 0; i < MAX_DLCS; i++) {
dlcs[i].status = DLC_CLOSED;
InitList(&dlcs[i].cmdlist);
}
ResetDLCCmd();
}
static void OpenDLC(INT8U dlci, BOOLEAN shielded)
{
if (dlci >= MAX_DLCS) return;
InitRoundBuf(&dlcs[dlci].s_round, dlcs[dlci].s_buf, dlcs[dlci].s_bufsize, NULL);
InitRoundBuf(&dlcs[dlci].r_round, dlcs[dlci].r_buf, dlcs[dlci].r_bufsize, NULL);
dlcs[dlci].prechar = 0;
dlcs[dlci].status &= (~DLC_MASK);
dlcs[dlci].status |= DLC_OPENED;
dlcs[dlci].status &= (~DLC_DATAMODE);
if (shielded) dlcs[dlci].status |= DLC_SHIELD;
else dlcs[dlci].status &= (~DLC_SHIELD);
/* handle DLC V.24 signals */
dlcs[dlci].signal = (SIG_DTR | SIG_RTS | SIG_DSR | SIG_CTS);
/*if (!shielded) {
if (!ControlDLCSignal(dlci, dlcs[dlci].signal)) {
ErrExit(ERR_DLCS_CTLSIGNAL);
}
}*/
#if DEBUG_DLC_STATUS > 0
PrintFromUART(DEBUG_UARTNo_DLC, "<");
SendFromUART_HEX(DEBUG_UARTNo_DLC, dlci);
PrintFromUART(DEBUG_UARTNo_DLC, " DLC is opend>\n");
#endif
}
static void CloseDLC(INT8U dlci)
{
if (dlci >= MAX_DLCS) return;
dlcs[dlci].status &= (~DLC_MASK);
dlcs[dlci].status |= DLC_CLOSED;
}
static void Hdl_TYPE_UA(void)
{
INT8U dlci;
DLCCMD_STRUCT *curcmd;
void (*informer)(INT8U dlci, INT8U reason);
dlci = DLCRecv.addr >> 2;
#if DEBUG_DLC_STATUS > 0
PrintFromUART(DEBUG_UARTNo_DLC, "<");
SendFromUART_HEX(DEBUG_UARTNo_DLC, dlci);
PrintFromUART(DEBUG_UARTNo_DLC, " DLC receive UA>\n");
#endif
if (dlci >= MAX_DLCS) return;
curcmd = (DLCCMD_STRUCT *)GetListHead(&dlcs[dlci].cmdlist);
if (curcmd != NULL) {
informer = curcmd->informer;
if (curcmd->ctltype == TYPE_SABM) { /* set asynchronous balanced mode */
DelListHead(&dlcs[dlci].cmdlist);
FreeDLCCmd(curcmd);
OpenDLC(dlci, FALSE); /* here, DLC is opened */
if (informer != NULL) informer(dlci, _SUCCESS);
} else if (curcmd->ctltype == TYPE_DISC) { /* disconnect */
DelListHead(&dlcs[dlci].cmdlist);
FreeDLCCmd(curcmd);
CloseDLC(dlci); /* here, DLC is closed */
if (informer != NULL) informer(dlci, _SUCCESS);
}
}
}
BOOLEAN GetDCD_VALID(INT8U dlci)
{
if(dlcs[dlci].signal & SIG_DCD) return TRUE;
else return FALSE;
}
static void Hdl_TYPE_MSC(void)
{
INT8U signals, dlci;
DLCCMD_STRUCT *curcmd;
#if DEBUG_DLC_STATUS > 0
PrintFromUART(DEBUG_UARTNo_DLC, "<receive MSC>\n");
#endif
if (DLCRecv.inf[0] & 0x02) { /* C/R = 1 */
dlci = DLCRecv.inf[2] >> 2; /* get control channel */
if (dlci >= MAX_DLCS) return;
signals = DLCRecv.inf[3];
if (signals & 0x02) dlcs[dlci].signal |= SIG_FCS_S; /* V.24 signals DATA SET control flow */
else dlcs[dlci].signal &= (~SIG_FCS_S);
if (signals & 0x04) dlcs[dlci].signal |= SIG_DSR; /* V.24 signals DSR */
else dlcs[dlci].signal &= (~SIG_DSR);
if (signals & 0x08) dlcs[dlci].signal |= SIG_CTS; /* V.24 signals CTS */
else dlcs[dlci].signal &= (~SIG_CTS);
if (signals & 0x40) dlcs[dlci].signal |= SIG_RI; /* V.24 signals RI */
else dlcs[dlci].signal &= (~SIG_RI);
if (signals & 0x80) dlcs[dlci].signal |= SIG_DCD; /* V.24 signals DCD */
else dlcs[dlci].signal &= (~SIG_DCD);
// if (DLCRecv.inf[0]==0xE3) {
// curcmd = AllocDLCCmd_MSC(dlci, signals, TRUE); /* respond to this command */
// if(curcmd!=NULL) AppendListEle(&dlcs[0].cmdlist, (LISTMEM *)curcmd); /* append to control channel command list */
// Printu("AppendListEle\r\n");
//}
//else{
//Printu("MSC Else\r\n");
//curcmd = (DLCCMD_STRUCT *)GetListHead(&dlcs[0].cmdlist);
//if (curcmd != NULL) {
// if (curcmd->cmdtype == 0xE3) {
// DelListHead(&dlcs[0].cmdlist); /* delete from control channel command list */
// FreeDLCCmd(curcmd); /* free DLC command */
//}
//}
//}
} else { /* C/R = 0 */
curcmd = (DLCCMD_STRUCT *)GetListHead(&dlcs[0].cmdlist);
if (curcmd != NULL) {
if (curcmd->cmdtype == 0xe3) {
DelListHead(&dlcs[0].cmdlist); /* delete from control channel command list */
FreeDLCCmd(curcmd); /* free DLC command */
}
}
}
}
static void Hdl_TYPE_UIH(void)
{
INT8U dlci, i;
dlci = DLCRecv.addr >> 2;
#if DEBUG_DLC_STATUS > 0
PrintFromUART(DEBUG_UARTNo_DLC, "<");
SendFromUART_HEX(DEBUG_UARTNo_DLC, dlci);
PrintFromUART(DEBUG_UARTNo_DLC, " receive UIH>\n");
#endif
if (dlci >= MAX_DLCS) return;
if (dlci == 0) { /* for control channel */
if ((DLCRecv.inf[0] & (~0x03)) == TYPE_MSC)
Hdl_TYPE_MSC();
} else {
for (i = 0; i < DLCRecv.len-1; i++) {
#if GSM_BENQ /* Convert Escape Oct */
if(DLCRecv.inf[i]==DLC_ESCAPE_OCT){
DLCRecv.inf[++i] |= 0x20;
}
#endif
// OS_ENTER_CRITICAL();
WriteDLCRecvRound(dlci, DLCRecv.inf[i]);
//OS_EXIT_CRITICAL();
}
}
}
static void CheckCmdList(void)
{
INT8U i;
DLCCMD_STRUCT *curcmd;
void (*informer)(INT8U dlci, INT8U reason);
for (i = 0; i < MAX_DLCS; i++) {
if ((curcmd = (DLCCMD_STRUCT *)GetListHead(&dlcs[i].cmdlist)) == NULL) continue;
if (!curcmd->needresend) continue;
if (curcmd->ct_overflow < DLC_OVERFLOW) curcmd->ct_overflow++;
if (curcmd->ct_send == 0 && curcmd->ct_overflow >= DLC_OVERFLOW) {
switch (curcmd->ctltype)
{
case TYPE_SABM:
break;
case TYPE_DISC:
break;
case TYPE_UIH:
break;
default:
break;
}
informer = curcmd->informer;
DelListHead(&dlcs[i].cmdlist);
FreeDLCCmd(curcmd);
if (informer != NULL) informer(i, _OVERTIME);
ErrExit(ERR_DLCS_OVERFLOW); /* error exit */
}
}
}
static BOOLEAN ScanCmdList(void)
{
INT8U i, pos;
BOOLEAN scan;
DLCCMD_STRUCT *curcmd;
void (*informer)(INT8U dlci, INT8U reason);
scan = FALSE;
for (i = 0; i < MAX_DLCS; i++) {
if ((curcmd = (DLCCMD_STRUCT *)GetListHead(&dlcs[i].cmdlist)) == NULL) continue;
if (curcmd->ct_overflow < DLC_OVERFLOW) continue;
if (curcmd->len > LeftDLCIO()) continue;
scan = TRUE;
#if DEBUG_DLC_IO > 0
PrintFromUART(DEBUG_UARTNo_DLC, "\n");
SendFromUART_HEX(DEBUG_UARTNo_DLC, i);
PrintFromUART(DEBUG_UARTNo_DLC, " DLC send: ");
#endif
for (pos = 0; pos < curcmd->len; pos++) {
WriteDLCIO(curcmd->buffer[pos]);
}
if (!curcmd->needresend) {
informer = curcmd->informer;
DelListHead(&dlcs[i].cmdlist);
FreeDLCCmd(curcmd);
if (informer != NULL) informer(i, _SUCCESS);
} else {
curcmd->ct_send--;
curcmd->ct_overflow = 0;
}
}
return scan;
}
static void ScanSendround(void)
{
INT16U len;
INT8U temp, crc, i;
for (i = 0; i < MAX_DLCS; i++) {
if ((dlcs[i].status & DLC_MASK) != DLC_OPENED) continue;
if (dlcs[i].status & DLC_SHIELD) {
len = UsedOfRoundBuf(&dlcs[i].s_round);
if (len == 0 || len > LeftDLCIO()) continue;
#if DEBUG_DLC_IO > 0
PrintFromUART(DEBUG_UARTNo_DLC, "\n");
SendFromUART_HEX(DEBUG_UARTNo_DLC, i);
PrintFromUART(DEBUG_UARTNo_DLC, " DLC send: ");
#endif
for (; len > 0; len--) {
temp = ReadRoundBuf(&dlcs[i].s_round);
WriteDLCIO(temp);
}
} else {
for (;;) {
if ((len = UsedOfRoundBuf(&dlcs[i].s_round)) >= MAX_SENDRDY) len = MAX_SENDRDY;
if (len == 0 || LeftDLCIO() < (len + 6)) break;
#if DEBUG_DLC_IO > 0
PrintFromUART(DEBUG_UARTNo_DLC, "\n");
SendFromUART_HEX(DEBUG_UARTNo_DLC, i);
PrintFromUART(DEBUG_UARTNo_DLC, " DLC send: ");
#endif
InitCrc(&crc);
WriteDLCIO(DLC_FLAG); /* FLAG */
temp = i << 2;
temp |= 0x03;
CalcCrcByByte(&crc, temp);
WriteDLCIO(temp); /* ADDRESS */
#if GSM_BENQ
temp = ReadRoundBufNoMVPtr(&dlcs[i].s_round);
if(temp==(TYPE_MSC|0x03)){
CalcCrcByByte(&crc, 0xFF);
WriteDLCIO(0xff);
}
else{
CalcCrcByByte(&crc, TYPE_UIH);
WriteDLCIO(TYPE_UIH); /* CONTROL TYPE */
}
#else
CalcCrcByByte(&crc, TYPE_UIH);
WriteDLCIO(TYPE_UIH); /* CONTROL TYPE */
temp = len << 1;
temp |= 0x01;
CalcCrcByByte(&crc, temp);
WriteDLCIO(temp); /* LENGTH */
#endif
for (; len > 0; len--) { /* INFORMATION */
temp = ReadRoundBuf(&dlcs[i].s_round);
#if GSM_BENQ /* Control Escape Oct */
if((temp==DLC_FLAG)||(temp==DLC_ESCAPE_OCT)){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -