Я нашёл несколько тем со схожими вопросами, однако в определённых моментах так и не разобрался.
Хочется работать с модемам не через TAPI, а передавая и принимая данные в COM-порт и из порта. Собственно, для начала была написана простая программа без обработки ошибок и с асинхронной моделью доступа, текст привожу ниже:
DCB ComDCB;
COMMTIMEOUTS CT;
HANDLE hComPort;
char* InputBuf;
char* OutputBuf = "ATZ\r";
OVERLAPPED OVRL;
DWORD mask;
DWORD bc;
//Установка time-out'ов — используется только ограничение на время между началом приёма двух символов
CT.ReadIntervalTimeout = 100;
CT.ReadTotalTimeoutMultiplier = CT.ReadTotalTimeoutConstant = 0;
CT.WriteTotalTimeoutMultiplier = CT.WriteTotalTimeoutConstant = 0;
//Открываем порт, используется асинхронный режим обмена
hComPort=CreateFile("COM3", GENERIC_READ | GENERIC_WRITE, 0, NULL,
OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
//Сбрасываем события
ZeroMemory(&OVRL, sizeof(OVRL));
OVRL.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
//Выделение памяти под принимаемую от модема строку — на 10 символов больше отправляемой
InputBuf = (char*) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
strlen(OutputBuf) + 11);
//Запись строки в порт
WriteFile(hComPort, OutputBuf, strlen(OutputBuf), &bc, &OVRL);
//Ожидание окончания операции
if(WaitForSingleObject(OVRL.hEvent, 1000) == WAIT_OBJECT_0)
{
GetOverlappedResult(hComPort, &OVRL, &bc, FALSE);
}
else
{
//Выход по time-out'у
ShowMessage("Unable to write to port!");
CloseHandle(hComPort);
CloseHandle(OVRL.hEvent);
return;
}
//Сброс события
ZeroMemory(&OVRL, sizeof(OVRL));
OVRL.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
//Чтение строки из порта — читаем на 10 символов больше, чем записали
ReadFile(hComPort, InputBuf, strlen(OutputBuf) + 10, &bc, &OVRL);
//Ожидание окончания операции
if(WaitForSingleObject(OVRL.hEvent, 1000) == WAIT_OBJECT_0)
{
GetOverlappedResult(hComPort, &OVRL, &bc, FALSE);
}
else
{
//Выход по time-out'у
ShowMessage("Unable to read from port!");
CloseHandle(hComPort);
CloseHandle(OVRL.hEvent);
return;
}
//Вывод принятой строки
ShowMessage(InputBuf);
//Освобождение занятой памяти и закрытие порта
HeapFree(GetProcessHeap(), 0, InputBuf);
CloseHandle(hComPort);
CloseHandle(OVRL.hEvent);
Проблема заключается в том, что при первом вызове функции выходим по time-out'у с сообщением "Unable to read from port!". Такая ситуация сохраняется, если вызвать функцию ещё раз пять, затем получаем правильный результат — отправленную строку + ОК от модема. Собственно, не совсем понятно, почему первые попытки заканчиваются неудачей. Также время от времени выход по time-out'у происходит, если продолжать вызывать функцию и по получении корректного сообщения от модема.