Bug 799138 - [b2g-bluetooth] Handle Connect/Disconnect/Put requests sent from remote devices, r=qdot

This commit is contained in:
Eric Chou 2012-10-09 13:56:17 +08:00
parent c6bfffd40f
commit 2291b0cd5c
2 changed files with 124 additions and 11 deletions

View File

@ -95,6 +95,7 @@ BluetoothOppManager::BluetoothOppManager() : mConnected(false)
, mRemoteMaxPacketLength(0)
, mAbortFlag(false)
, mReadFileThread(nullptr)
, mPacketLeftLength(0)
{
}
@ -188,12 +189,20 @@ BluetoothOppManager::StopSendingFile(BluetoothReplyRunnable* aRunnable)
void
BluetoothOppManager::ReceiveSocketData(UnixSocketRawData* aMessage)
{
uint8_t responseCode = aMessage->mData[0];
int packetLength = (((int)aMessage->mData[1]) << 8) | aMessage->mData[2];
uint8_t opCode;
int packetLength;
int receivedLength = aMessage->mSize;
if (mPacketLeftLength > 0) {
opCode = ObexRequestCode::Put;
packetLength = mPacketLeftLength;
} else {
opCode = aMessage->mData[0];
packetLength = (((int)aMessage->mData[1]) << 8) | aMessage->mData[2];
}
if (mLastCommand == ObexRequestCode::Connect) {
if (responseCode == ObexResponseCode::Success) {
if (opCode == ObexResponseCode::Success) {
mConnected = true;
// Keep remote information
@ -236,16 +245,17 @@ BluetoothOppManager::ReceiveSocketData(UnixSocketRawData* aMessage)
}
}
} else if (mLastCommand == ObexRequestCode::Disconnect) {
if (responseCode != ObexResponseCode::Success) {
if (opCode != ObexResponseCode::Success) {
// FIXME: Needs error handling here
NS_WARNING("[OPP] Disconnect failed");
} else {
mConnected = false;
mLastCommand = 0;
mBlob = nullptr;
mReadFileThread = nullptr;
}
} else if (mLastCommand == ObexRequestCode::Put) {
if (responseCode != ObexResponseCode::Continue) {
if (opCode != ObexResponseCode::Continue) {
// FIXME: Needs error handling here
NS_WARNING("[OPP] Put failed");
} else {
@ -266,7 +276,7 @@ BluetoothOppManager::ReceiveSocketData(UnixSocketRawData* aMessage)
}
}
} else if (mLastCommand == ObexRequestCode::PutFinal) {
if (responseCode != ObexResponseCode::Success) {
if (opCode != ObexResponseCode::Success) {
// FIXME: Needs error handling here
NS_WARNING("[OPP] PutFinal failed");
} else {
@ -274,12 +284,46 @@ BluetoothOppManager::ReceiveSocketData(UnixSocketRawData* aMessage)
SendDisconnectRequest();
}
} else if (mLastCommand == ObexRequestCode::Abort) {
if (responseCode != ObexResponseCode::Success) {
if (opCode != ObexResponseCode::Success) {
NS_WARNING("[OPP] Abort failed");
}
FileTransferComplete(false, false, sFileName, sSentFileLength);
SendDisconnectRequest();
} else {
// Remote request or unknown mLastCommand
if (opCode == ObexRequestCode::Connect) {
ReplyToConnect();
} else if (opCode == ObexRequestCode::Disconnect) {
ReplyToDisconnect();
} else if (opCode == ObexRequestCode::Put ||
opCode == ObexRequestCode::PutFinal) {
/*
* A PUT request from remote devices may be divided into multiple parts.
* In other words, one request may need to be received multiple times,
* so here we keep a variable mPacketLeftLength to indicate if current
* PUT request is done.
*/
bool final = (opCode == ObexRequestCode::PutFinal);
if (mPacketLeftLength == 0) {
if (receivedLength < packetLength) {
mPacketLeftLength = packetLength - receivedLength;
} else {
ReplyToPut(final);
}
} else {
NS_ASSERTION(mPacketLeftLength < receivedLength,
"Invalid packet length");
if (mPacketLeftLength <= receivedLength) {
ReplyToPut(final);
mPacketLeftLength = 0;
} else {
mPacketLeftLength -= receivedLength;
}
}
}
}
}
@ -289,7 +333,8 @@ BluetoothOppManager::SendConnectRequest()
if (mConnected) return;
// Section 3.3.1 "Connect", IrOBEX 1.2
// [opcode:1][length:2][version:1][flags:1][MaxPktSizeWeCanReceive:2][Headers:var]
// [opcode:1][length:2][version:1][flags:1][MaxPktSizeWeCanReceive:2]
// [Headers:var]
uint8_t req[255];
int index = 7;
@ -308,7 +353,8 @@ BluetoothOppManager::SendConnectRequest()
}
void
BluetoothOppManager::SendPutHeaderRequest(const nsAString& aFileName, int aFileSize)
BluetoothOppManager::SendPutHeaderRequest(const nsAString& aFileName,
int aFileSize)
{
uint8_t* req = new uint8_t[mRemoteMaxPacketLength];
@ -354,7 +400,7 @@ BluetoothOppManager::SendPutRequest(uint8_t* aFileBody,
return;
}
// IrOBEX 1.2 3.3.3
// Section 3.3.3 "Put", IrOBEX 1.2
// [opcode:1][length:2][Headers:var]
uint8_t* req = new uint8_t[mRemoteMaxPacketLength];
@ -378,7 +424,7 @@ BluetoothOppManager::SendPutRequest(uint8_t* aFileBody,
void
BluetoothOppManager::SendDisconnectRequest()
{
// IrOBEX 1.2 3.3.2
// Section 3.3.2 "Disconnect", IrOBEX 1.2
// [opcode:1][length:2][Headers:var]
uint8_t req[255];
int index = 3;
@ -407,6 +453,69 @@ BluetoothOppManager::SendAbortRequest()
SendSocketData(s);
}
void
BluetoothOppManager::ReplyToConnect()
{
if (mConnected) return;
mConnected = true;
// Section 3.3.1 "Connect", IrOBEX 1.2
// [opcode:1][length:2][version:1][flags:1][MaxPktSizeWeCanReceive:2]
// [Headers:var]
uint8_t req[255];
int index = 7;
req[3] = 0x10; // version=1.0
req[4] = 0x00; // flag=0x00
req[5] = BluetoothOppManager::MAX_PACKET_LENGTH >> 8;
req[6] = BluetoothOppManager::MAX_PACKET_LENGTH;
SetObexPacketInfo(req, ObexResponseCode::Success, index);
UnixSocketRawData* s = new UnixSocketRawData(index);
memcpy(s->mData, req, s->mSize);
SendSocketData(s);
}
void
BluetoothOppManager::ReplyToDisconnect()
{
if (!mConnected) return;
mConnected = false;
// Section 3.3.2 "Disconnect", IrOBEX 1.2
// [opcode:1][length:2][Headers:var]
uint8_t req[255];
int index = 3;
SetObexPacketInfo(req, ObexResponseCode::Success, index);
UnixSocketRawData* s = new UnixSocketRawData(index);
memcpy(s->mData, req, s->mSize);
SendSocketData(s);
}
void
BluetoothOppManager::ReplyToPut(bool aFinal)
{
if (!mConnected) return;
// Section 3.3.2 "Disconnect", IrOBEX 1.2
// [opcode:1][length:2][Headers:var]
uint8_t req[255];
int index = 3;
if (aFinal) {
SetObexPacketInfo(req, ObexResponseCode::Success, index);
} else {
SetObexPacketInfo(req, ObexResponseCode::Continue, index);
}
UnixSocketRawData* s = new UnixSocketRawData(index);
memcpy(s->mData, req, s->mSize);
SendSocketData(s);
}
void
BluetoothOppManager::FileTransferComplete(bool aSuccess,
bool aReceived,

View File

@ -62,6 +62,9 @@ private:
void FileTransferComplete(bool aSuccess, bool aReceived,
const nsString& aFileName, uint32_t aFileLength);
void UpdateProgress(uint32_t aProcessed, uint32_t aFileLength);
void ReplyToConnect();
void ReplyToDisconnect();
void ReplyToPut(bool aFinal);
bool mConnected;
int mConnectionId;
@ -70,6 +73,7 @@ private:
uint8_t mRemoteConnectionFlags;
int mRemoteMaxPacketLength;
bool mAbortFlag;
int mPacketLeftLength;
nsCOMPtr<nsIDOMBlob> mBlob;
nsCOMPtr<nsIThread> mReadFileThread;