TAPI и COM-порт
От: vkilikov  
Дата: 27.08.02 08:42
Оценка:
Привет !
Я пытаюсь написать программу для обмена данными посредством модема. Для работы с модемом (дозвон, соединение, контроль состояния линии и т.п.) хочу использовать TAPI, а для пересылки и получения данных — стандартную работу через COM-порт с посощью WriteFile/ReadFile. Если я сначала соединяюсь с помощью TAPI, а потом пытаюсь создать файл посредством CreateFile, то получаю ошибку "The process cannot access the file because it is being used by another process". Если пытаюсь сначала создать файл, а потом соединяться с помощью TAPI то вылетаю на lineOpen с загадочной ошибкой LINEERR_OPERATIONFAILED.
Можно ли в принципе работать одновременно с TAPI и COM-портом через файл ? Если нет, то как сделать ?
Re: TAPI и COM-порт
От: VladSharkov Россия  
Дата: 08.07.03 16:01
Оценка:
V>Можно ли в принципе работать одновременно с TAPI и COM-портом через файл ? Если нет, то как сделать ?

Привет, народ, Хоть вопрос и давнишний, но он так и остался без ответа, и я присоединяюсь к вопрошающему. Если кто-то работал одновременно и c Tapi и c CreateFile, то натолкните на мысль. Буду призателен (и не только я один) за все полезные высказывания по вопросу.
Re: TAPI и COM-порт
От: Аноним  
Дата: 04.07.04 17:25
Оценка:
V>Можно ли в принципе работать одновременно с TAPI и COM-портом через файл ? Если нет, то как сделать ?

Я сам хочу написатьтакое приложение. Но на твой вопрос ответ очень прост. Одновременно работать с ТАПИ и через файл нельзя. Аргументирую я это так. При работе через файл ты занимаешь порт и результат — линия занята для другуго приложения. Аналогично и наооборот. Ты должен выбрать один из двух способов. Но при работе с файлом тебе придётся изучать модем и АТ команды, а при работе с ТАПИ только тот геморрой, который предоставляет майкрософт. У меня есть документация по ТАПИ немного лучше по пониманию, чем MSDN, но пока моя разборка с ней находится в процессе. Так что давай объединим свои усилия. И вообще если кто работает с модемом, даже если не через ТАПИ — пишите мне на мыло doskach@VD14212.spb.edu или по аське 152649484.
Re: TAPI и COM-порт
От: Sergeant Украина www.photomirror.com.ua
Дата: 05.07.04 07:05
Оценка:
Здравствуйте, vkilikov, Вы писали:

V>Привет !

V>Я пытаюсь написать программу для обмена данными посредством модема. Для работы с модемом (дозвон, соединение, контроль состояния линии и т.п.) хочу использовать TAPI, а для пересылки и получения данных — стандартную работу через COM-порт с посощью WriteFile/ReadFile. Если я сначала соединяюсь с помощью TAPI, а потом пытаюсь создать файл посредством CreateFile, то получаю ошибку "The process cannot access the file because it is being used by another process". Если пытаюсь сначала создать файл, а потом соединяться с помощью TAPI то вылетаю на lineOpen с загадочной ошибкой LINEERR_OPERATIONFAILED.
V>Можно ли в принципе работать одновременно с TAPI и COM-портом через файл ? Если нет, то как сделать ?

Можно. только CreateFile здесь не нужен, механизм немного другой. Сначала переводим модем в режим LINEBEARERMODE_PASSTHROUGH (см. lineSetCallParams). Потом получаем ID устройства datamodem (см. lineGetID). А уж потом из полученной структуры VARSTRING вылавливаем HANDLE на СОМ-порт. Его и используем в функциях WriteFile, ReadFile.
btw, если кто расскажет мне, как из режима LINEBEARERMODE_PASSTHROUGH ыввести модем обратно в AUTOMATEDVOICE, не делая hangup, буду очень признателен. Потому как в литературе этого момента не нашел, а МСДН по этому поводу такую муть написала, что.... лучше и не знать, что такая муть вообще бывает
Удачи.
Курить я буду, но пить не брошу.
Re[2]: TAPI и COM-порт
От: Аноним  
Дата: 05.07.04 07:43
Оценка:
Здравствуйте, Sergeant, Вы писали:

