Implementing OBEX PUSH Server on Android 2.3
I need to setup an in-app OBEX server on an Android 2.3 device. Using the Bluetooth Chat Sample code I was able to setup an OBEX server. However, the server needs to use a custom UUID so the service is not registered as an 'OBEX Server'
# sdptool browse local
...(snip)...
Service Name: OBEX Object Push
Service RecHandle: 0x10000
Service Class ID List:
UUID 128: ab123abc-1a2b-3c4d-5d7f-1234567890ab
Protocol Descriptor List:
"L2CAP" (0x0100)
"RFCOMM" (0x0003)
Channel: 18
So, when I receive data, it looks like I am receiving a raw OBEX 开发者_运维技巧connection request:
80 00 07 10 00 04 00 00 00 00 ...(snip)... 00 00 00 (1kb file)
Is there an OBEX implementation that I can use or do I have to implement the protocol myself?
I don't want to use the inbuilt OBEX server - this has to be in app. I have tried BlueCove but I abandoned it when I had issues registering a service.
Yes, I did see this post and read the link in it, but by golly, there must be an easier way!
I ended up implementing the protocol myself. It wasn't as hairy as I imagined. Since I was expecting only a specific client to connect and I knew that the client would only be pushing one file I was able to partially implement only the sections of the protocol that I needed.
Some documentation that helped with understanding the OBEX protocol were Obex13.pdf at: http://gitorious.org/gammu/gsm-docs/trees/e5161a75fb1e1c1608959b27ae3c3940bcf0911b/standards/obex
A quick snippet of how I parsed the sockets input stream: (Note OBEXUtils and OBEXConstants are my classes.)
try
{
//Read all bytes passed in
bytes = mmInStream.read(buffer);
//Ensure we have the entire packet before we proceed
// Packet length is in the 1st and 2nd byte
expectedLength = OBEXUtils.bytesToShort(buffer[OBEXConstant.LENGTH_IDENTIFIER],
buffer[OBEXConstant.LENGTH_IDENTIFIER + 1]);
packetLength = bytes;
//Keep reading until we get what we expect.
while (packetLength < expectedLength)
{
bytes = mmInStream.read(buffer, packetLength, maxPacketSize);
packetLength += bytes;
}
//Switch on Packet Header
switch (buffer[OBEXConstant.HEADER_IDENTIFIER])
{
case OBEXConstant.CONNECT:
//Parse the packet and return an acknowledgement packet
write(OBEXConnect.parsePacket(buffer));
break;
case OBEXConstant.PUT:
case OBEXConstant.PUT_FINAL:
//Parse the PUT packet and return an acknowledgement packet
//For Parsing PUT packets I referred to the android and bluecove implementations
write(putPacket.appendPacket(buffer, packetLength));
break;
case OBEXConstant.DISCONNECT:
//Parse the packet and return an acknowledgement packet
write(OBEXDisconnect.parsePacket(buffer));
break;
case OBEXConstant.GET:
case OBEXConstant.GET_FINAL:
case OBEXConstant.SETPATH:
case OBEXConstant.SETPATH_FINAL:
case OBEXConstant.SESSION:
//Did not implement these
break;
case OBEXConstant.ABORT:
Log.w(Constant.TAG, TAG + "ABORT Request Received");
isDisconnected = true;
break;
default:
break;
}
}
catch (final IOException e)
{
...(snip)...
}
Snip of OBEXConstant:
public static final byte FINAL_BIT = (byte) 0x80;
public static final byte CONNECT = 0x00 | FINAL_BIT; //*high bit always set Connect choose your partner, negotiate capabilities
public static final byte DISCONNECT = 0x01 | FINAL_BIT; //*high bit always set Disconnect signal the end of the session
public static final byte PUT = 0x02; //(0x82) Put send an object
public static final byte PUT_FINAL = PUT | FINAL_BIT;
public static final byte GET = 0x03; //(0x83) Get get an object
public static final byte GET_FINAL = GET | FINAL_BIT; //(0x83) Get get an object
public static final byte SETPATH = 0x05;
public static final byte SETPATH_FINAL = SETPATH | FINAL_BIT;
public static final byte SESSION = 0x07;
public static final byte ABORT = (byte) 0xFF;
public static final byte OBEX_RESPONSE_CONTINUE = (byte) 0x90;
public static final byte OBEX_RESPONSE_SUCCESS = (byte) 0xA0;
maybe this helps: com.android.bluetooth.pbap.BluetoothPbapObexServer
精彩评论