На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
  
    > Как отправить строку(АТ команду) в модем
      Я научился отправлять АТ команды на модем, если он подключен к СОМ порту. Но если модем подключен через USB, IrDa или еще как, то способ записи в СОМ порт не проходит...Как в этом случае передать АТ команду модему? И как посмотреть список установленных модемов? (Как это делается в HyperTerminal)
        а как ты открываешь порт?

        вообще задумка в системе была такая, что ты имеешь некий дескриптор, и по нему пишешь данные.. а что под ним - тебе пофиг..

        ExpandedWrap disabled
          HANDLE hModem;
          ...
          например hModem = CreateFile( "COM1"... );
          ..
          WriteFile( hModem, "ATZ".. );
          Да, примерно так все и происходит.
          Только, например я беру мобильник с модемом, и подключаю его к компу чере IrDa, что мне укаывать вместо COM1?
            kleva
            Одной из проблем в программировании инфракрасных сокетов является невозможность применения стандартной схемы разрешения имен хостов на базе статических ресурсов локальной сети, каким является сервер DNS. В программах протокола IrDA стало невозможным применение таких функций, как gethostbyname() и обычных схем IP-адресации, что привело к возникновению нового коммуникационного домена и соответствующей ему схемы адресациии - AF_IRDA.
            Определена новая структура адреса инфракрасного сокета:
            typedef struct _SOCKADDR_IRDA
            ExpandedWrap disabled
              {
                  u_short     irdaAddressFamily;
                  u_char      irdaDeviceID[4];
                  char        irdaServiceName[25];
              } SOCKADDR_IRDA, *PSOCKADDR_IRDA, FAR *LPSOCKADDR_IRDA;


            Поле irdaAddressFamily содержит константу AF_IRDA. Поле идентификатора инфракрасного устройства irdaDeviceID представляет собой четырехбайтовую строку, единственным образом идентифицирующую устройство, на котором будет исполняться сервис. Сервер IrSock игнорирует это поле, но оно важно для клиентского приложения, так как именно оно определяет устройство, с которым клиенту предстоит взаимодействовать. Последнее поле, irdaServiceName[25] содержит название сервиса, который должен быть зарегистрирован в системе (сервер) с помощью bind(), или к которому идет запрос на соединение c помощью connect() (клиент). Для Windows СE эту структуру в клиентском приложении обычно инициализируют примерно таким образом:
            ExpandedWrap disabled
              SOCKADDR_IRDA Аddress = {AF_IRDA, 0, 0,0,0,"Service_Name"};

            В IrDA-технологии существуют "известные" имена сервисов, к ним относятся OBEX (Object Exchange) для передачи файлов, IrCOMM – протокол эмуляции последовательного порта, IrLAN -для эмуляции сетевого взаимодействия в среде Ethernet и т.д.
            Основные проблемы программирования IrDA связаны с нетрадиционной схемой адресации нужного устройства. Для этого применяются две методологии – основанная на Logical Service Access Point Selectors (LSAP-SEL) и IAS. Адреса вышеупомянутых логических каналов называются Logical Service Access Point Selectors и находятся в диапазоне 0х01 до 0х6F (1-111-Windows CE), в настольных Windows – до 127. Адрес 0х00 зарезервирован, на нем находится служба IAS (Information Access Services), с помощью которой логическим каналам присваивается имя в виде текстовой строки - можно считать IAS "инфракрасным" аналогом службы DNS.
            IrDA оснащается только потоковым протоколом, датаграммных протоколов для него не существует.
            Служба Information Access Service (IAS) поддерживает так называемые "yellow pages - желтые страницы", которые представляют собой набор записей для логических каналов с их идентификаторами, именами и атрибутами. Например, ноутебук PC1 может послать IAS-запрос на десктоп PC2 с логическим именем сервиса Speakers и атрибутом LSAP-SEL и получить в ответ значение 0х03, означающее, что программа, обслуживающая звуковое воспроизведение, стартует, если данные будут посланы на логический канал 0х03.
            Программирование этих действий для клиентского приложения выполняется следующим образом. После создания IrDA-сокета:
            sd = socket (AF_IRDA, SOCK_STREAM, 0);
            клиент производит просмотр устройств в разрешенном диапазоне с помощью функции getsockopt():
            int getsockopt(SOCKET sd, int level, int optname, const char FAR *optval, int optlen);
            с указанием уровня SOL_IRLMP, а параметр optname может быть одним из следующих:
            · IRLMP_ENUMDEVICES – запрашивается перечисление удаленных IRDA-устройств;
            · IRLMP_IAS_QUERY – опрос IAS-атрибутов;
            · IRLMP_SEND_PDU_LEN - опрос максимального размера посылаемого пакета для режима IrLPT.
            Использование параметра IRLMP_ENUMDEVICES приводит к заполнению структуры WINDOWS_DEVICELIST необходимой информацией о всех доступных устройствах:
            ExpandedWrap disabled
              typedef struct _WINDOWS_DEVICELIST
              {
                  ULONG                       numDevice;
                  WINDOWS_IRDA_DEVICE_INFO    Device[1];
              } WINDOWS_DEVICELIST, *PWINDOWS_DEVICELIST, FAR *LPWINDOWS_DEVICELIST;

            где структура IRDA_DEVICE_INFO имеет следующий вид:
            ExpandedWrap disabled
              typedef struct _WINDOWS_IRDA_DEVICE_INFO
              {
                  u_char  irdaDeviceID[4];
                  char    irdaDeviceName[22];
                  u_char  irdaDeviceHints1;   //Отсутствует в Windows CE
                  u_char  irdaDeviceHints2;   //Отсутствует в Windows CE
                  u_char  irdaCharSet;
              } WINDOWS_IRDA_DEVICE_INFO, *PWINDOWS_IRDA_DEVICE_INFO,
                FAR *LPWINDOWS_IRDA_DEVICE_INFO;

            Примечание:
            Для Windows СE обе эти структуры имеют несколько иной вид.
            Доступ к полям нужной структуры мы получаем через указатель *optval.
            Использование getsockopt() с параметром IRLMP_ENUMDEVICES для перечисления доступных устройств не является оптимальным для мобильных устройств, так как это приводит к значительному потреблению энергии аккумулятора при циклическом опросе, потому что для просмотра всех устройств функцию getsockopt() надо вызывать в цикле. Практичнее использовать вызов setsockopt(), который может перевести наше IR-устройство в специальный режим поиска, используя опцию IRLMP_DISCOVERY_MODE.
            Метод, изложенный выше, представляет собой попытку соединения с нужным сервисом на хосте-партнере – это похоже на посылку TCP-сегмента с флагом S. Второй способ – это выполнение запроса IAS для нужного сервиса с помощью опции IRLMP_IAS_QUERY – это аналог DNS-запроса. В последнем случае мы получим указатель на структуру IAS_QUERY для Windows CE и WINDOWS_IAS_QUERY – для Windows 98,Me,2000 и XP.
            Следующий фрагмент использует Winsock1.1 для Windows CE – для этой версии ОС действительна только спецификация WinSock 1.1. Для работы необходимо подключение заголовочного файла af_irda.h, который доступен по адресу http://www.cswl.com/whiteppr/white/arhead.html.

            ExpandedWrap disabled
              #include <windows.h>
              #include <af_irda.h>
              #include <stdio.h>
              #pragma comment ( lib, "WS2_32.Lib" )
              void main()
              {
              SOCKET sd;
              SOCKADDR_IRDA address = {AF_IRDA, 0, 0,0,0,"MyServer"};
              DEVICELIST devList;
              char helloClient[25];
              int mode = 1;
              sd = socket (AF_IRDA, SOCK_STREAM, 0);
              // Перевод сокета в режим поиска
              setsockopt (sd, SOL_IRLMP, IRLMP_DISCOVERY_MODE, (char *)&devList,(int)&mode);
              // Получаем сигнал от нового устройствa – функция блокирующая
              recv(sd, (char *)&devList, sizeof(devList), 0);
              // Выключаем режим поиска
              mode = FALSE;
              setsockopt (sd, SOL_IRLMP, IRLMP_DISCOVERY_MODE, (char *) &devList, (int)&mode);
              // Выбираем первое устройство в списке
              for(int i=0;i<=3;i++)address.irdaDeviceID[i] = (char)devList.Device[i].irdaDeviceID;
              // Соединение клиента с сервисом по имени MyServer на выбранном устройстве
              connect(sd, (struct sockaddr*)&address, sizeof(SOCKADDR_IRDA));
              // Шлем сообщение
              send(sd, "Hello Server!", strlen("Hello World!")+1, 0);
              // Ожидание и получение ответа.
              recv(sd, helloClient, sizeof(helloClient), 0);
              printf("%s\n", helloClient);
              closesocket(sd);
              }

            Пример программирования клиентского приложения для Windows 2000 с использованием WinSock 2.0 можно найти по адресу http://www.alanjmcf.me.uk/comms/infrared/irdaWinsockCli.cpp.html.
              Oleg2004,
              Спасибо за статью, буду пробовать.
              Тем не менее вопрос остается в силе, ибо, дальше мне искать как послать строку по USB, FireWare, LPT etc? Я не думаю, что HyperTerminal поддерживает непосредственно все эти соединения. Мне кажется, что Muran в данном случае прав - есть некий дескриптор, по которому все именуется. Наверно проще получить дескриптор абстрактного модема, не привязываясь к способу его соединения (в данном случае я просто привел пример с irda. Хотя поскольку у меня именно такое соединение, то буду пробовать ваш способ).
                kleva
                Цитата
                есть некий дескриптор, по которому все именуется

                Тогда надо искать специальное API, где поддерживается этот "неизвестный" дескриптор.
                Например, WinInet API вводит дескриптор интернет-сессии HINTERNET, он же и предоставляет набор функций для работы с ним.
                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                0 пользователей:


                Рейтинг@Mail.ru
                [ Script execution time: 0,0272 ]   [ 17 queries used ]   [ Generated: 29.03.24, 12:42 GMT ]