S>Можно. только CreateFile здесь не нужен, механизм немного другой. Сначала переводим модем в режим LINEBEARERMODE_PASSTHROUGH (см. lineSetCallParams). Потом получаем ID устройства datamodem (см. lineGetID). А уж потом из полученной структуры VARSTRING вылавливаем HANDLE на СОМ-порт. Его и используем в функциях WriteFile, ReadFile.

S>btw, если кто расскажет мне, как из режима LINEBEARERMODE_PASSTHROUGH ыввести модем обратно в AUTOMATEDVOICE, не делая hangup, буду очень признателен. Потому как в литературе этого момента не нашел, а МСДН по этому поводу такую муть написала, что.... лучше и не знать, что такая муть вообще бывает
S> Удачи.
Не надо переводить модем в режим LINEBEARERMODE_PASSTHROUGH. Просто lineGetID надо вызывать после того, как линия перешла в состояние LINECALLSTATE_CONNECTED. И главное, полученный HANDLE СОМ-порта открыт в режиме OVERLAPPED.
Re[3]: TAPI и COM-порт
От: Sergeant Украина www.photomirror.com.ua
Дата: 05.07.04 08:40
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Не надо переводить модем в режим LINEBEARERMODE_PASSTHROUGH. Просто lineGetID надо вызывать после того, как линия перешла в состояние LINECALLSTATE_CONNECTED. И главное, полученный HANDLE СОМ-порта открыт в режиме OVERLAPPED.


Не согласен. Если не переводить линию в режим LINEBEARERMODE_PASSTHROUGH, WriteFile или ReadFile возвращают ERROR_INVALID_HANDLE.
Курить я буду, но пить не брошу.
Re[4]: TAPI и COM-порт
От: Аноним  
Дата: 06.07.04 10:24
Оценка:
Здравствуйте, Sergeant, Вы писали:

А>>Не надо переводить модем в режим LINEBEARERMODE_PASSTHROUGH. Просто lineGetID надо вызывать после того, как линия перешла в состояние LINECALLSTATE_CONNECTED. И главное, полученный HANDLE СОМ-порта открыт в режиме OVERLAPPED.


S>Не согласен. Если не переводить линию в режим LINEBEARERMODE_PASSTHROUGH, WriteFile или ReadFile возвращают ERROR_INVALID_HANDLE.


Странно. У меня работает. Вот куски кода
  LPVARSTRING DeviceID;
  struct CommInfo
  {
   HANDLE hComm;            // handle of open comm. device
   CHAR   szDeviceName[1];  // name of comm. device
  } *comminfo;
...
   case LINECALLSTATE_CONNECTED:
     DeviceID=(LPVARSTRING)ReallocBuff(sizeof(LPVARSTRING));
     do
     {
      lineGetID(NULL, 0, (HCALL)(TapiMsg.hDevice), LINECALLSELECT_CALL, DeviceID, "comm/datamodem");
      if(DeviceID->dwTotalSize>=DeviceID->dwNeededSize)break;
      DeviceID=(LPVARSTRING)ReallocBuff(DeviceID->dwNeededSize);
     }while (true);
     comminfo=(CommInfo*)((char*)DeviceID+DeviceID->dwStringOffset);
...
int __stdcall CommRead(HANDLE hComm, char *Buff, DWORD BuffSize, DWORD timeout)
{
 if(GetFileType(hComm)!=FILE_TYPE_CHAR)return -2;
 DWORD dwReaded;
 OVERLAPPED Overlapped={0,0,0,0,0};
 Overlapped.hEvent=CreateEvent(NULL, true, false, NULL);
 try
 {
 if(!ReadFile(hComm, Buff, BuffSize, &dwReaded, &Overlapped))
 {
  if(GetLastError()==ERROR_IO_PENDING)
  {
   WaitForSingleObject(Overlapped.hEvent, timeout);
   if(!GetOverlappedResult(hComm, &Overlapped, &dwReaded, false))CancelIo(hComm);
  }
  else dwReaded=-1;
 }
 }
 catch(...)
 {
     dwReaded=-3;
 }
 CloseHandle(Overlapped.hEvent);
 return dwReaded;

}
Re[5]: TAPI и COM-порт
От: Sergeant Украина www.photomirror.com.ua
Дата: 06.07.04 12:47
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Странно. У меня работает. Вот куски кода


