// // 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 #include #include #include #include #include #include #include #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) { _BluetoothOppSystemAdapter* inst = null; inst = new (std::nothrow) _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 char* pDstPath) { unique_ptr pUuidStr; bool isUsed = false; 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); ret = bt_opp_server_initialize_by_connection_request(pDstPath, &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 if (ret == BT_ERROR_INVALID_PARAMETER) { r = E_INACCESSIBLE_PATH; } 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 char* pDstPath) { result r = E_FAILURE; int ret = BT_ERROR_NONE; ret = bt_opp_server_set_destination(pDstPath); 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; } else if (ret == BT_ERROR_INVALID_PARAMETER) { r = E_INACCESSIBLE_PATH; } 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 pServerDevAddr; unique_ptr 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