mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 05:41:12 +00:00
Bug 1162902 - Implement PBAP SetPhoneBook function, r=shuang
This commit is contained in:
parent
ca6308f1f7
commit
478901b821
@ -76,6 +76,7 @@ BluetoothPbapManager::HandleShutdown()
|
||||
BluetoothPbapManager::BluetoothPbapManager() : mConnected(false)
|
||||
{
|
||||
mDeviceAddress.AssignLiteral(BLUETOOTH_ADDRESS_NONE);
|
||||
mCurrentPath.AssignLiteral("");
|
||||
}
|
||||
|
||||
BluetoothPbapManager::~BluetoothPbapManager()
|
||||
@ -220,11 +221,27 @@ BluetoothPbapManager::ReceiveSocketData(BluetoothSocket* aSocket,
|
||||
ReplyToDisconnectOrAbort();
|
||||
AfterPbapDisconnected();
|
||||
break;
|
||||
case ObexRequestCode::SetPath: {
|
||||
// Section 3.3.6 "SetPath", IrOBEX 1.2
|
||||
// [opcode:1][length:2][flags:1][contants:1][Headers:var]
|
||||
if (!ParseHeaders(&data[5], receivedLength - 5, &pktHeaders)) {
|
||||
ReplyError(ObexResponseCode::BadRequest);
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t response = SetPhoneBookPath(data[3], pktHeaders);
|
||||
if (response != ObexResponseCode::Success) {
|
||||
ReplyError(response);
|
||||
return;
|
||||
}
|
||||
|
||||
ReplyToSetPath();
|
||||
}
|
||||
break;
|
||||
case ObexRequestCode::Put:
|
||||
case ObexRequestCode::PutFinal:
|
||||
case ObexRequestCode::Get:
|
||||
case ObexRequestCode::GetFinal:
|
||||
case ObexRequestCode::SetPath:
|
||||
ReplyError(ObexResponseCode::BadRequest);
|
||||
BT_LOGR("Unsupported ObexRequestCode %x", opCode);
|
||||
break;
|
||||
@ -263,9 +280,93 @@ BluetoothPbapManager::CompareHeaderTarget(const ObexHeaderSet& aHeader)
|
||||
return true;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
BluetoothPbapManager::SetPhoneBookPath(uint8_t flags,
|
||||
const ObexHeaderSet& aHeader)
|
||||
{
|
||||
// Section 5.2 "SetPhoneBook Function", PBAP 1.2
|
||||
// flags bit 1 must be 1 and bit 2~7 be 0
|
||||
if ((flags >> 1) != 1) {
|
||||
BT_LOGR("Illegal flags [0x%x]: bits 1~7 must be 0x01", flags);
|
||||
return ObexResponseCode::BadRequest;
|
||||
}
|
||||
|
||||
nsString newPath = mCurrentPath;
|
||||
|
||||
/**
|
||||
* Three cases:
|
||||
* 1) Go up 1 level - flags bit 0 is 1
|
||||
* 2) Go back to root - flags bit 0 is 0 AND name header is empty
|
||||
* 3) Go down 1 level - flags bit 0 is 0 AND name header is not empty,
|
||||
* where name header is the name of child folder
|
||||
*/
|
||||
if (flags & 1) {
|
||||
// Go up 1 level
|
||||
if (!newPath.IsEmpty()) {
|
||||
newPath = StringHead(newPath, newPath.RFindChar('/'));
|
||||
}
|
||||
} else {
|
||||
MOZ_ASSERT(aHeader.Has(ObexHeaderId::Name));
|
||||
|
||||
nsString childFolderName;
|
||||
aHeader.GetName(childFolderName);
|
||||
if (childFolderName.IsEmpty()) {
|
||||
// Go back to root
|
||||
newPath.AssignLiteral("");
|
||||
} else {
|
||||
// Go down 1 level
|
||||
newPath.AppendLiteral("/");
|
||||
newPath.Append(childFolderName);
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure the new path is legal
|
||||
if (!IsLegalPath(newPath)) {
|
||||
BT_LOGR("Illegal phone book path [%s]",
|
||||
NS_ConvertUTF16toUTF8(newPath).get());
|
||||
return ObexResponseCode::NotFound;
|
||||
}
|
||||
|
||||
mCurrentPath = newPath;
|
||||
BT_LOGR("current path [%s]", NS_ConvertUTF16toUTF8(mCurrentPath).get());
|
||||
|
||||
return ObexResponseCode::Success;
|
||||
}
|
||||
|
||||
bool
|
||||
BluetoothPbapManager::IsLegalPath(const nsAString& aPath)
|
||||
{
|
||||
static const char* sLegalPaths[] = {
|
||||
"", // root
|
||||
"/telecom",
|
||||
"/telecom/pb",
|
||||
"/telecom/ich",
|
||||
"/telecom/och",
|
||||
"/telecom/mch",
|
||||
"/telecom/cch",
|
||||
"/SIM1",
|
||||
"/SIM1/telecom",
|
||||
"/SIM1/telecom/pb",
|
||||
"/SIM1/telecom/ich",
|
||||
"/SIM1/telecom/och",
|
||||
"/SIM1/telecom/mch",
|
||||
"/SIM1/telecom/cch"
|
||||
};
|
||||
|
||||
NS_ConvertUTF16toUTF8 path(aPath);
|
||||
for (uint8_t i = 0; i < MOZ_ARRAY_LENGTH(sLegalPaths); i++) {
|
||||
if (!strcmp(path.get(), sLegalPaths[i])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothPbapManager::AfterPbapConnected()
|
||||
{
|
||||
mCurrentPath.AssignLiteral("");
|
||||
mConnected = true;
|
||||
}
|
||||
|
||||
@ -330,6 +431,21 @@ BluetoothPbapManager::ReplyToDisconnectOrAbort()
|
||||
SendObexData(req, ObexResponseCode::Success, index);
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothPbapManager::ReplyToSetPath()
|
||||
{
|
||||
if (!mConnected) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Section 3.3.6 "SetPath", IrOBEX 1.2
|
||||
// [opcode:1][length:2][Headers:var]
|
||||
uint8_t req[255];
|
||||
int index = 3;
|
||||
|
||||
SendObexData(req, ObexResponseCode::Success, index);
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothPbapManager::ReplyError(uint8_t aError)
|
||||
{
|
||||
|
@ -43,13 +43,21 @@ private:
|
||||
|
||||
void ReplyToConnect();
|
||||
void ReplyToDisconnectOrAbort();
|
||||
void ReplyToSetPath();
|
||||
void ReplyError(uint8_t aError);
|
||||
void SendObexData(uint8_t* aData, uint8_t aOpcode, int aSize);
|
||||
|
||||
uint8_t SetPhoneBookPath(uint8_t flags, const ObexHeaderSet& aHeader);
|
||||
bool CompareHeaderTarget(const ObexHeaderSet& aHeader);
|
||||
bool IsLegalPath(const nsAString& aPath);
|
||||
void AfterPbapConnected();
|
||||
void AfterPbapDisconnected();
|
||||
|
||||
/**
|
||||
* Current phonebook path
|
||||
*/
|
||||
nsString mCurrentPath;
|
||||
|
||||
/**
|
||||
* OBEX session status. Set when OBEX session is established.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user