Ээээ.... А в каком режиме находится линия? AUTOMATEDVOICE? Или она изначально в data?
Курить я буду, но пить не брошу.
Re[6]: TAPI и COM-порт
От: v.v.s  
Дата: 06.07.04 13:31
Оценка:
Здравствуйте, Sergeant, Вы писали:


S>Ээээ.... А в каком режиме находится линия? AUTOMATEDVOICE? Или она изначально в data?

Она изначально в LINEMEDIAMODE_DATAMODEM.
Re[7]: TAPI и COM-порт
От: Sergeant Украина www.photomirror.com.ua
Дата: 07.07.04 07:47
Оценка:
Здравствуйте, v.v.s, Вы писали:

VVS>Здравствуйте, Sergeant, Вы писали:



S>>Ээээ.... А в каком режиме находится линия? AUTOMATEDVOICE? Или она изначально в data?

VVS>Она изначально в LINEMEDIAMODE_DATAMODEM.

Аааа, ну тада возможно Ваш код и работает. У меня просто линия в AUTOMATEDVOICE и чтоб получить хендл на порт приходится переводить линию в LINEBEARERMODE_PASSTHROUGH. А вот обратно перещелкнуть линию после этого в AUTOMATEDVOICE не удается, приходится хангап делать. Читал в старых (1997...98 годы) постингах, что эта проблема Unimodem V, мол, скоро поправят. Видать до сих пор не поправили
Курить я буду, но пить не брошу.
Re[7]: TAPI и COM-порт
От: Slavan Россия www.doskach.spb.ru
Дата: 07.07.04 12:52
Оценка:
Признаю свою ошибку. Действительно я не прав. Но умне есть ещё вопросик. Можно ли с помощью тапи различить звонки голосовые,RAS, хрен знает какой программы и т.д. Если кто знает — подскажите.
Если ты в жизни совершил много ошибок — запусти отладку. :-))
www.doskach.spb.ru
Re[8]: TAPI и COM-порт
От: Sergeant Украина www.photomirror.com.ua
Дата: 07.07.04 13:32
Оценка:
Здравствуйте, Slavan, Вы писали:

S>Признаю свою ошибку. Действительно я не прав. Но умне есть ещё вопросик. Можно ли с помощью тапи различить звонки голосовые,RAS, хрен знает какой программы и т.д. Если кто знает — подскажите.


На все 100% нельзя. Вообще, эта задача не простая. Есть АТС, которые по запросу выдают тип звонка. Если АТС не имеет такой возможности — работать не будет Остальное делается руками и основано та творческом подходе

Попробуй посмотреть здесь: http://groups.google.com.ua/groups?q=detect+type+incoming+call&hl=ru&lr=&ie=UTF-8&newwindow=1&selm=39076fe9.4078929%40news-server&rnum=10

и здесь:
http://groups.google.com.ua/groups?q=detect+type+incoming+call&hl=ru&lr=&ie=UTF-8&newwindow=1&selm=384E94EE.65DD701A%40mx3.redestb.es&rnum=18
Курить я буду, но пить не брошу.
Re: TAPI и COM-порт
От: ScorpZ Украина  
Дата: 16.07.04 09:38
Оценка:
Здравствуйте, vkilikov, Вы писали:

V>Привет !

V>Я пытаюсь написать программу для обмена данными посредством модема. Для работы с модемом (дозвон, соединение, контроль состояния линии и т.п.) хочу использовать TAPI, а для пересылки и получения данных — стандартную работу через COM-порт с посощью WriteFile/ReadFile. Если я сначала соединяюсь с помощью TAPI, а потом пытаюсь создать файл посредством CreateFile, то получаю ошибку "The process cannot access the file because it is being used by another process". Если пытаюсь сначала создать файл, а потом соединяться с помощью TAPI то вылетаю на lineOpen с загадочной ошибкой LINEERR_OPERATIONFAILED.
V>Можно ли в принципе работать одновременно с TAPI и COM-портом через файл ? Если нет, то как сделать ?


