Страницы
| 1
|
2
| 3
|
4
|
Вступление
Наконец, после долгого перерыва я добрался и до заключительной, как я надеюсь,
части статьи про Bluetooth.
Здесь я постараюсь изложить в доступной форме, как же все-таки передавать данные
через Bluetooth. Я не буду приводить здесь каких-либо готовых примеров
приложений. Дам только теорию. К практике, я думаю, вы перейдете сами.
Как вы помните из предыдущих моих статей, мы используем исключительно Windows
API для работы с Bluetooth. Сразу хочу оговориться, что описанные здесь способы
не будут работать с драйверами BlueSoliel и VIDCOMM. В конце статьи я расскажу,
как установить драйвера от Microsoft, если вы это еще не сделали.
И так, приступаем.
Что вы должны знать
Прежде чем начать излагать основной материал, я хочу сформулировать требования к
вашим знаниям.
Вы должны понимать работу с сетями в Microsoft Windows и знать термины и
определения, данные мною в предыдущих статьях. Я буду часто отсылать к
пройденному материалу, что бы не повторяться.
Вы также должны более или менее разбираться в технологии Winsock.
Bluetooth и Winsock
Как не странно это звучит, но Microsoft решила реализовать всю функциональность
по передаче данных посредством Windows Socket Model. Тем, кто писал что-либо для
IrDA это должно показаться знакомым.
На мой взгляд – правильное решение. Зачем огород городить, когда уже есть
проверенные средства.
Я не буду описывать здесь все правила применения функций WinSock к работе с
Bluetooth. Остановлюсь лишь на практической стороне вопроса. А именно - передача
данных.
В статье мы сделаем простенький Bluetooth-клиент, который будет подсоединяться к
удаленному устройству как к модему и позволит вам выполнять AT-команды. Весьма
полезная вещь. Учтите, что данный клиент будет требовать авторизации устройств и
не будет требовать наличия в системе каких-либо виртуальных COM-портов.
Сервисы и профили
Сервисы и профили... Это два краеугольных понятия Bluetooth. В некотором смысле
– они идентичны.
Сервис – приложение-сервер, которое регистрирует определенным образом параметры
в стеке протоколов Bluetooth. Наименование (GUID) всех сервисов строго
определены Bluetooth.org.
Профиль – соглашения и стандарты работы сервиса. Понятнее объяснить не смогу.
Начало
И так, прежде чем можно будет использовать библиотеку WinSock, ее необходимо
инициализировать. Делается это вызовом функции WSAStartup.
Вот как она выглядит:
function WSAStartup(
wVersionRequired: Word;
var lpWSAData: WSAData): Integer; stdcall;
Не буду описывать все параметры, так как они есть в любой справочной системе (MSDN,
Delphi). Скажу только, что для использования WinSock с Bluetooth необходимо
указаь в качестве параметра wVersionRequired номер версии $0202.
Вот как выглядит вызов этой функции:
var
Data: WSADATA;
begin
if WSAStartUp($0202, Data) <> 0 then
raise Exception.Create(‘Winsock Initialization Failed.’);
По окончанию работы с WinSock библиотеку необходимо освободить. Для этого
существует функция WSACleanup.
function WSACleanup: Integer; stdcall;
Вызывается она просто, без всяких параметров. Возвращаемое значение, в принципе,
можно не проверять:
begin
WSACleanup;
Создание клиента
После того, как библиотека инициализирована, мы можем вызывать функции WinSock.
Давайте создадим простой сокет, для работы с Bluetooth устройствами. Для этого
необходимо вызвать функцию socket.
function socket(af, type_, protocol: Integer): TSocket; stdcall;
Вот как это делается:
var
ASocket: TSocket;
begin
ASocket := socket(AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
if ASocket = INVALID_SOCKET then RaiseLastOsError;
Функция вернет корректный описатель сокета, либо INVALID_SOCKET в случае ошибки.
Запомните, что Bluetooth поддерживает только потоковые сокеты (SOCK_STREAM).
Далее нам необходимо заполнить структуру SOCKADDR_BTH. В эту структуру
записывается информация о сервере, к которому нам нужно подключиться (адрес,
сервис и т.п.). Делается это следующим образом:
var
Addr: SOCKADDR_BTH;
AddrSize: DWORD;
begin
AddrSize := SizeOf(SOCKADDR_BTH);
FillChar(Addr, AddrSize, 0);
with Addr do begin
addressFamily := AF_BTH;
btAddr := ADeviceAddress;
serviceClassId := SerialPortServiceClass_UUID;
port := DWORD(BT_PORT_ANY);
end;
Здесь в переменной ADeviceAddress должен быть адрес устройства (Int64),
присоединяемся к любому порту (BT_PORT_ANY) сервиса SerialPortServiceClass.
Далее вызываем функцию connect, которая имеет вид:
function connect(s: TSocket; name: PSockAddr; namelen: Integer): Integer;
stdcall;
Делается это вот так:
begin
if connect(ASocket, @Addr, AddrSize) <> 0 then RaiseLastOsError;
Если функция выполнится успешно, вернет 0, в противном случае отличное от нуля
значение.
После того, как соединение установлено, можно передавать и принимать данные
через сокет функциями send и recv.
function send(s: TSocket; var buf; len, flags: Integer): Integer; stdcall;
function recv(s: TSocket; var buf; len, flags: Integer): Integer; stdcall;
Функции возвращают количество переданных или принятых байт в случае успеха и
отрицательное число в случае ошибки. Количество переданных или принятых байт
может быть меньше, чем указанная в параметре len длина буфера. Тогда вам нужно
повторить передачу/прием оставшихся байт.
Ну и закрытие сокета осуществляется вызовом функции closesocket:
function closesocket(s: TSocket): Integer; stdcall;
Опять же, возвращаемое значение можно проигнорировать (если вы знаете, что
делаете).
В общем то, вышеуказанный материал не представляет ничего нового для тех, кто
хоть раз программировал под WinSock. Единственное, на что следует обратить
внимание, это новые константы AF_BTH и BTHPROTO_RFCOMM.
Создание сервера
Как и создание клиента, создание сервера ничем не отличается от создания сервера
для любой службы WinSock.
И так, начнем. Сокет создается также как и в приведенном выше примере для
клиента. Точно также заполняем структуру Addt: SOCKADDR_BTH. Только в качестве
адреса устройства указываем 0. Далее, необходимо привязать сокет к адресу.
Делается это функцией bind:
function bind(s: TSocket; name: PSockAddr; namelen: Integer): Integer; stdcall;
Которая вызывается следующим образом:
begin
if Bind(ASocket, @Addr, AddrSize) <> 0 then RaiseLastOsError;
Далее вызываем функцию listen, для того чтобы сервер начал прослушивать сокет на
предмет подключения клиентов и функцию accept для приема входящего подключения:
function listen(s: TSocket; backlog: Integer): Integer; stdcall;
function accept(s: TSocket; addr: PSockAddr; addrlen: PINT): TSocket; stdcall;
Делается это вот так:
var
AClientSocket: TSocket;
begin
if listen(ASocket, 10) <> 0 then RaiseLastOSError;
AClientSocket = accept(ASocket, nil, nil);
После подключения клиента можно работать с AClientSocket – передавать и
принимать данные.
Если вы не желаете больше принимать входящие подключения, закройте слушающий
сокет.
Что осталось за кадром
Как и обещал, я коротко описал процедуры, необходимые для построения простого
клиента и сервера, которые будут работать с Bluetooth через WinSock.
Однако, здесь я не рассматривал вопросы регистрации сервисов и протоколы
верхнего уровня.
Приведенной здесь информации достаточно для того, что бы вы могли создать
приложение клиент, которое соединится с ваши телефоном по Bluetooth и сможет
выполнять AT-команды.
Более полную информацию и рабочие примеры можно найти здесь:
http://www.btframework.com.
Там же приведено решение по установке драйверов от Microsoft.
Страницы
| 1
|
2
| 3
|
4
|
Дата: 26.07.2007,
Автор:
Петриченко
Михаил.
Оригинал статьи:
http://mobileservicesoft.narod.ru/stat.html
|