На главную... Продукты | Технологии | Классификаторы | Проекты | Скачать | Цены| Форум | Статьи | Обучение | Контакты

Gpsapi

Поиск  Пользователи  Правила  Войти
Форум » Настольные приложения » GIS ToolKit, GIS ToolKit Active, ГИС Конструктор для Windows
Страницы: 1
RSS
Gpsapi, как узнать путь к USB устройству
 
Попытался разобраться и попробовать применить на практике набор функций работы с GPS подключенных к компьютеру по кабелю USB. Не смог понять, каким образом работает gpsOpen пишут надо указать путь к COM порту либо указать путь к USB устройству.
На данный момент у меня Oregon 650. Я смог его в ГИС Карта 2000 запустить и работать с ним. Но хотелось бы в собственном приложении на GTK немного расширить функционал. Вывод диалога, при попадании в зону. Заполнение данных и занесение в базу. Заранее спасибо.
 
Цитата
Роман Перминов пишет:
Не смог понять, каким образом работает gpsOpen пишут надо указать путь к COM порту либо указать путь к USB устройству.
Из файла gpsapi.h:
Код
// Открыть COM или USB порт для чтения GPS - сообщений в формате NMEA O183
// Для Windows:
// portname - имя COM-порта (например, "\\\\.\\COM1" или путь к USB-порту)
// baudrate - частота обмена с портом (например, 9600 или 0)
// Для Linux:
//   portname - имя COM-порта (например, "/dev/ttyS0"("COM1:" в Windows))
//   baudrate - частота обмена с портом (например, B9600 или B4800)
// При ошибке возвращает 0
_MAPIMP HCOMPORT _MAPAPI gpsOpen(LPTSTR portname, long int baudrate);
_MAPIMP HCOMPORT _MAPAPI gpsOpenUn(const WCHAR* portname, long int baudrate);   // 21/06/16
Функционал, объявленный в  gpsapi.h, применим к устройствам, передающим сообщения в формате NMEA0183 на COM-порт.

Существуют устройства, которые подключаются к USB-порту, посредством драйвера "USB-to-Serial Comm Port" создают в системе виртуальный COM-порт и передают на виртуальный COM-порт сообщения в формате NMEA O183.
К таким устройствам так же могут применяться функции, объявленные в gpsapi.h.
Примером данного класса устройств являются так называемые таблетки:
- BU-353(SiRF III) - таблетка USB. Использует драйвер USB-to-Serial Comm Port, версия 2.0.2.8.
- BU-353(SiRF IV)  - таблетка USB. Использует драйвер Prolific Serial-to-USB Comm Port, версия 3.3.17.203 от 29.04.2011

Модуль "GPS\ГЛОНАСС Монитор" подключает USB приемники Garmin, обращаясь к установленному драйверу Garmin для данного устройства.
Взаимодействие программы с драйвером USB-приемника Garmin осуществляется по двоичному протоколу обмена формата GARMIN.
Указанное взаимодействие реализовано в соответствии с документацией производителя  "Garmin Device Interface Specification" редакции 19 мая 2006г.
Реализованы физический протокол, протокол связи и протоколы приложения (L001, A010, A100, D110, A201, D202, D110, D210, A301, D312, D302, A400, D110, A700, D700, A800, D800) для устройств Garmin GpsMap 60, Garmin GpsMap 60 Cx.

Ниже приведен список API-функций для подключения USB-приемника Garmin:
Код
/*******************************************************************
*                                                                  *
*              API-функции для рабоы с USB-приемником Garmin       *
*                      Библиотека gisGps.dll                       *
*                                                                  *
*******************************************************************/
#ifndef GpsTApi_H
#define GpsTApi_H

#include "mapapi.h"

typedef HANDLE GPSTEST;    // ИДЕНТИФИКАТОР ОТКРЫТОГО GPS-УСТРОЙСТВА
                              // (УКАЗАТЕЛЬ НА TGpsTest)