Работать и с тем и с другим в принципе возможно , но с большими ограничениями...

1) C помощью ф-ций TAPI (lineInitializeEx , lineOpen ) мы открваем модемную линию и можем работать с ней , используя ф-ции TAPI .
НО !!!!!!!!!!!!!!!!! в этот момент мы не можем получить доступ к COM порту и не можем получить его хэндл, на котором висит модем , используя ф-цию CreateFile . Так как в этот момент COM порт занимается TSP драйвером модема
(пердположим "Zyxel Omni")

Что нам , по этому поводу говорит МСДН .

В Windows TAPI существуют несколько типов устройсв , один из них — "comm/datamodem" — которым и является наша отрытая TAPI линия. Так вот !!! , в принципе , есть возможность , через TAPI , получить хэндл КОМ порта.
Делается это с помощью lineGetID функции — в первых 4х битах пятого параметра (LPVARSTRING lpDeviceID) как раз и содержится хэндл порта ....
------------------------------
comm/datamodem
The comm/datamodem device class consists of datamodem devices. You access these devices by using the Win32 file and communications functions. Devices in this class are associated with line devices that support the LINEMEDIAMODE_DATAMODEM media type, which is specified in the dwMediaModes member of the LINEDEVCAPS structure for the line device.

The lineGetID function fills a VARSTRING structure, setting dwStringFormat to the STRINGFORMAT_BINARY value and appending these additional members:

HANDLE hComm; // Win32 file handle to data modem
CHAR szDeviceName[1]; // name of data modem

The hComm member is the handle of the open communications port. This member is NULL if the port is not yet open or if the dwSelect parameter of lineGetID is not the LINECALLSELECT_CALL value.

---------------------------------

А вот здесь то и начинаются ограничения — полученый хэндл активен только , если TAPI линия модема (точнее звонок на этой линии) находится в состоянии соединения LINECALLSELECT_CALL... — вот и как обойти этого ограничения TAPI я так и не разобрался ........
Re[2]: TAPI и COM-порт
От: ScorpZ Украина  
Дата: 21.09.04 08:03
Оценка:
Здравствуйте, VladSharkov, Вы писали:

V>>Можно ли в принципе работать одновременно с TAPI и COM-портом через файл ? Если нет, то как сделать ?


VS>Привет, народ, Хоть вопрос и давнишний, но он так и остался без ответа, и я присоединяюсь к вопрошающему. Если кто-то работал одновременно и c Tapi и c CreateFile, то натолкните на мысль. Буду призателен (и не только я один) за все полезные высказывания по вопросу.



В общем в свое время я сталкивался с такой проблемой . И вот что у меня получилось.
HANDLE ком порта (который мы получаем из CreateFile) можно получить через ТАПИ lineGetID — НО !!! Этот хэндл будет рабочий только при условии что линия , с которой мы получаем этот хэндл , (тапи линия модема , полученая через LineOpen) будет находиться в состоянии CONNECTED !!! В других случая хэндл будет не рабочий

// Вот небольшая статейка из МСДН по этому поводу

The lineGetID function fills a VARSTRING structure, setting dwStringFormat to the STRINGFORMAT_BINARY value and appending these additional members:

HANDLE hComm; // Win32 file handle to data modem
CHAR szDeviceName[1]; // name of data modem

The hComm member is the handle of the open communications port. This member is NULL if the port is not yet open or if the dwSelect parameter of lineGetID is not the LINECALLSELECT_CALL value. If a call is active, the service provider typically opens the port itself to get direct control of the communications hardware, but is only required to return a valid handle if the line is connected. The service provider opens the port using the FILE_FLAG_OVERLAPPED value and then configures the port using the settings specified by the lineSetDevConfig function. You can set additional configuration options for the device by using Win32 functions with the returned handle
Re[3]: TAPI и COM-порт
От: Sergeant Украина www.photomirror.com.ua
Дата: 22.09.04 06:33
Оценка:
Здравствуйте, ScorpZ, Вы писали:

SZ>В общем в свое время я сталкивался с такой проблемой . И вот что у меня получилось.

SZ>HANDLE ком порта (который мы получаем из CreateFile) можно получить через ТАПИ lineGetID — НО !!! Этот хэндл будет рабочий только при условии что линия , с которой мы получаем этот хэндл , (тапи линия модема , полученая через LineOpen) будет находиться в состоянии CONNECTED !!! В других случая хэндл будет не рабочий

