Цитата(bloodden @ Aug 29 2008, 17:02)

Очень любопытно узнать как кто-то другой с этим боролся. Не могли бы Вы поделиться опытом/кодом.
см выше, задача была специфическая.
особенности:
getchar неблокирующий
в целом, приём данных по терминалу блокирующий, но с таймаутом
парсились цифровые аргументы, возвращаемые at командой
Там пара файлов, если будут вопросы, другие файлы могу выложить
пример использования функции WaitForAnswer():
Код
//-----------------------------------------------------------------------------
//try to set memory as mem1 in gsmModem (suggest connection is open):
unsigned char TestPhoneMemoryAsClass1(const PHONE_MEMORY *pmemToTest)
{
//send: AT_CPMS=memToTest[CRLF]
FlushUartRxBuffer();
SendAtCommandWithArgsF(&cpmsComm, pmemToTest->pmemString);
if(WaitForAnswer(atMemoryTimeoutMs, "\r\n+CPMS", 0) == WAIT_OK)
{
__delay_cycles(1000000);
return SUCCESS_CODE;
}
return ERROR_CODE;
}
//-----------------------------------------------------------------------------
Использование функции GetAtAnswerArgs():
Код
//-----------------------------------------------------------------------------
//listTactics affects on at_commands, used for listing
//ppsubmitPosBuf - address of ptr to the smsPosBuffer
//ppdeliveryPosBuf - address of ptr, used to return deliveryPosBuf start address
unsigned char ListSmsToBufRef(LIST_DATA *plistData)
{
WaitUntilNoUartInput(WAIT_UART_NO_INPUT_MSECONDS);
FlushUartRxBuffer();
unsigned char buf[6] = {0};
unsigned char submitIndex = 0;
unsigned char deliveryIndex = 0;
SMS_POSITION pos = {0};
unsigned char listedCounter = 0;
const unsigned char listedBufSize = plistData->submitListedNumb;
//const unsigned char maxPos = plistData->minPos + listedBufSize;
unsigned int maxReceivedPos = plistData->minPos;
UIntToStr(plistData->tactics, buf, sizeof(buf));
SendAtCommandWithArgs(&cmglComm, (char*)buf + 5);
if(WaitForAnswer(atTimeoutMs * 4, "\r\n", 0) != WAIT_OK)
{
return ERROR_CODE;
}
//for each +cmgl answer:*/
while(1 /*listedCounter < listedBufSize*/)
{
if(WaitForAnswerDual(atTimeoutMs, "+CMGL: ", "\r\nOK\r\n", 0) != WAIT_OK_1)
{
break;
}
AT_ANSWER_ARGUMENT argBuf[5] = {0};
unsigned char receivedArgs = sizeof(argBuf) / sizeof(AT_ANSWER_ARGUMENT);
if(GetAtAnswerArgs(argBuf, &receivedArgs, atTimeoutMs * 4) != SUCCESS_CODE)
{
break;
}
//now we can get info from args:
if(argBuf[0].isSet != 1)
{
break;
}
pos.position = argBuf[0].argVal;
//pass message if it is out of range or listedBuf is full
if((pos.position < plistData->minPos) ||
((deliveryIndex + submitIndex) == listedBufSize))
{
if(PassPduRest(atTimeoutMs * 3) != SUCCESS_CODE)
{
//return ERROR_CODE;
}
continue;
}
if(maxReceivedPos < pos.position)
{
maxReceivedPos = pos.position;
}
//here we analyze pdu type (submit or delivery)
//and place pos info to appropriate buffPart (head or tail)
if(PassSMSCNumber(atTimeoutMs * 10) != SUCCESS_CODE)
{
break;
}
unsigned int typeCode = 0;
if(ReceivePduTypeCode(&typeCode, atTimeoutMs) != SUCCESS_CODE)
{
break;
}
if((typeCode & 0x01) != 0)
{
//submitPdu
(plistData->psubmitPosBuf)[submitIndex++] = pos;
}
else if((typeCode & 0x03) == 0)
{
//deliveryPdu
const unsigned char deliveryShift = listedBufSize -
deliveryIndex++ - 1;
(plistData->psubmitPosBuf)[deliveryShift] = pos;
plistData->pdeliveryPosBuf =
plistData->psubmitPosBuf + deliveryShift;
}
else
{
//error: unknown typeCode for pdu
return ERROR_CODE;
}
++listedCounter;
if(PassPduRest(atTimeoutMs * 3) != SUCCESS_CODE)
{
return ERROR_CODE;
}
}//while(listedCounter < listedBufSize)
//endReceive:
if((deliveryIndex + submitIndex) == listedBufSize)
{
//listedBuf is full, we should do next list Iter:
plistData->minPos = maxReceivedPos + 1;
}
else
{
plistData->minPos = 0; //indicate that listing is finished
}
plistData->submitListedNumb = submitIndex;
plistData->deliveryListedNumb = deliveryIndex;
return SUCCESS_CODE;
}
//-----------------------------------------------------------------------------
Сообщение отредактировал Lem - Aug 29 2008, 13:28