typedef struct WAYPOINT_GPS
{
  SIGNDEGREE B_degree;          // координаты точки B (WGS84 - градусы, минуты, секунды)
  SIGNDEGREE L_degree;          // координаты точки L (WGS84 - градусы, минуты, секунды)
  double HeightGeo;             // высота точки в СК WGS84
  char   NamePoint[32];         // Название точки (Для GpsMap60 название точки ограничено 10-ю символами, заполнять только латиницей.)
  char   DescriptionPoint[32];  // Описание точки (Для GpsMap60 заполнять только латиницей.)
  char   IconPoint[32];         // название иконки точки (при записи путевых точек на GPS-приемник не используется)
  unsigned long int IconIdent;  // код иконки точки
  char   UnitHeight[4];         // единицы измерения высоты точки
}
  WAYPOINT_GPS;

typedef struct ROUTE_GPS
{
  WAYPOINT_GPS Point[500];    // Массив точек маршрута     (Garmin)
  char     NameRoute[32];     // Название маршрута  (Garmin)
  long int NumberRoute;       // Номер маршрута     (Garmin)
  long int CountPoints;       // Количество точек маршрута
  char     DescriptionRoute[MAX_PATH]; // Описание маршрута
  char     Rez[4];
}
  ROUTE_GPS;

typedef struct TRACKPOINT_GPS
{
  SIGNDEGREE B_degree;           // координаты точки B (WGS84 - градусы, минуты, секунды)
  SIGNDEGREE L_degree;           // координаты точки L (WGS84 - градусы, минуты, секунды)
  double Height;                 // высота точки в СК WGS84
  char   UnitHeight[4];          // единицы измерения высоты точки
  unsigned long int Time;        // используется чтобы указать абсолютное время.
                                 // значение - число секунд, пошедшее с 12:00 - 31 декабря, 1989 UTC.
}
  TRACKPOINT_GPS;

typedef struct TRACKLOG_GPS
{
  TRACKPOINT_GPS Point[2000];      // координаты точки в градусах. В Garmin'е сохраненный TrackLog содержит 500 точек, текущий TrackLog - до 2000 точек.
  long int PointCount;             // Количество точек TrackLog'а   (Garmin)
  long int NumberTrackLog;         // Номер TrackLog'а   (Garmin)
  char     NameTrackLog[MAX_PATH]; // Название TrackLog'а  (Garmin)
  char     Rez[4];
}
  TRACKLOG_GPS;