Согласен, именно так это и делается (см. постинги выше ). Я данной возможностью пользуюсь чтобы получить хендл порта в том случае, если есть соединение. Если соединения нет — гашу линию и работаю с компортом обычным способом (Create/Read/WriteFile). Код получается почти один и тот же, разница только в получении хендла.
Курить я буду, но пить не брошу.
Re[3]: TAPI и COM-порт
От: explorus Россия  
Дата: 23.03.05 12:14
Оценка:
Здравствуйте, ScorpZ, Вы писали:

SZ>Здравствуйте, VladSharkov, Вы писали:


V>>>Можно ли в принципе работать одновременно с TAPI и COM-портом через файл ? Если нет, то как сделать ?


VS>>Привет, народ, Хоть вопрос и давнишний, но он так и остался без ответа, и я присоединяюсь к вопрошающему. Если кто-то работал одновременно и c Tapi и c CreateFile, то натолкните на мысль. Буду призателен (и не только я один) за все полезные высказывания по вопросу.



SZ>В общем в свое время я сталкивался с такой проблемой . И вот что у меня получилось.

SZ>HANDLE ком порта (который мы получаем из CreateFile) можно получить через ТАПИ lineGetID — НО !!! Этот хэндл будет рабочий только при условии что линия , с которой мы получаем этот хэндл , (тапи линия модема , полученая через LineOpen) будет находиться в состоянии CONNECTED !!! В других случая хэндл будет не рабочий

SZ>// Вот небольшая статейка из МСДН по этому поводу


SZ>The lineGetID function fills a VARSTRING structure, setting dwStringFormat to the STRINGFORMAT_BINARY value and appending these additional members:


SZ>HANDLE hComm; // Win32 file handle to data modem

SZ>CHAR szDeviceName[1]; // name of data modem

SZ>The hComm member is the handle of the open communications port. This member is NULL if the port is not yet open or if the dwSelect parameter of lineGetID is not the LINECALLSELECT_CALL value. If a call is active, the service provider typically opens the port itself to get direct control of the communications hardware, but is only required to return a valid handle if the line is connected. The service provider opens the port using the FILE_FLAG_OVERLAPPED value and then configures the port using the settings specified by the lineSetDevConfig function. You can set additional configuration options for the device by using Win32 functions with the returned handle



Очень все верно... НО !!! столкнулся я с таким траблом, если полученный хендл хотя бы раз использовать для чтения или записи, то его обязательно нужно закрыть CloseHandle(hComm), иначе последующий lineMakeCall вернет LINEERR_OPERATIONFAILED, поскольку порт остается занятым (DTR).
А еще нужно соблюдать количество lineInitialixeEx c lineOpen == lineClose c lineShutdown
иначе будет LINEERR_OPERATIONFAILED с последующим lineOpen, это если используется Unimodem.TSP
У кого есть комментарии на эти замечания ???
Я тут мог очепятаться, не ругаейте сильно, быстро печатал чего помнил
Re[4]: TAPI и COM-порт
От: Sergeant Украина www.photomirror.com.ua
Дата: 23.03.05 15:02
Оценка:
Здравствуйте, explorus, Вы писали:

E>Очень все верно... НО !!! столкнулся я с таким траблом, если полученный хендл хотя бы раз использовать для чтения или записи, то его обязательно нужно закрыть CloseHandle(hComm), иначе последующий lineMakeCall вернет LINEERR_OPERATIONFAILED, поскольку порт остается занятым (DTR).

Конечно, по этому поводу и в МСДН написано: The application must call CloseHandle on the handle it received from lineGetID.

E>А еще нужно соблюдать количество lineInitialixeEx c lineOpen == lineClose c lineShutdown

E>иначе будет LINEERR_OPERATIONFAILED с последующим lineOpen, это если используется Unimodem.TSP
Ну дык это... Конечно нужно,как же иначе?.. Нельзя открыть линию, если она не закрыта с прошлого раза. И нельзя завести ТАПИ, если его с прошлого раза не погасили...
Курить я буду, но пить не брошу.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.