Всем привет.
Пишу программу на д7 по обмену данными между пк и мобилкой на основе ик порта. Работаю через сокеты.
Набросал пример в котором инициализируется финсокет, создается сокет, и вытягивются данные о модели телефона.
Но вот подключться к телефону по обексу не получается.
Господа программеры помогите разобраться в пробеле.
if pbuf.numDevice = 0 then
List.Items.Add( 'Mibile device NOT FOUND......' )
else
for i := 0 to pbuf.numDevice — 1 do
begin
Name := '';
DEV_INFO_0 := pbuf.Device[ i ];
for j := 0 to 22 do
Name :=Name + DEV_INFO_0.irdaDeviceName[ j ];
List.Items.Add( 'Device ' + inttostr( i + 1 ) + '....' + Name );
List.Items.Add( '..............................' );
end;
Здравствуйте, Tsnok, Вы писали:
T>Всем привет. T>Пишу программу на д7 по обмену данными между пк и мобилкой на основе ик порта. Работаю через сокеты. T>Набросал пример в котором инициализируется финсокет, создается сокет, и вытягивются данные о модели телефона. T>Но вот подключться к телефону по обексу не получается. T>Господа программеры помогите разобраться в пробеле.
Для того чтобы законнектиться по OBEX SOCKADDR_IRDA ддолжна быть.
Проблема в том, что структура адреса и имя сервиса у меня определено.
Сам пишу на дельфи и с C почти незнаком.
Пример ( хотя бы общие вещи ) на дельфи не подкинешь.
Не понял этого выражения: T>Проблема в том, что структура адреса и имя сервиса у меня определено.
А в чем тогда проблема? Или даже так — а почему в этом проблема?
Почему (в чём) проблема, что "структура адреса и имя сервиса" определено?
Короче я не понял вопроса.
Я вот понимаю что определено, но не так. Значит надо провильно определить. Или что?
T>Сам пишу на дельфи и с C почти незнаком. T>Пример ( хотя бы общие вещи ) на дельфи не подкинешь.
С точностью до наоборот.-) Доже на слух морщусь от слова Pascal
T>Благодарю за помошь.
Здравствуйте, Tsnok, Вы писали:
T>Дело в том, что для связи с мобильным устройством использую сокеты — WINSOCK, и ком порт(эмуляция его работы) мне не подходит
А где ты увидел COM порт? Если ты про (TComm), то это базовый класс работы с портами (это мной написано поэтому не ищи в справке) от которого наследуются классы для работы уже с COM, IrDA, Bluetooth.
И в функцию описанную выше
bool OBEX_FTP::Open(TComm *p)
Я уже передаю готовый открытый порт (а что это за порт это не важно).
Просто если это COM порт то его надо предварительно перевести (на мобильном устройстве) в двоичный (точнее в данном случае OBEX, потому что существуют и другие режимы) режим AT коммандой (какой зависит от устройсва, фирмы, модели).
А в случае с открытием через Инфракрасный порт или BT посредством сокетов ты указывая в свойсвах SOCKADDR_IRDA "OBEX"
Ты говоришь ему по какому протоколу будешь общаться через этот сокет. Потому что есть ещё масса других протоколов (и тот же СОМ потр, и печать на принтере, и нискоуровневые. А у Bluetooth я вообще молчу)
Конечно нужно и другие поля этой струкруры заполнить. Ты же ещё не сказал к какому конкретно устройству будешь обращаться (а ведь можно сразу параллельно к нескольким).
что то типа того (это выдержки из моего кода для понимания):
#define DEVICE_LIST_LEN 10
unsigned char DevListBuff[sizeof(DEVICELIST) -
sizeof(IRDA_DEVICE_INFO) +
(sizeof(IRDA_DEVICE_INFO) * DEVICE_LIST_LEN)];
int DevListLen = sizeof(DevListBuff);
PDEVICELIST pDevList = (PDEVICELIST) &DevListBuff;
pDevList->numDevice = 0;
getsockopt(sock, SOL_IRLMP, IRLMP_ENUMDEVICES,
(char *) pDevList, &DevListLen);
if (pDevList->numDevice == 0) // Не найдено ни одного устройства
{
...
}
else
{
for (int i = 0; i < (int) pDevList->numDevice; i++)
{
memcpy(&SockAddr.irdaDeviceID[0], &pDevList->Device[i].irdaDeviceID[0], 4);
}
}
остаётся только запросить нужный сервис у OBEX (пример кода я приводил выше). Он же не только просмотр файлов обеспечивает:
Открыть сокет мне удалось, мобильник определяет подключение.
Возникли следующие вопросы, если несложно,
1. Как можно прочитать каталоги с файлами.( и вообще как работать с каталогами )\\ например"image/jpeg"
2. Как можно задать скорость соединения.
Здравствуйте, Tsnok, Вы писали:
T>Открыть сокет мне удалось, мобильник определяет подключение.
T>Возникли следующие вопросы, если несложно, T> 1. Как можно прочитать каталоги с файлами.( и вообще как работать с каталогами )\\ например"image/jpeg"
Т.е. до этого такого вопроса не возникало
Вот с этого момента при работе с OBEX и начинается гимморой!
После того как ты открыл сокет, нужно открыть OBEX сессию. Код я приволил выше, прничём это рабочий код! http://www.rsdn.ru/Forum/?mid=1470363
А устройств должно тебе ответить тоже пачкой байтов которую нужно "расшифровать".
Вот пример из того файла.
Client Request: bytes Meaning
Opcode 0x80 CONNECT, Final bit set
0x0011 packet length = 17
0x10 version 1.0 of OBEX
0x00 flags, all zero for this version of OBEX
0x2000 8K is the max OBEX packet size client can accept
0xC0 HI for Count header (optional header)
0x00000004 four objects being sent
0xC3 HI for Length header (optional header)
0x0000F483 total length of hex F483 bytes
Server
Response:
response code 0xA0 SUCCESS, Final bit set
0x0007 packet length of 7
0x10 version 1.0 of OBEX
0x00 Flags
0x0400 1K max packet size
Т.е. мобилка тебе когда ответит то первый байт должен быть 0xA0.
Потом, два байта, длина всего этого пакета 0x0007 включая и первый байт. Т.е. ты можешь всегда при
работе с OBEX сначала читать три первых байта, потом зная сколько он тебе должен прислать читаешь остатки, а потом
разбараешь уже что там тебе прислали.
Даже если устройство вернёт ошибку оно вернет 3 байта (ну иногда больше) где первй байт код ошибки и 2 байта (с числом 0x0003) это длина.
Короче тебе теперь нужно дабиться открытия OBEX сессии (кстати закрывать её тоже надо, для этого есть коды, описаны в указанном файле).
А потом уже можно двигаться дальше, запрашивать нужные сервисы у сервера (удаленное устройство является сервером OBEX по отношению к клиенту — ПК).
T> 2. Как можно задать скорость соединения.
А этот вопрос пусть вообще тебя не волнует. Во всяком случае пока. Связь устанавливается по умолчанию на максимально возможной скорости. Ты можешь только понижать скорость влезая в эту кухню. И то это ещё надо суметь, а оно тебе надо?
Здравствуйте, kiborg, Вы писали:
K>т.е. ты должен послать такую последовательность в порт
Я кончно извиняюсь за глупый вопрос, но как связать сокет и порт.
И какими функциями можно воспользоваться для отправки в порт, и чтения из порта. \\предполагаю что сенд и ресайв, но неуверен.
T>Я кончно извиняюсь за глупый вопрос, но как связать сокет и порт.
А ты упорный. Ещё чуть-чуть и у тебя получиться.
Конечно говоря о портах может возникнуть некоторая путаница, потому что разные вещи называются портами.
Но в данном контексте я имею ввиду сокет = порт. Ты открыл сокет, это и есть порт. Тебе остаётся только посылать и принимать байты через этот сокет.
T>И какими функциями можно воспользоваться для отправки в порт, и чтения из порта. \\предполагаю что сенд и ресайв, но неуверен.
Совершенно верно. Только зачем извращать и без того извращенное? Функции называются своими именами латинскими буквами:
int send (
SOCKET s,
const char FAR * buf,
int len,
int flags
);
Ну и другая, как там ты её обозвал.
Как видишь при вызове указывается сокет (SOCKET s) который ты открыл (открыл?) и никаких там портов.
Другой вопрос что лучше бы перевести сокет из режима по умолчанию в "не блокирующий" (асинхронный) режим, о то можно навсегда уйдти в ожидание ответа с порта. Но это тебе к книгам по программированию сокетов, мобильные устройства тут не причем.
Но это всё потом. Если не бросишь всё это.
Здравствуйте, kiborg, Вы писали:
>> // opcode|length |version|flag|packsize|HI|data length|data(uuid) >> // 80 | 001A |10 |00 |0x2000 |46|0013 |6B01CB31410611D49A770050DA3F471F >> Всё это описано в спецификации на протокол OBEX
>> А устройств должно тебе ответить тоже пачкой байтов которую нужно "расшифровать". >> Вот пример из того файла.
>> Client Request: bytes Meaning >> Opcode 0x80 CONNECT, Final bit set >> ..........
Попытался реализовать OBEX сессию, но возникли проблемы.
Посмотрел доку по OBEX, и попробывал открыть сессию ... при передаче данных инфракрасник начинает сильнее моргать примерно на 150 милисекунд, а затем как обычно, в режиме ожидания, но в буфере который читает полученную информацию ничего нет.
ПОдскажите, что не так делаю ... ?
\\при отрпавке сокет создан + установлен коннект с мобилкой( мобила информирует об установленном соединении )
Здравствуйте, Tsnok, Вы писали:
T>Здравствуйте, kiborg, Вы писали:
>>> // opcode|length |version|flag|packsize|HI|data length|data(uuid) >>> // 80 | 001A |10 |00 |0x2000 |46|0013 |6B01CB31410611D49A770050DA3F471F >>> Всё это описано в спецификации на протокол OBEX
T>Попытался реализовать OBEX сессию, но возникли проблемы.
Хотя я и не понимаю паскаль конкретно, но принцип то любого языка понятен.
И глядя на твой код вижу что ты пока не ведаешь что творишь.
Конечно он работать не будет, потому как в каждой первой строке ошибки.
T> BUF_S : array [ 0 .. 4096 ] of Char;
Хотя это не принципиально, но максимальный размер пакета
в OBEX 8КБ может быть, вроде как я понял читая спецификацию
Ты скачал спецификацию?
Далее, забудь про символы. Ты посылаешь конкретно пакет байтов который сам формируешь.
Т.е. 80h это число в шестнадцатеричной системе (в десятичной 128), а не код символа.
T> Buf_s[ 0 ] := chr( $80 );
Т.о. здесь должно быть, как то так:
Buf_s[ 0 ] := 128;
или вместо лучше 128 в шестнадцатеричной системе, но я не знаю как в Паскале
наверно так:
Buf_s[ 0 ] := $80;
Далее в следующей строке сразу две ошибки
T> Buf_s[ 1 ] := chr( $001A ); Во первых 001Ah это длина (length) пакета в байтах (26 байт)
Конкретно вот этого:
Если ты посчитаешь количество этих байт то получишь 26.
80 — один, 00 — два, 1A — три, 10 — четыре....
Но это длина моего пакета. У твоего длина другая (хотя у тебя вообще не пакет пока а мусор)
Во вторых 001A это ДВА байта. Т.е. на Си я писал бы так
*((unsigned short *)&Buf_s[1]) = ((unsigned short)0x001A);
Но я не знаю как на Паскале преобразовавать типы. Суть в том что должно быть так
Buf_s[ 1 ] := $00;
Buf_s[ 2 ] := $1A;
Понимаешь? А уже потом
Buf_s[ 3 ] := $10; и т.д.
T> Buf_s[ 2 ] := chr( $10 ); T> Buf_s[ 3 ] := chr( $00 );
Соответсвенно это тоже бред T> Buf_s[ 4 ] := chr( $0800 );
А это вообще что? T> Buf_s[ 5 ] := chr( $70 ); T> Buf_s[ 6 ] := chr( $13 );
Далее соответственно ты посылаешь не строку (что ты зачем то пылался сделать завершая символом $13).
Поэтому нельзя вичислить длину. Поэтому никаких length
Но ты точно знаешь количество посылаемых байт, потому что ты сам формируешь паакет, вот его и указываешь.
И в Buf_s[ 1 ], Buf_s[ 2 ] и в функции send()
T> send( Sock, BUF_S, length( BUF_S ) + 1, 0 );
T> Sleep( 500 );
Это кто тебя научил так делать?
Самое главное бессмысленно. recv не завершиться пока не считает байты (в синхронном режиме конечно, но он и есть по умолчанию)
И опять же пол секунды зачем ждать, а если считает быстрее, зачем лишний тормоз?
T> recv( Sock, BUF_SND, length( BUF_SND ) + 1, 0 );
T> Посмотрел доку по OBEX, и попробывал открыть сессию ... при передаче данных инфракрасник начинает сильнее моргать примерно на 150 милисекунд, а затем как обычно, в режиме ожидания, но в буфере который читает полученную информацию ничего нет.
Ну а чё бы ему не мигать, ты же посылаешь свой мусор в эфир через сокет.
Вот когда пошлешь на языке понятном для сервера, он тебе и ответит.
T>ПОдскажите, что не так делаю ... ? T>\\при отрпавке сокет создан + установлен коннект с мобилкой( мобила информирует об установленном соединении )
T>Благодарю за помощь!
Ну а где благодарность? Хотя бы ввиде оценок и плюсиков???
... T>Попытался реализовать OBEX сессию, но возникли проблемы.
T> BUF_S : array [ 0 .. 4096 ] of Char;
T> Buf_s[ 0 ] := chr( $80 ); T> Buf_s[ 1 ] := chr( $001A ); T> Buf_s[ 2 ] := chr( $10 ); T> Buf_s[ 3 ] := chr( $00 ); T> Buf_s[ 4 ] := chr( $0800 ); T> Buf_s[ 5 ] := chr( $70 ); T> Buf_s[ 6 ] := chr( $13 ); T> send( Sock, BUF_S, length( BUF_S ) + 1, 0 ); T> Sleep( 500 ); T> recv( Sock, BUF_SND, length( BUF_SND ) + 1, 0 );
T> Посмотрел доку по OBEX, и попробывал открыть сессию ... при передаче данных инфракрасник начинает сильнее моргать примерно на 150 милисекунд, а затем как обычно, в режиме ожидания, но в буфере который читает полученную информацию ничего нет.
T>ПОдскажите, что не так делаю ... ?
Все не так http://64.233.183.104/search?q=cache:RPbQFs0ZwvsJ:www.pocketpcdn.com/articles/obex.html+obex+cpp&hl=ru — рабочий код чтения/записи через IrDA OBEX
Надо прочитать и перестать глупости спрашивать.
T>\\при отрпавке сокет создан + установлен коннект с мобилкой( мобила информирует об установленном соединении )
T>Благодарю за помощь!
Здравствуйте, Tsnok, Вы писали:
T>Всем привет. T>Пишу программу на д7 по обмену данными между пк и мобилкой на основе ик порта. Работаю через сокеты. T>Набросал пример в котором инициализируется финсокет, создается сокет, и вытягивются данные о модели телефона. T>Но вот подключться к телефону по обексу не получается. T>Господа программеры помогите разобраться в пробеле.
T>GLOB VAR T> WSAData_ : WSAdata; T> Sock : TSocket; T> devlist : PWINDOWS_DEVICELIST; T> irADRR : SOCKADDR_IRDA;
T> var T> buf: array[ 0..4096 ]of char; T> temp: integer; T> res: integer; T> pbuf: PWINDOWS_DEVICELIST; T> DEV_INFO_0 : _windows_IRDA_device_info; T> i,j : longint; T> Name : string; T> time : longint; {debug var} //\\\\\\\\\\\
T> is_rec : IAS_SET; //irADRR : TirDASockADRR ;// = ( AF_IRDA,0,0,0,0,''#0'' );
T> tmp : longint; T>begin T> Sock:= Socket( AF_IRDA, SOCK_STREAM, 0);
T> temp := 4096; T> res := getsockopt(Sock, SOL_IRLMP, IRLMP_ENUMDEVICES, buf, temp); T> pBuf := @buf;
T> irADRR.irdaAddressFamily := AF_IRDA; T> for i := 0 to 4 do T> irADRR.irdaDeviceID[ i ] := pbuf.numDevice; T> irADRR.irdaServiceName := 'IrDA:IrCOMM'; T> tmp := connect( Sock, TSockAddr(( @irADRR )^), sizeof( irADRR ) );
T> List.Items.Add( 'Count found device"s...' + IntToStr( pbuf.numDevice ) ); // List.Items.Add( PCHAR( DEV_INFO_0.irdaDeviceID ) );
T> if pbuf.numDevice = 0 then T> List.Items.Add( 'Mibile device NOT FOUND......' ) T> else T> for i := 0 to pbuf.numDevice — 1 do T> begin T> Name := ''; T> DEV_INFO_0 := pbuf.Device[ i ];
T> for j := 0 to 22 do T> Name :=Name + DEV_INFO_0.irdaDeviceName[ j ]; T> List.Items.Add( 'Device ' + inttostr( i + 1 ) + '....' + Name ); T> List.Items.Add( '..............................' ); T> end;
T>ЗЫ T>Благодарю за помощь!
Уважаемый Tsnok, столкнулся с такой же задачей (связать телефон с компом по ИК). Только у меня успехов еще меньше
Я так же как и Вы дружу больше с Делфи чем с Си. Если вы добились каких-либо результатов — помогите мне. Во-первых, что надо подключить чтобы хотябы приведенный вами код давал признаки жизни? а если можете, не могли бы вы выложить полный листинг. (обещаю использовать только в ознакомительных целях ) Благодарю!
Здравствуйте, Tsnok, Вы писали:
T>Подключи winsock. T>Если закончу свой труд( — надеюсь на это ), скорее всего выложу
WinSock я подключил. У меня ругается вот так:
[Error] Unit1.pas(24): Undeclared identifier: 'PWINDOWS_DEVICELIST'
[Error] Unit1.pas(25): Undeclared identifier: 'SOCKADDR_IRDA'
по-моему, надо подключить что-то типа af_irda.h в Си
Здравствуйте, Mickey_Mouse, Вы писали:
M_M>Здравствуйте, Tsnok, Вы писали:
T>>Подключи winsock. T>>Если закончу свой труд( — надеюсь на это ), скорее всего выложу
M_M> WinSock я подключил. У меня ругается вот так:
M_M> [Error] Unit1.pas(24): Undeclared identifier: 'PWINDOWS_DEVICELIST' M_M> [Error] Unit1.pas(25): Undeclared identifier: 'SOCKADDR_IRDA' M_M>по-моему, надо подключить что-то типа af_irda.h в Си
из ддк бери заголовочный файл, портируй под д, и подключай в проектте ...
Здравствуйте, Tsnok, Вы писали:
T>Здравствуйте, kiborg:
T>оформил пакет, ( не уверен, чтио правильно, но пока только так, )
Думаешь с той стороны кто-то сидит и небольшие неточности твои исправляет?
Увы. Тогда тебе к гумманитариям. Они могут седня так бла-бла, завтра диаметрально противоположно.
А тут либо поедет, либо нет.
Тык вот. Я тебе зачем писал что ты байты должен передпвать?
Почему ты их упорно превращаешь в коды символов? ЗАЧЕМ??? Ты применяешь функцию chr???
В Buf_s[ 0 ] должно быть число $80.
в результате выполнения chr
выдается буква, порядковый номер которой (ASCII код) равен аргументу функции
T> BUF_S, T> BUF_R : packed array [ 0 .. 8192 ] of Char; //Real;
T> Buf_s[ 0 ] := chr( $80 ); T> Buf_s[ 1 ] := chr( $00 ); T> Buf_s[ 2 ] := chr( $07 ); T> Buf_s[ 3 ] := chr( $10 ); T> Buf_s[ 4 ] := chr( $00 ); T> Buf_s[ 5 ] := chr( $01 ); T> Buf_s[ 6 ] := chr( $00 );
Напиши напротив каждой строки выше тобой приведённой, что ты имеешь ввиду под байтом присваемым тобобой
в каждую ячейку.
А где у тебя uuid сервиса OBEX для которого выполняется операция???
T> View_BUF_SND.AppendBuffer( @BUF_S, 7 ); T> View_BUF_SND.SelStart := 0;
T> recv( Sock, BUF_R, sizeof( BUF_R ), 0 ); T> View_BUF_RCV.AppendBuffer( @BUF_R, 256 ); T> View_BUF_RCV.SelStart := 0;
T>в ответ получаю, соедующее [ A0 00 07 10 00 01 00 ]
Даже не буду анализировать потому что этого не может быть.
T>начало вроде правильно( если смореть спецификацию ), но все остальное дублирует отправляемое ...
T>при отправке [ 81 00 03 ] это, как я понимаю разрыв сесси, получаю [ A0 00 07 10 00 01 ]
А этого тем более не может быть потому что показано что должно быть 7 байт в пакете, а ты привел 6.