extern "C"
{

// Запросить названия устройств, подключенных к USB
// names - адрес строки для размещения названий USB-устройств, размер строки - MAX_PATH
//         названия USB-устройств разделены нулем
// programmNames - адрес строки для размещения технических названий USB-устройств, размер строки - MAX_PATH
//         технические названия USB-устройств разделены нулем
// count - адрес переменной для размещения количества устройств, подключенных к USB
// При ошибке возвращает ноль

// Названия устройств из names предназначены для показа пользователю, а технические
// названия USB-устройств из programmNames - для установки связи с GPS-приемником.
// i-е название из names и i-е техническое название из programmNames соответствуют i-му устройству
long int _export WINAPI gpsTestGetUSBDevicesNames(char* names, char* programmNames, long int * count);

// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// +++++   ОПИСАНИЕ ФУНКЦИЙ ДОСТУПА К GPS-ПРИЕМНИКУ,   +++++
// +++++    ПОДКЛЮЧЕННОМУ К USB ПО ПРОТОКОЛУ GARMIN    +++++
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++

// Установить связь с GPS-приемником
// name - адрес строки c названием GPS-приемника, подключенного к USB
// programmNames - адрес строки с техническим названием GPS-приемника
// Получение списка имен см. в ф-ии gpsTestGetUSBDevicesNames()
// При ошибке возвращает ноль
GPSTEST _export WINAPI gpsTestOpenUSBDevice(char* name, char* programmNames);

// Разорвать связь с GPS-приемником
// device - ИДЕНТИФИКАТОР ОТКРЫТОГО GPS-УСТРОЙСТВА
// При ошибке возвращает ноль
long int _export WINAPI gpsTestCloseUSBDevice(GPSTEST device);

// Запросить название устройства и данные производителя
// (описание устройства и версия программного обеспечения, Product ID, Software version);
// device - ИДЕНТИФИКАТОР ОТКРЫТОГО GPS-УСТРОЙСТВА
// product_ID - номер устройства
// software_version - версия ПО
// product_description - адрес строки для размещения описания устройства, размер строки - MAX_PATH
//                       очередная характеристика заканчивается нулем
// При ошибке возвращает ноль
long int _export WINAPI gpsTestGetDescriptionUSBDevice(GPSTEST device,
                                                       unsigned long int* product_ID,
                                                       long int* software_version,
                                                       char* product_description);

// Запросить путевые точки с GPS-приемника
// Информация о количестве путевых точек GPS-приемником заранее не выдается
// device - ИДЕНТИФИКАТОР ОТКРЫТОГО GPS-УСТРОЙСТВА
// wayPoints - адрес массива структур для размещения путевых точек, получаемых с GPS-приемника
// count - размерность передаваемого в функцию массива wayPoints
// При ошибке возвращает ноль, иначе - количество путевых точек, записанных в массив
long int _export WINAPI gpsTestGetWayPoints(GPSTEST device, HWND handle, WAYPOINT_GPS* wayPoints, long int count);


// Запросить маршруты с GPS-приемника
// Информация о количестве маршрутов GPS-приемником заранее не выдается
// device - ИДЕНТИФИКАТОР ОТКРЫТОГО GPS-УСТРОЙСТВА
// handle - Идентификатор окна приложения
//          Окну приложения посылается cообщение о соcтоянии процесса (0x590)
// routes - адрес массива структур для размещения маршрутов, получаемых с GPS-приемника
// count - размерность передаваемого в функцию массива routes
// При ошибке возвращает ноль, иначе - количество маршрутов, записанных в массив
long int _export WINAPI gpsTestGetRoutes(GPSTEST device, HWND handle, ROUTE_GPS* routes, long int count);


// Запросить TrackLog'и с GPS-приемника
// Информация о количестве TrackLog'ов GPS-приемником заранее не выдается
// device - ИДЕНТИФИКАТОР ОТКРЫТОГО GPS-УСТРОЙСТВА
// handle - Идентификатор окна приложения
//          Окну приложения посылается cообщение о соcтоянии процесса (0x590)
// trackLogs - адрес массива структур для размещения TrackLog'ов, получаемых с GPS-приемника
// count - размерность передаваемого в функцию массива trackLogs
// При ошибке возвращает ноль, иначе - количество TrackLog'ов, записанных в массив
long int _export WINAPI gpsTestGetTrackLogs(GPSTEST device, HWND handle, TRACKLOG_GPS* trackLogs, long int count);

// Записать путевые точки на GPS-приемник
// device - ИДЕНТИФИКАТОР ОТКРЫТОГО GPS-УСТРОЙСТВА
// handle - Идентификатор окна приложения
//          Окну приложения посылается cообщение о соcтоянии процесса (0x590)
// wayPoints - адрес массива структур путевых точек, передаваемых на GPS-приемник
// count - размерность передаваемого в функцию массива wayPoints
// При ошибке возвращает ноль
long int _export WINAPI gpsTestSetWayPoints(GPSTEST device, HWND handle,
                                            WAYPOINT_GPS* wayPoints, long int count);


// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// +++++                 СЕРВИСНЫЕ ФУНКЦИИ             +++++
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++

// Запросить код последней ошибки
// device - ИДЕНТИФИКАТОР ОТКРЫТОГО GPS-УСТРОЙСТВА
// language - код языка сообщения (1 - ENGLISH, 2 - RUSSIAN)
// error - адрес строки для размещения сообщения об ошибке
// При отсутствии ошибок возвращает ноль
long int _export WINAPI gpsTestGetLastError(GPSTEST device, long int language, char* error);
}

#endif
 
Подниму эту тем еще раз.


Пишу на Delphi


При вызове функции gpsTestGetDescriptionUSBDevice возвращаются непонятные данные:

функцию я обявляю так:

function gpsTestGetUSBDevicesNames(names: PChar; programmNames: PChar; var count: Integer): Integer;
{$IFNDEF LINUXAPI} stdcall {$ELSE} cdecl {$ENDIF} external sGisGps;

вызываю так:


procedure TMainFrm.GPS2Click(Sender: TObject);
var
 Ret: Cardinal;
 names: array [1..MAX_PATH] of Char;
 programmNames: array [1..MAX_PATH] of Char;
 count: Integer;

