OBEX 可能是通过支持蓝牙的设备传输文件最常用的技术。相反,由于它是最常见的,所以它的实际工作原理并没有很好的记录。
我在OBEX方面没有太多经验。我的目标是在我的笔记本电脑上设计一个 OBEX 客户端服务器,它应该通过像this这样的弹出窗口将文件发送到我的 Android 设备。
我选择了 C++ 作为在 Windows 上从头开始对服务器进行编程的语言。我正在使用的此操作的 UUID 是这个。
00001105-0000-1000-8000-00805F9B34FB
我已经像这样初始化了 OBEX 客户端。
GUID OBEX_GUID;
UuidFromString((unsigned char*)"00001105-0000-1000-8000-00805F9B34FB",(UUID*)&OBEX_GUID);
SOCKET soc,acpt;
SOCKADDR_BTH BluetoothAddress;
BluetoothAddress.addressFamily = AF_BTH;
BluetoothAddress.port = BT_PORT_ANY;
str2ba((char*)"BC:41:01:11:BC:2F",&BluetoothAddress.btAddr);
BluetoothAddress.serviceClassId = OBEX_GUID;
//OBEXObjectPushServiceClass_UUID;
soc = socket(AF_BTH , SOCK_STREAM , BTHPROTO_RFCOMM);
if(soc>0){
printf("Socket initialisation success\n");
}
stat = connect(soc,(sockaddr*)&BluetoothAddress,sizeof(BluetoothAddress));
printf("%s\n\n",(stat==0) ? "CONNECTED to the remote device!" : "Remote device is unavailable." );
此连接过程已成功,并且没有任何错误,它开始与地址为 BC:41:01:11:BC:2F 的 Android 设备进行通信。套接字的状态 connect() 函数返回零(也成功)。
现在,根据 OBEX 1.4 pdf ,我需要在成功建立连接后启动会话。所以在PDF的第38页中,连接的启动会话得到了很好的描述,我尝试模仿这样的连接包的语法
char connect_req[] = {
0x80 , 0x00 , 0x11 , 0x10 , 0x00 , 0x20 , 0x00 , 0xc0 , 0x00 , 0x00 , 0x00 , 0x01 , 0xc3 , 0x00 , 0x00 , 0xf4 , 0x83
// CNCT | 2B Length | Vers | Flag | Max Pack 8K | Count | 4 byte file count | Len Header | Total length of hex
};
将此连接包发送到我的 Android 后,它成功返回,值为 0xA0。这意味着会话终于开始了。
会话开始后,我需要发送一个虚拟文件,该文件需要作为 PUT 方法 进行请求,该方法在 PDF 的第 40 页中定义。尝试做同样的模仿,最终得到了这样的包。
unsigned char putfile_req[] = {
0x82 , 0x00 , 0x21 , 0x01 , 0x00 , 0x17 , 0x00,0x41 , 0x00,0x42 , 0x00,0x43 , 0x00,0x44 , 0x00,0x45 , 0x00,0x2c , 0x00,0x74 , 0x00,0x78 , 0x00,0x74 , 0xC3 , 0x00 , 0x00 , 0x00 , 0x01 , 0x49 , 0x00 , 0x01 , 0x74
// PUT | 2b Len | HI Name | NameLen | A B C D E . T X T | Len | 1 Byte | end | 1 Byte |
};
在发送文件名为 ABCDE.TXT(1 字节)的 PUT 请求时,我的 Android 的响应以某种方式返回不成功,值为零 (0)
问题是,在连接会话状态之前,每个请求和响应都工作得很好,但每当我发送带有文件名的 PUT 请求时,Android 都会收到它,但由于某些未知的原因,Android 无法处理它并返回零.
我听到有人说Android不支持OBEX,但如果这是实际因素,则在开始发送连接包时不会返回成功(A0)状态。
如果重要的话,这是完整的代码...
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <inttypes.h>
#include <winsock2.h>
#include <windows.h>
#include <ws2bth.h>
#include <bthsdpdef.h>
#include <bluetoothapis.h>
#include <ws2bth.h>
GUID OBEX_GUID;
int str2ba(const char *straddr, BTH_ADDR *btaddr)
{
int i;
unsigned int aaddr[6];
BTH_ADDR tmpaddr = 0;
if (sscanf(straddr, "%02x:%02x:%02x:%02x:%02x:%02x",
&aaddr[0], &aaddr[1], &aaddr[2],
&aaddr[3], &aaddr[4], &aaddr[5]) != 6)
return 1;
*btaddr = 0;
for (i = 0; i < 6; i++) {
tmpaddr = (BTH_ADDR) (aaddr[i] & 0xff);
*btaddr = ((*btaddr) << 8) + tmpaddr;
}
return 0;
}
int main(){
unsigned char response[10000]={0};
UuidFromString((unsigned char*)"00001105-0000-1000-8000-00805F9B34FB",(UUID*)&OBEX_GUID);
WSADATA ws;
WSAStartup(MAKEWORD(2,2),&ws);
int stat;
SOCKET soc,acpt;
SOCKADDR_BTH BluetoothAddress;
BluetoothAddress.addressFamily = AF_BTH;
BluetoothAddress.port = BT_PORT_ANY;
str2ba((char*)"BC:41:01:11:BC:2F",&BluetoothAddress.btAddr);
BluetoothAddress.serviceClassId = OBEX_GUID;
OBEXObjectPushServiceClass_UUID;
soc = socket(AF_BTH , SOCK_STREAM , BTHPROTO_RFCOMM);
if(soc>0){
printf("Socket initialisation success\n");
}
stat = connect(soc,(sockaddr*)&BluetoothAddress,sizeof(BluetoothAddress));
printf("%s\n\n",(stat==0) ? "CONNECTED to the remote device!" : "Remote device is unavailable." );
char connect_req[] = {
0x80 , 0x00 , 0x11 , 0x10 , 0x00 , 0x20 , 0x00 , 0xc0 , 0x00 , 0x00 , 0x00 , 0x01 , 0xc3 , 0x00 , 0x00 , 0xf4 , 0x83
// CNCT | 2B Length | Vers | Flag | Max Pack 8K | Count | 4 byte file count | Len Header | Total length of hex
};
unsigned char putfile_req[] = {
0x82 , 0x00 , 0x21 , 0x01 , 0x00 , 0x17 , 0x00,0x41 , 0x00,0x42 , 0x00,0x43 , 0x00,0x44 , 0x00,0x45 , 0x00,0x2c , 0x00,0x74 , 0x00,0x78 , 0x00,0x74 , 0xC3 , 0x00 , 0x00 , 0x00 , 0x01 , 0x49 , 0x00 , 0x01 , 0x74
// PUT | 2b Len | HI Name | NameLen | A B C D E . T X T | Len | 1 Byte | end | 1 Byte |
};
printf("PUT packet Length: %d\n\n",sizeof(putfile_req)/sizeof(unsigned char));
send(soc,(const char*)connect_req,sizeof(connect_req)/sizeof(connect_req[0]),0);
int Recvd = recv(soc,(char*)response,sizeof(response),0);
printf("OBEX CONNECT status: %X\n",response[0]);
if(response[0]==0xA0){
printf(" SUCCESS\n");
}
memset(response,0,sizeof(response));
send(soc,(char*)putfile_req,sizeof(putfile_req)/sizeof(putfile_req[0]),0);
Recvd = recv(soc,(char*)response,sizeof(response),0);
printf("PUT Request status: %X\n",response[0]);
if(response[0]==0x00){
printf("Something went wrong!\n");
}
}
输出看起来像, 即使连接会话成功并返回值 0xA0,套接字也会关闭并返回错误代码零作为 PUT 请求的响应。因此,我的 Android 端的弹出对话框不应该出现。
现在,我想要的只是从从头开始编写的 Winsock2 OBEX 客户端发送一个文件到我的 Android,其中我的 Android 设备中应该出现一个弹出窗口,要求用户接受或拒绝传入的文件或请求。接受后,文件传输应开始。
所以这似乎是我的错,我无法诊断。这就是为什么我在这里向该领域经验丰富的人寻求一些建议和帮助。
感谢和问候。
我有一个 C 编程的 OBEX 客户端,它成功地将以下命令发送到 Android。名称 = 你好.txt。 数据=你好。块大小 = 400。数据大小 = 5。 数据大小必须在 0xC3 4 字节项中发送,您的代码似乎值为 1。
unsigned char connect[7] = {0x80,0x00,0x07,0x10,0x00,0x01,0x90};
unsigned char send[39] = {0x82,0x00,0x27,
0x01,0x00,0x17,0,'h',0,'e',0,'l',0,'l',0,'o',0,'.',0,'t',0,'x',0,'t',0,0,
0xC3,0,0,0,5,
0x49,0,8,'H','e','l','l','o'};
unsigned char disconnect[3] = {0x81,0x00,0x03};