diff options
Diffstat (limited to 'src/FNetBt_BluetoothOppSystemAdapter.cpp')
-rwxr-xr-x | src/FNetBt_BluetoothOppSystemAdapter.cpp | 380 |
1 files changed, 380 insertions, 0 deletions
diff --git a/src/FNetBt_BluetoothOppSystemAdapter.cpp b/src/FNetBt_BluetoothOppSystemAdapter.cpp new file mode 100755 index 0000000..e3d126d --- /dev/null +++ b/src/FNetBt_BluetoothOppSystemAdapter.cpp @@ -0,0 +1,380 @@ +// +// Open Service Platform +// Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// @file FNetBt_BluetoothOppSystemAdapter.cpp +// @brief This is the implementation file for the _BluetoothOppSystemAdapter class. +// + +#include <unique_ptr.h> +#include <pthread.h> +#include <FBaseByteBuffer.h> +#include <FBaseUtilStringUtil.h> +#include <FNetBtBluetoothTypes.h> +#include <FNetBtBluetoothDevice.h> +#include <FBaseSysLog.h> +#include <FBase_StringConverter.h> +#include "FNetBt_BluetoothOppSystemAdapter.h" +#include "FNetBt_BluetoothGapSystemAdapter.h" +#include "FNetBt_BluetoothDeviceImpl.h" +#include "FNetBt_BluetoothOppClientImpl.h" +#include "FNetBt_BluetoothOppServerImpl.h" + +using namespace std; +using namespace Tizen::Base; +using namespace Tizen::Base::Collection; +using namespace Tizen::Base::Utility; + +namespace Tizen { namespace Net { namespace Bluetooth +{ + +_BluetoothOppSystemAdapter* _BluetoothOppSystemAdapter::__pInstance = null; + +_BluetoothOppSystemAdapter::_BluetoothOppSystemAdapter(void) + : __pOppServerImpl(null) + , __pOppClientImpl(null) + , __serverTransferId(0) + , __serverRecvFileName() + , __serverRecvFileSize(0) +{ +} + +_BluetoothOppSystemAdapter::~_BluetoothOppSystemAdapter(void) +{ +} + +void +_BluetoothOppSystemAdapter::InitSingleton(void) +{ + static _BluetoothOppSystemAdapter inst = _BluetoothOppSystemAdapter(); + + __pInstance = &inst; +} + +_BluetoothOppSystemAdapter* +_BluetoothOppSystemAdapter::GetInstance(void) +{ + static pthread_once_t onceBlock = PTHREAD_ONCE_INIT; + + if (__pInstance == null) + { + ClearLastResult(); + pthread_once(&onceBlock, InitSingleton); + result r = GetLastResult(); + if (IsFailed(r)) + { + onceBlock = PTHREAD_ONCE_INIT; + } + } + + return __pInstance; +} + +result +_BluetoothOppSystemAdapter::StartOppServer(const _BluetoothOppServerImpl& impl, const Tizen::Base::String& dstPath) +{ + unique_ptr<char[]> pUuidStr; + bool isUsed = false; + unique_ptr<char[]> pConvertedDestPath; + result r = E_SUCCESS; + int ret = BT_ERROR_NONE; + + // check OPP server's availability + pUuidStr.reset(_StringConverter::CopyToCharArrayN(UuId(BT_SVC_UUID_OPP).ToString())); + ret = bt_adapter_is_service_used(pUuidStr.get() , &isUsed); + SysTryReturnResult(NID_NET_BT, (ret == BT_ERROR_NONE) && !isUsed, E_SERVICE_UNAVAILABLE, "OPP Server is not available. [0x%08X]", ret); + + pConvertedDestPath.reset(_StringConverter::CopyToCharArrayN(dstPath)); + SysTryReturnResult(NID_NET_BT, pConvertedDestPath != null, E_INACCESSIBLE_PATH, "The file path is invalid."); + + ret = bt_opp_server_initialize_by_connection_request(pConvertedDestPath.get(), &OnOppServerConnectionRequested, null); + SysLog(NID_NET_BT, "Starting the OPP Server %s. [0x%-04X]", ret == BT_ERROR_NONE ? "is successful" : "fails", ret); + + if (ret == BT_ERROR_NONE) + { + __pOppServerImpl = const_cast <_BluetoothOppServerImpl*>(&impl); + } + else + { + r = E_FAILURE; + } + + return r; +} + +result +_BluetoothOppSystemAdapter::StopOppServer(void) +{ + int ret = BT_ERROR_NONE; + + ret = bt_opp_server_deinitialize(); + SysLog(NID_NET_BT, "Stop the OPP Server %s. [0x%08X]", ret == BT_ERROR_NONE ? "is successful" : "fails", ret); + + if (ret == BT_ERROR_NONE) + { + __pOppServerImpl = null; + return E_SUCCESS; + } + + return E_FAILURE; +} + +result +_BluetoothOppSystemAdapter::SetOppReceivePath(const Tizen::Base::String& dstPath) +{ + char* pConvertedDestPath = NULL; + result r = E_FAILURE; + int ret = BT_ERROR_NONE; + + pConvertedDestPath = _StringConverter::CopyToCharArrayN(dstPath); + SysTryReturnResult(NID_NET_BT, pConvertedDestPath != null, E_INACCESSIBLE_PATH, "The file path is invalid."); + + ret = bt_opp_server_set_destination(pConvertedDestPath); + SysLog(NID_NET_BT, "Setting the receive path of the OPP Server %s. [0x%08X]", + ret == BT_ERROR_NONE ? "is successful" : "fails", ret); + + if (ret == BT_ERROR_NONE) + { + r = E_SUCCESS; + } + + delete[] pConvertedDestPath; + return r; +} + +result +_BluetoothOppSystemAdapter::AcceptOppPush(const Tizen::Base::String& fileName) +{ + result r = E_FAILURE; + int ret = BT_ERROR_NONE; + + char* pConvertedfileName = _StringConverter::CopyToCharArrayN(fileName); + SysTryReturnResult(NID_NET_BT, pConvertedfileName != null, E_FAILURE, "The file name is invalid."); + + ret = bt_opp_server_accept(&OnOppServerTransferInProgress, &OnOppServerTransferCompleted, pConvertedfileName, null, + &__serverTransferId); + SysLog(NID_NET_BT, "Accepting the OPP push request %s. [0x%08X]", ret == BT_ERROR_NONE ? "is successful" : "fails", ret); + + if (ret == BT_ERROR_NONE) + { + r = E_SUCCESS; + } + + delete[] pConvertedfileName; + return r; +} + +result +_BluetoothOppSystemAdapter::RejectOppPush(void) +{ + int ret = BT_ERROR_NONE; + + ret = bt_opp_server_reject(); + SysLog(NID_NET_BT, "Rejecting the OPP push request %s. [0x%08X]", ret == BT_ERROR_NONE ? "is successful" : "fails", ret); + + if (ret == BT_ERROR_NONE) + { + return E_SUCCESS; + } + + return E_FAILURE; +} + +result +_BluetoothOppSystemAdapter::StopOppTransfer(void) +{ + int ret = BT_ERROR_NONE; + + // if a file transfer is not started yet, the default transfer ID (0) is used for terminating the OPP server. + ret = bt_opp_server_cancel_transfer(__serverTransferId); + SysLog(NID_NET_BT, "Stop the OPP file transfer (ID:%d) %s. [0x%08X]", __serverTransferId, + ret == BT_ERROR_NONE ? "is successful" : "fails", ret); + + if (ret == BT_ERROR_NONE) + { + return E_SUCCESS; + } + + return E_OPERATION_FAILED; +} + +result +_BluetoothOppSystemAdapter::PushOppFile(const _BluetoothOppClientImpl& impl, const Tizen::Base::ByteBuffer& serverAddress, + const Tizen::Base::String& filePath) +{ + result r = E_FAILURE; + int ret = BT_ERROR_NONE; + unique_ptr<char[]> pServerDevAddr; + unique_ptr<char[]> pFileName; + + SysTryReturnResult(NID_NET_BT, __pOppClientImpl == null, E_SERVICE_UNAVAILABLE, "The already OPP client is running."); + SysTryReturnResult(NID_NET_BT, serverAddress.GetRemaining() == _BT_ADDRESS_LENGTH, E_FAILURE, + "The address of the remote device is incorrect."); + + pFileName.reset(_StringConverter::CopyToCharArrayN(filePath)); + SysTryReturnResult(NID_NET_BT, pFileName != null, E_INACCESSIBLE_PATH, "The file path is invalid."); + pServerDevAddr.reset(_StringConverter::CopyToCharArrayN(_BluetoothDeviceImpl::GetAddressString(serverAddress))); + SysTryReturnResult(NID_NET_BT, pServerDevAddr != null, E_FAILURE, "The server address is invalid."); + + if (bt_opp_client_initialize() == BT_ERROR_NONE) + { + (void) bt_opp_client_add_file(pFileName.get()); + ret = bt_opp_client_push_files(pServerDevAddr.get(), &OnOppClientConnectionResponded, &OnOppClientTransferInProgress, + &OnOppClientTransferCompleted, null); + SysLog(NID_NET_BT, "Sending a push request to device [%s] %s. [0x%08X]", pServerDevAddr.get(), + ret == BT_ERROR_NONE ? "is successful" : "fails", ret); + + if (ret == BT_ERROR_NONE) + { + __pOppClientImpl = const_cast<_BluetoothOppClientImpl*>(&impl); + r = E_SUCCESS; + } + else + { + bt_opp_client_deinitialize(); + } + } + + return r; +} + +result +_BluetoothOppSystemAdapter::CancelOppPush(void) +{ + int ret = BT_ERROR_NONE; + + ret = bt_opp_client_cancel_push(); + SysLog(NID_NET_BT, "Cancel the OPP file transfer %s. [0x%08X]", ret == BT_ERROR_NONE ? "is successful" : "fails", ret); + + if (ret == BT_ERROR_NONE) + { + return E_SUCCESS; + } + + return E_FAILURE; +} + +void +_BluetoothOppSystemAdapter::OnOppClientConnectionResponded(int status, const char* pRemoteAddress, void* pUserData) +{ + _BluetoothOppSystemAdapter* pOppAdapter = _BluetoothOppSystemAdapter::GetInstance(); + + if (pOppAdapter->__pOppClientImpl) + { + if (status == BT_ERROR_NONE) + { + pOppAdapter->__pOppClientImpl->OnOppPushResponded(E_SUCCESS); + } + else + { + pOppAdapter->__pOppClientImpl->OnOppPushResponded(E_SYSTEM); + pOppAdapter->__pOppClientImpl = null; + bt_opp_client_deinitialize(); + } + } +} + +void +_BluetoothOppSystemAdapter::OnOppClientTransferInProgress(const char* pFilePath, long long fileSize, int progress, void* pUserData) +{ + _BluetoothOppSystemAdapter* pOppAdapter = _BluetoothOppSystemAdapter::GetInstance(); + + pOppAdapter->__serverRecvFileSize = fileSize; + // converts the UTF8 multibyte string to Unicode String + (void) StringUtil::Utf8ToString(pFilePath, pOppAdapter->__serverRecvFileName); + + if (pOppAdapter->__pOppClientImpl) + { + pOppAdapter->__pOppClientImpl->OnOppTransferInProgress(progress); + } +} + +void +_BluetoothOppSystemAdapter::OnOppClientTransferCompleted(int status, const char* pRemoteAddress, void* pUserData) +{ + bool isCompleted = true; + _BluetoothOppSystemAdapter* pOppAdapter = _BluetoothOppSystemAdapter::GetInstance(); + + if (pOppAdapter->__pOppClientImpl) + { + if (status != BT_ERROR_NONE) + { + isCompleted = false; + } + + pOppAdapter->__pOppClientImpl->OnOppTransferDone(pOppAdapter->__serverRecvFileName, pOppAdapter->__serverRecvFileSize, + isCompleted); + pOppAdapter->__pOppClientImpl = null; + // TODO: Is it right that the following statement is located in the next of callback? + bt_opp_client_deinitialize(); + } +} + +void +_BluetoothOppSystemAdapter::OnOppServerConnectionRequested(const char* pRemoteAddress, void* pUserData) +{ + result r = E_SUCCESS; + BluetoothDevice requester; + ByteBuffer deviceAddress; + String deviceAddressStr(pRemoteAddress); + _BluetoothOppSystemAdapter* pOppAdapter = _BluetoothOppSystemAdapter::GetInstance(); + + if (pOppAdapter->__pOppServerImpl) + { + deviceAddress.Construct(_BT_ADDRESS_LENGTH); + (void) _BluetoothDeviceImpl::GetAddressByteBuffer(deviceAddressStr, L":", deviceAddress); + + r = _BluetoothGapSystemAdapter::GetPairedDevice(deviceAddress, requester); + SysTryReturnVoidResult(NID_NET_BT, r == E_SUCCESS, E_SYSTEM, "[E_SYSTEM] Getting information of the request has failed."); + + pOppAdapter->__pOppServerImpl->OnOppPushRequested(requester); + } +} + +void +_BluetoothOppSystemAdapter::OnOppServerTransferInProgress(const char* pFilePath, long long fileSize, int progress, void* pUserData) +{ + _BluetoothOppSystemAdapter* pOppAdapter = _BluetoothOppSystemAdapter::GetInstance(); + + if (pOppAdapter->__pOppServerImpl) + { + pOppAdapter->__pOppServerImpl->OnOppTransferInProgress(progress); + } +} + +void +_BluetoothOppSystemAdapter::OnOppServerTransferCompleted(int status, const char* pFilePath, long long fileSize, void* pUserData) +{ + bool isCompleted = true; + String convertedFilePath; + + _BluetoothOppSystemAdapter* pOppAdapter = _BluetoothOppSystemAdapter::GetInstance(); + + if (pOppAdapter->__pOppServerImpl) + { + pOppAdapter->__serverTransferId = 0; + + if (status != BT_ERROR_NONE) + { + isCompleted = false; + } + // TODO: not file name but file path + // converts the UTF8 multibyte string to Unicode String + (void) StringUtil::Utf8ToString(pFilePath, convertedFilePath); + pOppAdapter->__pOppServerImpl->OnOppTransferDone(convertedFilePath, fileSize, isCompleted); + } +} + +} } } // Tizen::Net::Bluetooth |