begin
 Ret := gpsTestGetUSBDevicesNames(pchar(@names), pchar(@programmNames), count);
end;


переменные names и programmNames объявил как-то так.

Возвращает вот такие данные:

переменная names

USB-устрой#0#0#0#0#0#0#0#0#0#0#0Составное US#0#0#0#0#0#0#0#0#0#0#0#0#0Garmin #0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0?#0#0§??A??#0#0#0#0?A??????????????#0?A?$#0[cut#0#0#0#0#0p#0????????#0#0]#0#0#0#0#0??/????Y#0#0[cut#0?Ш?r??Y?#0#0?Ш??r??Y?[/cut]#0#0#0#0A?Y?Ш??Y?#0#0?#0#0?][/cut]#0#0#0

переменная programmNames

\\?\usb#vid_046d&pid_c077#5&30b7b990&0&1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0\\?\usb#vid_046d&pid_c31c#5&30b7b990&0&4#0#0#0#0#0#0#0#0#0???#0#0#0??#0#0#0#0#0#0??#0#0#0#0?E??#0#0?????#0#0E#0?#0§??/??#0#0?????@?#0#0§?#0#0?#0#0#0?Ї?#0????@#0?@?@#0#0?@#0????@?#0?#0??#0#0???Ї?Ї?Ї?#0?@?@?????#0#0?#0


переменная count вовращает  = 3
переменная Ret = 3

Где здесь 3 устрйства? Почему имена устройств урезаны? А в programmName как найти нужные идентификаторы? Первый и второй вижу, третий где? Мне что парсить надо строчки?

что-то не так делаю?

Помогите разобраться!
Изменено: Роман Перминов - 02.02.2017 12:48:49
 
Похоже ,что проблема кроется в несоответствии unicode и ansi объявлений.

Если Вы используете Delphi XE2 и выше, то все объявления строковых переменных типа String реально будут как UnicodeString.
Char - тоже будут, соответственно, уже не однобайтовой кодировки.

Тогда как в ГИС-ядре указанная Вами функция требует кодировку ANSI.
Код
// Названия устройств из names предназначены для показа пользователю, а технические
// названия USB-устройств из programmNames - для установки связи с GPS-приемником.
// i-е название из names и i-е техническое название из programmNames соответствуют i-му устройству
long int _export WINAPI gpsTestGetUSBDevicesNames(char* names, char* programmNames, long int * count);
Для обращения к ней из Delphi следует сделать объявление:
Код
names: array [1..MAX_PATH] of AnsiChar; 
programmNames: array [1..MAX_PATH] of AnsiChar; 
function gpsTestGetUSBDevicesNames(names: PAnsiChar; programmNames: PAnsiChar; var count: Integer): Integer; 
{$IFNDEF LINUXAPI} stdcall {$ELSE} cdecl {$ENDIF} external sGisGps; 
В GIS ToolKit, кстати, есть специальное переопределения для этого - GTKString, GTKChar, GTKPString, GTKPChar.
 
Цитата
Денис Вицко написал:
Похоже ,что проблема кроется в несоответствии unicode и ansi объявлений.

Если Вы используете Delphi XE2 и выше, то все объявления строковых переменных типа String реально будут как UnicodeString.
Char - тоже будут, соответственно, уже не однобайтовой кодировки.

Тогда как в ГИС-ядре указанная Вами функция требует кодировку ANSI.
Код
 // Названия устройств из names предназначены для показа пользователю, а технические
// названия USB-устройств из programmNames - для установки связи с GPS-приемником.
// i-е название из names и i-е техническое название из programmNames соответствуют i-му устройству
long int _export WINAPI gpsTestGetUSBDevicesNames(char* names, char* programmNames, long int * count); 
Для обращения к ней из Delphi следует сделать объявление:
Код
 names: array [1..MAX_PATH] of AnsiChar; 
programmNames: array [1..MAX_PATH] of AnsiChar; 
function gpsTestGetUSBDevicesNames(names: PAnsiChar; programmNames: PAnsiChar; var count: Integer): Integer; 
{$IFNDEF LINUXAPI} stdcall {$ELSE} cdecl {$ENDIF} external sGisGps;  
В GIS ToolKit, кстати, есть специальное переопределения для этого - GTKString, GTKChar, GTKPString, GTKPChar.

Исправил на:
Код
function gpsTestGetUSBDevicesNames(names: PAnsiChar; programmNames: PAnsiChar; var count: Integer): Integer;
{$IFNDEF LINUXAPI} stdcall {$ELSE} cdecl {$ENDIF} external sGisGps;

Код
procedure TMainFrm.GPS2Click(Sender: TObject);
var
  Ret: Cardinal;
  names: array [1..MAX_PATH] of AnsiChar;
  programmNames: array [1..MAX_PATH] of AnsiChar;
  count: Integer;
begin
  try

    Ret := gpsTestGetUSBDevicesNames(PAnsiChar(@names), PAnsiChar(@programmNames), count);

  except
    on e:exception do AddErrInfo('TMainFrm.GPS2Click: ', E);
  end;
end;


Все равно выгружает UTF-8


Обратите внимание на данные которые содержат переменные. Может всеже ваш Api неправльно формирует строку names, programmNames при вызове функции.

names содержит:
('U', #0, 'S', #0, 'B', #0, '-', #0, 'C', #4, 'A', #4, 'B', #4, '@', #4, '>', #4, '9', #4, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, '!', #4, '>', #4, 'A', #4, 'B', #4, '0', #4, '2', #4, '=', #4, '>', #4, '5', #4, ' ', #0, 'U', #0, 'S', #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0)

programmNames
('\', #0, '\', #0, '?', #0, '\', #0, 'u', #0, 's', #0, 'b', #0, '#', #0, 'v', #0, 'i', #0, 'd', #0, '_', #0, '0', #0, '4', #0, '6', #0, 'd', #0, '&', #0, 'p', #0, 'i', #0, 'd', #0, '_', #0, 'c', #0, '0', #0, '7', #0, '7', #0, '#', #0, '5', #0, '&', #0, '3', #0, '0', #0, 'b', #0, '7', #0, 'b', #0, '9', #0, '9', #0, '0', #0, '&', #0, '0', #0, '&', #0, '1', #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, '\', #0, '\', #0, '?', #0, '\', #0, 'u', #0, 's', #0, 'b', #0, '#', #0, 'v', #0, 'i', #0, 'd', #0, '_', #0, '0', #0, '4', #0, '6', #0, 'd', #0, '&', #0, 'p', #0, 'i', #0, 'd', #0, '_', #0, 'c', #0, '3', #0, '1', #0, 'c', #0, '#', #0, '5', #0, '&', #0, '3', #0, '0', #0, 'b', #0, '7', #0, 'b', #0, '9', #0, '9', #0, '0', #0, '&', #0, '0', #0, '&', #0, '4', #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0, #0)

Вы не ответили на вопросы.
1. Мне нужно парсить строку?
2. Почему между записями много нулей?
 
Здравствуйте! Честно говоря очень много времени теряется на поиск истины.

У вас gpsApi ИМХО некорректно работает и некорректно выдает данные.

Итак чтобы получить путь сутройства функция gpsTestGetUSBDevicesNames не работает. Вместо этого я сделал вот это.

Код
  TPnPInfo = class
    DeviceID:        DWORD;
    DevicePath:      AnsiString;
    // registry values
    Capabilities:    DWORD;
    ClassDescr:      AnsiString;
    ClassGUID:       AnsiString;
    CompatibleIDs:   AnsiString;
    ConfigFlags:     DWORD;
    DeviceDescr:     AnsiString;
    Driver:          AnsiString;
    FriendlyName:    AnsiString;
    HardwareID:      AnsiString;
    LowerFilters:    AnsiString;
    Mfg:             AnsiString;
    UpperFilters:    AnsiString;
    Address:         AnsiString;
    BusNumber:       DWORD;
    BusType:         AnsiString;
    Characteristics: AnsiString;
    DevType:         AnsiString;
    EnumeratorName:  AnsiString;
    Exclusive:       DWORD;
    LegacyBusType:   AnsiString;
    LocationInfo:    AnsiString;
    PhysDevObjName:  AnsiString;
    Security:        AnsiString;
    Service:         AnsiString;
    UINumber:        DWORD;
    UINumberFormat:  AnsiString;
  end;


function GetRegistryPropertyString(PnPHandle: HDEVINFO; const DevData: TSPDevInfoData; Prop: DWORD): ansistring;
var
  BytesReturned: DWORD;
  RegDataType:   DWORD;
  Buffer:        array [0..256] of AnsiChar;
begin
  BytesReturned := 0;
  RegDataType   := 0;
  Buffer[0]     := #0;
  SetupDiGetDeviceRegistryProperty(PnPHandle, DevData, Prop,
    RegDataType, @Buffer[0], SizeOf(Buffer), BytesReturned);
  Result := Buffer;
end;

function GetRegistryPropertyDWord(PnPHandle: HDEVINFO; const DevData: TSPDevInfoData; Prop: DWORD): DWORD;
var
  BytesReturned: DWORD;
  RegDataType:   DWORD;
begin
  BytesReturned := 0;
  RegDataType   := 0;
  Result        := 0;
  SetupDiGetDeviceRegistryProperty(PnPHandle, DevData, Prop,
    RegDataType, @Result, SizeOf(Result), BytesReturned);
end;


procedure TMainFrm.GPS2Click(Sender: TObject);
var
  PnPHandle:               HDEVINFO;
  DevData:                 TSPDevInfoData;
  DeviceInterfaceData:     TSPDeviceInterfaceData;
  FunctionClassDeviceData: PSPDeviceInterfaceDetailData;
  Success:                 LongBool;
  Devn:                    Integer;
  BytesReturned:           DWORD;
  FHidGuid:                TGUID;
  PnPInfo:                 TPnPInfo;

begin
  try

    Memo1.Lines.Clear;

    FHidGuid := GUID_CLASS_USB_DEVICE; // GUID всех USB

    PnPHandle := SetupDiGetClassDevs(@FHidGuid, nil, 0, DIGCF_PRESENT or DIGCF_DEVICEINTERFACE);
    if PnPHandle = INVALID_HANDLE_VALUE then Exit;

    Devn := 0;
    repeat
      DeviceInterfaceData.cbSize := SizeOf(TSPDeviceInterfaceData);
      Success := SetupDiEnumDeviceInterfaces(PnPHandle, nil, @FHidGuid, Devn, @DeviceInterfaceData);
      if Success then
      begin
        DevData.cbSize := SizeOf(DevData);
        BytesReturned  := 0;
        SetupDiGetDeviceInterfaceDetail(PnPHandle, @DeviceInterfaceData, nil, 0, @BytesReturned, @DevData);
        if (BytesReturned <> 0) and (GetLastError = ERROR_INSUFFICIENT_BUFFER) then
        begin
          FunctionClassDeviceData := AllocMem(BytesReturned);
          FunctionClassDeviceData.cbSize := 5;
          if SetupDiGetDeviceInterfaceDetail(PnPHandle, @DeviceInterfaceData, FunctionClassDeviceData, BytesReturned, @BytesReturned, @DevData) then
          begin
//            with PnPInfo do
//            begin
              PnPInfo := TPnPInfo.Create;

              PnPInfo.DeviceID        := DevData.DevInst;
              PnPInfo.DevicePath      := PAnsiChar(@FunctionClassDeviceData.DevicePath);

              PnPInfo.Capabilities    := GetRegistryPropertyDWord (PnPHandle, DevData, SPDRP_CAPABILITIES);
              PnPInfo.ClassDescr      := GetRegistryPropertyString(PnPHandle, DevData, SPDRP_CLASS);
              PnPInfo.ClassGUID       := GetRegistryPropertyString(PnPHandle, DevData, SPDRP_CLASSGUID);
              PnPInfo.CompatibleIDs   := GetRegistryPropertyString(PnPHandle, DevData, SPDRP_COMPATIBLEIDS);
              PnPInfo.ConfigFlags     := GetRegistryPropertyDWord (PnPHandle, DevData, SPDRP_CONFIGFLAGS);
              PnPInfo.DeviceDescr     := GetRegistryPropertyString(PnPHandle, DevData, SPDRP_DEVICEDESC);
              PnPInfo.Driver          := GetRegistryPropertyString(PnPHandle, DevData, SPDRP_DRIVER);
              PnPInfo.FriendlyName    := GetRegistryPropertyString(PnPHandle, DevData, SPDRP_FRIENDLYNAME);
              PnPInfo.HardwareID      := GetRegistryPropertyString(PnPHandle, DevData, SPDRP_HARDWAREID);
              PnPInfo.LowerFilters    := GetRegistryPropertyString(PnPHandle, DevData, SPDRP_LOWERFILTERS);
              PnPInfo.Mfg             := GetRegistryPropertyString(PnPHandle, DevData, SPDRP_MFG);
              PnPInfo.UpperFilters    := GetRegistryPropertyString(PnPHandle, DevData, SPDRP_UPPERFILTERS);

              PnPInfo.Address         := GetRegistryPropertyString(PnPHandle, DevData, SPDRP_ADDRESS);
              PnPInfo.BusNumber       := GetRegistryPropertyDWord (PnPHandle, DevData, SPDRP_BUSNUMBER);
              PnPInfo.BusType         := GetRegistryPropertyString(PnPHandle, DevData, SPDRP_BUSTYPEGUID);
              PnPInfo.Characteristics := GetRegistryPropertyString(PnPHandle, DevData, SPDRP_CHARACTERISTICS);
              PnPInfo.DevType         := GetRegistryPropertyString(PnPHandle, DevData, SPDRP_DEVTYPE);
              PnPInfo.EnumeratorName  := GetRegistryPropertyString(PnPHandle, DevData, SPDRP_ENUMERATOR_NAME);
              PnPInfo.Exclusive       := GetRegistryPropertyDWord (PnPHandle, DevData, SPDRP_EXCLUSIVE);
              PnPInfo.LegacyBusType   := GetRegistryPropertyString(PnPHandle, DevData, SPDRP_LEGACYBUSTYPE);
              PnPInfo.LocationInfo    := GetRegistryPropertyString(PnPHandle, DevData, SPDRP_LOCATION_INFORMATION);
              PnPInfo.PhysDevObjName  := GetRegistryPropertyString(PnPHandle, DevData, SPDRP_PHYSICAL_DEVICE_OBJECT_NAME);
              PnPInfo.Security        := GetRegistryPropertyString(PnPHandle, DevData, SPDRP_SECURITY);
              PnPInfo.Service         := GetRegistryPropertyString(PnPHandle, DevData, SPDRP_SERVICE);
              PnPInfo.UINumber        := GetRegistryPropertyDWord (PnPHandle, DevData, SPDRP_UI_NUMBER);
              PnPInfo.UINumberFormat  := GetRegistryPropertyString(PnPHandle, DevData, SPDRP_UI_NUMBER_DESC_FORMAT);

            rzDevicesList.AddObject(PnPInfo.ClassDescr, PnPInfo);

            Inc(Devn);
          end;
          FreeMem(FunctionClassDeviceData);
        end;
      end;
    until not Success;
    SetupDiDestroyDeviceInfoList(PnPHandle);

    rzGpsSetupPanel.Visible := true;

  except
    on e:exception do AddErrInfo('TMainFrm.GPS2Click: ', E);
  end;
end;


Что же я здесь делаю? Ну я создал структуру PnPInfo куда собрал всю информацию о девайсе. Я это сделал намеренно, чтобы перебрать все ее параметры с целью выявления DevicePath собственно он был найден сразу.

Вот что я сделал дальше.

Код
procedure TMainFrm.rzConnectGpsBClick(Sender: TObject);
var
  item: TPnPInfo;
  device: GPSTEST;
  ret: Cardinal;
  ID: Cardinal;
  software_version: Integer;
  descrtiption: PWideChar;

begin
  try


    try
      if rzDevicesList.SelectedItem='' then begin
        ShowMessage('Выберите устройство для соединения');
        Exit;
      end;

      item := TPnpInfo(rzDevicesList.Items.Objects[rzDevicesList.ItemIndex]);

//      AsyncInit(pchar(item.DevicePath));
// Выше закоментированая команда это попытка договоритсья с девайсом на низком уровне через CreateFile, FileWrite, FileRead и т.д.

      device := gpsTestOpenUSBDevice(pAnsiChar(item.ClassDescr), PAnsiChar(item.DevicePath));
      if device = 0 then exit;


      getMem(descrtiption, MAX_PATH * sizeof(char));
      ret := gpsTestGetDescriptionUSBDevice(device, @ID, @software_version, descrtiption);

      Memo1.Lines.Add('ID: ' + IntToStr(ID));
      Memo1.Lines.Add('Ver: ' + IntToStr(software_version));
      Memo1.Lines.Add('Description: ' + descrtiption);

      Memo1.SelStart := Length(Memo1.Text);
      Memo1.SelLength := 0;
      SendMessage(Memo1.Handle, EM_SCROLLCARET, 0, 0);
    finally
      gpsTestCloseUSBDevice(device)
    end;

  except
    on e:Exception do AddErrInfo('TMainFrm.N1Click ', E);
  end;
end;
После выполнения функции gpsTestOpenUSBDevice все проходит замечательно. device не нулевой =) Значит открылся.

Далее вызываю функцию gpsTestGetDescriptionUSBDevice и все зависает. Программа не реагирует ни на что. ctrl+f2 в отладчике Дельфи.

Вот как-бы все.

Для того что бы убедиться, что мое устройство нормально соединяется, я попробовал в ГИС Карта 2011 соединиться с гарминкой и все вышло.
 
Проблемы с функцией gpsTestGetDescriptionUSBDevice  присутствуют на уровне исходного кода в библиотеке. Они те же самые, что и с остальными функциями gpsTest*** из этой библиотеки, работающих со строками.
Функции gpsTest*** были написаны около 10 лет назад и в них нет поддержки юникода.
Эту ситуацию мы исправим.

Хотя Вы прошли по правильному пути: получение системной информации об устройствах USB - это не задача прикладной части (ГИС-ядра), это решается общением программиста с операционной системой. Аналогично можно запросить и Description.

Если Вы обратили внимание, функции gpsTest*** не документированы. Заголовочный файл с ними не включен в состав GIS ToolKit.
Для работы с GPS используется API, описанный в gpsapi.h.
Остальные функции (недокументированные и невключенные в состав GTK) Вы используете, что называется, на свой страх и риск. Не исключена ситуация, что такие "секретные" функции могут в последующих версиях просто исчезнуть из dll.
Прошу прощения за то, что Dmitry_ рассказал Вам про эти функции.
Их работу мы исправим. Раз уж пока они есть в библиотеке, должны работать.
Но я настоятельно рекомендую Вам пользоваться только официальным MAPAPI, а функции gpsTest*** к таковому не относятся.
Собственно, слово Test этих функциях появилось, скорее всего, не случайно.
 
Спасибо за ответ! Я пока буду на низком уровне общаться с устройством. Вроде как нашел документацию по протоколам Garmin.

А приведенные выше "таблетки" я так понимаю работают с NMEA и с документированными функциями gpsapi?
Код
- BU-353(SiRF III) - таблетка USB. Использует драйвер USB-to-Serial Comm Port, версия 2.0.2.8. 
- BU-353(SiRF IV) - таблетка USB. Использует драйвер Prolific Serial-to-USB Comm Port, версия 3.3.17.203 от 29.04.2011 
Изменено: Роман Перминов - 16.02.2017 09:56:11
 
NMEA - общепринятый протокол, который де-факто является международным стандартом и поддерживается практически всеми GPS-приемниками.

MAPAPI функции, описанные в gpsapi.h, являются более-менее универсальными и позволяют общаться с различными GPS-устройствами через COM-порт. В том числе есть возможность общения и посредством протокола NMEA.

Что касается приемников Garmin, то с ними нам удавалось общаться и напрямую через USB посредством их родных протоколов, о чем Dmitry_ Вам написал выше. Такой интерфейс и был реализован в функциях gpsTest***, но, поскольку он получился узкоспециализированным с поддержкой только отдельных моделей Garmin, то распространения он не получил.

Функции, описанные в gpsapi.h, должны работать с приемниками различных производителей, в том числе и Garmin, которые подключаются к COM-порту и выдают сообщения в формате NMEA 0183.
Страницы: 1
Читают тему (гостей: 1)



© КБ Панорама, 1991-2024

Регистрируясь или авторизуясь на форуме, Вы соглашаетесь с Политикой конфиденциальности