📄 at_trans.c
字号:
/****************************************************************
** *
** FILE : AT_Trans.C *
** COPYRIGHT : (c) 2001 .Xiamen Yaxon NetWork CO.LTD *
** *
** *
** By : CCH 2002.1.15 *
****************************************************************/
#include "includes.h"
#include "bsp.h"
#include "message.h"
#include "errtask.h"
#include "gsmtask.h"
#include "tools.h"
#include "timetask.h"
#include "at_cmd.h"
#include "at_core.h"
#include "at_trans.h"
#include "dlcs.h"
#include "phonedrv.h"
#include "ZPrint.h"
/*
********************************************************************************
* DEFINE CONFIG PARAMETERS
********************************************************************************
*/
#define MAX_TCB 4
/* define TCB1 buffer size */
#define SIZE_ACKBUF_1 20
#define SIZE_RECVBUF_1 50
/* define TCB2 buffer size */
#define SIZE_ACKBUF_2 20
#define SIZE_RECVBUF_2 50
/* define TCB3 buffer size */
#define SIZE_ACKBUF_3 20
#define SIZE_RECVBUF_3 50
/* define timer period */
#define PERIOD_WAIT MILTICK, 2
#define PERIOD_TEST MILTICK, 2
/* define times of test send */
#define MAX_TEST ((OS_TICKS_PER_SEC * 4) / 2) /* 2 = PERIOD_TEST */
/*
********************************************************************************
* DEFINE AT COMMAND CONTROL BLOCK STRUCTURE
********************************************************************************
*/
typedef struct {
BOOLEAN opened; /* open status */
BOOLEAN echo; /* echo status */
TMR_TSK *waittmr; /* wait timer */
TMR_TSK *overflowtmr; /* overflow timer */
INT16U bufsize; /* receive buffer size */
INT8U *recvbuf; /* receive buffer */
ATCMDACK_STRUCT atcmdack; /* at command ack */
INT8U status; /* command status */
INT8U ct_test; /* test times */
INT8U overtime; /* overflow time */
INT8U nsEC; /* number of END'S characters(send) */
INT8U naEC; /* number of END'S characters(ack) */
INT8U nrEC; /* number of END'S characters(receive) */
INT16U wlen; /* write length */
INT8U *wptr; /* write position */
INT16U sendlen; /* send data length */
INT8U *sendptr; /* send data buffer */
void (* informer)(INT8U, const ATCMDACK_STRUCT *); /* command informer */
INT16S (* handler)(INT8U *, INT16U, ATCMDACK_STRUCT *); /* command handler */
} TCB_STRUCT;
/*
********************************************************************************
* DEFINE MODULE VARIANT
********************************************************************************
*/
static TCB_STRUCT *TCB[MAX_TCB];
/* define TCB1 variants */
static TCB_STRUCT TCB1;
static INT8U ackbuf_1[SIZE_ACKBUF_1];
static INT8U recvbuf_1[SIZE_RECVBUF_1];
/* define TCB2 variants */
static TCB_STRUCT TCB2;
static INT8U ackbuf_2[SIZE_ACKBUF_2];
static INT8U recvbuf_2[SIZE_RECVBUF_2];
/* define TCB3 variants */
static TCB_STRUCT TCB3;
static INT8U ackbuf_3[SIZE_ACKBUF_3];
static INT8U recvbuf_3[SIZE_RECVBUF_3];
static void DelTCB(INT8U id, INT8U reason)
{
if (TCB[id] == NULL) return;
if (TCB[id]->status & ATCMD_EXIST) {
TCB[id]->status &= ~ATCMD_EXIST;
TCB[id]->status |= ATCMD_WAIT;
StartTmr(TCB[id]->waittmr, PERIOD_WAIT);
StopTmr(TCB[id]->overflowtmr);
if (TCB[id]->informer != 0) TCB[id]->informer(reason, &TCB[id]->atcmdack);
}
OSQPost(GsmTaskMsgQue, MSG_ATTRANS_FREE, 0, 0);
}
static void StartSend(INT8U id)
{
if (TCB[id] == NULL) return;
if ((TCB[id]->status & (ATCMD_EXIST | ATCMD_READY)) != (ATCMD_EXIST | ATCMD_READY)) return;
if (PushDatatoDLC(id, TCB[id]->sendptr, TCB[id]->sendlen)) {
TCB[id]->status &= ~ATCMD_READY;
StartTmr(TCB[id]->overflowtmr, SECOND, TCB[id]->overtime);
if (!TCB[id]->echo && TCB[id]->naEC == 0)
DelTCB(id, AT_SUCCESS);
if (TCB[id]->nsEC == 0)
DelTCB(id, AT_SUCCESS);
} else {
StartTmr(TCB[id]->overflowtmr, PERIOD_TEST);
if (--TCB[id]->ct_test == 0)
ErrExit(ERR_ATTRANS_TEST);
}
}
static void WaitTmrProc(void)
{
INT8U id;
id = GetCurTmrIndex();
StopTmr(TCB[id]->waittmr);
TCB[id]->status &= ~ATCMD_WAIT;
OSQPost(GsmTaskMsgQue, MSG_ATTRANS_FREE, 0, 0);
}
static void OverflowTmrProc(void)
{
INT8U id;
id = GetCurTmrIndex();
StopTmr(TCB[id]->overflowtmr);
if ((TCB[id]->status & (ATCMD_EXIST | ATCMD_READY)) == (ATCMD_EXIST | ATCMD_READY)) {
StartSend(id);
} else {
RecoveryATCmd(id);
DelTCB(id, AT_OVERTIME);
}
}
static void DiagnoseProc(void)
{
INT8U i;
for (i = 0; i < MAX_TCB; i++) {
if (TCB[i] == NULL) continue;
if ((TCB[i]->status & (ATCMD_EXIST | ATCMD_READY)) == ATCMD_EXIST) {
if (GetTmrSwitch(TCB[i]->overflowtmr) != ON) ErrExit(ERR_ATTRANS_TMR);
}
if (TCB[i]->status & ATCMD_WAIT) {
if (GetTmrSwitch(TCB[i]->waittmr) != ON) ErrExit(ERR_ATTRANS_TMR);
}
}
}
void InitAT_Trans(void)
{
INT8U i;
/* initialize TCB1 */
{
TCB1.recvbuf = recvbuf_1;
TCB1.bufsize = sizeof(recvbuf_1);
TCB1.atcmdack.ackbuf = ackbuf_1;
TCB1.atcmdack.bufsize = sizeof(ackbuf_1);
}
/* initialize TCB2 */
{
TCB2.recvbuf = recvbuf_2;
TCB2.bufsize = sizeof(recvbuf_2);
TCB2.atcmdack.ackbuf = ackbuf_2;
TCB2.atcmdack.bufsize = sizeof(ackbuf_2);
}
/* initialize TCB3 */
{
TCB3.recvbuf = recvbuf_3;
TCB3.bufsize = sizeof(recvbuf_3);
TCB3.atcmdack.ackbuf = ackbuf_3;
TCB3.atcmdack.bufsize = sizeof(ackbuf_3);
}
/* initialize TCB array */
{
TCB[0] = NULL;
TCB[1] = &TCB1;
TCB[2] = &TCB2;
TCB[3] = &TCB3;
}
for (i = 0; i < MAX_TCB; i++) {
if (TCB[i] == NULL) continue;
TCB[i]->opened = TRUE;
TCB[i]->echo = TRUE;
TCB[i]->status = 0;
TCB[i]->waittmr = CreateTimer(WaitTmrProc, i);
TCB[i]->overflowtmr = CreateTimer(OverflowTmrProc, i);
}
InstallDiagProc(DiagnoseProc); /* install diagnose procedure */
}
BOOLEAN SendATCmd(INT8U id, ATCMDPARA_STRUCT *cmdptr, INT8U *ptr, INT16U len, void (* fp)(INT8U, const ATCMDACK_STRUCT *))
{
if (TCB[id] == NULL) return FALSE;
if (!TCB[id]->opened || TCB[id]->status & ATCMD_EXIST) return FALSE;
TCB[id]->status = cmdptr->status;
if (TCB[id]->status & ATCMD_INSANT) {
TCB[id]->naEC = 1;
TCB[id]->atcmdack.numEC = 0;
} else {
TCB[id]->naEC = cmdptr->naEC;
}
TCB[id]->nsEC = cmdptr->nsEC;
TCB[id]->overtime = cmdptr->overtime;
TCB[id]->handler = cmdptr->handler;
TCB[id]->status |= (ATCMD_EXIST | ATCMD_READY);
TCB[id]->ct_test = MAX_TEST;
TCB[id]->nrEC = 0;
TCB[id]->wlen = 0;
TCB[id]->wptr = TCB[id]->recvbuf;
TCB[id]->sendlen = len;
TCB[id]->sendptr = ptr;
TCB[id]->informer = fp;
OSQPost(GsmTaskMsgQue, MSG_ATTRANS_TSK, 0, 0);
return TRUE;
}
void StopATCmd(INT8U id, INT8U reason)
{
if (TCB[id] == NULL) return;
DelTCB(id, reason);
}
void AbandonATCmd(INT8U id)
{
if (TCB[id] == NULL) return;
if ((TCB[id]->status & (ATCMD_EXIST | ATCMD_READY)) == ATCMD_EXIST) RecoveryATCmd(id);
DelTCB(id, AT_ABANDON);
}
void AbandonAllATCmd(void)
{
INT8U i;
for (i = 0; i < MAX_TCB; i++) AbandonATCmd(i);
}
BOOLEAN CanSendATCmd(INT8U id)
{
#if GSM_BENQ
if((GetPhoneStatus(PHONE_COM)==PHONE_CONNECTING)&&(id==DLC_SM)) return FALSE;
#endif
if (TCB[id] == NULL) return FALSE;
if (!TCB[id]->opened) return FALSE;
if (TCB[id]->status & (ATCMD_EXIST | ATCMD_WAIT)) return FALSE;
else return TRUE;
}
BOOLEAN EchoOnATTrans(INT8U id)
{
if (TCB[id] == NULL) return FALSE;
TCB[id]->echo = TRUE;
return TRUE;
}
BOOLEAN EchoOffATTrans(INT8U id)
{
if (TCB[id] == NULL) return FALSE;
TCB[id]->echo = FALSE;
return TRUE;
}
BOOLEAN OpenATTrans(INT8U id)
{
if (TCB[id] == NULL) return FALSE;
TCB[id]->opened = TRUE;
OSQPost(GsmTaskMsgQue, MSG_ATTRANS_FREE, 0, 0);
return TRUE;
}
BOOLEAN CloseATTrans(INT8U id)
{
if (TCB[id] == NULL) return FALSE;
TCB[id]->opened = FALSE;
return TRUE;
}
void CloseAllATTrans(void)
{
INT8U i;
for (i = 0; i < MAX_TCB; i++) CloseATTrans(i);
}
void HdlATCmdTrans(void)
{
INT8U i;
for (i = 0; i < MAX_TCB; i++) StartSend(i);
}
BOOLEAN HdlATCmdAck(INT8U id, INT8U *sptr, INT16U len)
{
INT8U nsEC;
INT16S hdlres;
if (TCB[id] == NULL || len <= 3) return FALSE;
if ((TCB[id]->status & (ATCMD_EXIST | ATCMD_READY)) == ATCMD_EXIST) {
if (TCB[id]->echo && TCB[id]->nsEC == 1 && TCB[id]->nrEC == 0) {
/* if (!SearchDataInMem(sptr, len, TCB[id]->sendptr, TCB[id]->sendlen))
return FALSE; */
}
TCB[id]->nrEC++;
if (TCB[id]->echo && TCB[id]->nrEC <= TCB[id]->nsEC) {
if (TCB[id]->nrEC == TCB[id]->nsEC && TCB[id]->naEC == 0)
{
DelTCB(id, AT_SUCCESS);
}
} else {
TCB[id]->atcmdack.numEC++;
if (TCB[id]->status & ATCMD_INSANT) {
if (TCB[id]->handler == 0) {
DelTCB(id, AT_FAILURE);
} else {
if ((hdlres = TCB[id]->handler(sptr, len, &TCB[id]->atcmdack)) != -1)
DelTCB(id, hdlres);
}
} else {
if ((TCB[id]->wlen + len) > TCB[id]->bufsize) {
DelTCB(id, AT_FAILURE);
return TRUE;
}
memcpy(TCB[id]->wptr, sptr, len);
TCB[id]->wptr += len;
TCB[id]->wlen += len;
if (TCB[id]->echo) nsEC = TCB[id]->nsEC;
else nsEC = 0;
if (TCB[id]->nrEC == (nsEC + TCB[id]->naEC)) {
if (TCB[id]->handler == 0)
DelTCB(id, AT_FAILURE);
else
DelTCB(id, TCB[id]->handler(TCB[id]->recvbuf, TCB[id]->wlen, &TCB[id]->atcmdack));
}
}
}
return TRUE;
} else {
return FALSE;
}
}
BOOLEAN SuspendATRecv(INT8U id)
{
if (TCB[id] == NULL) return FALSE;
if ((TCB[id]->status & (ATCMD_EXIST | ATCMD_SUSPENDRECV)) == (ATCMD_EXIST | ATCMD_SUSPENDRECV))
return TRUE;
else
return FALSE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -