From 3251642fe7cb716a089a0c78713c20065f95bd38 Mon Sep 17 00:00:00 2001 From: Joohyun Kim Date: Wed, 17 Apr 2013 22:12:56 +0900 Subject: [PATCH] Fix SerialPort Change-Id: I2cdaf910fead90cba9238881d832f4ffbdaec7dd Signed-off-by: Joohyun Kim --- src/io/CMakeLists.txt | 1 + src/io/FIoSerialPort.cpp | 40 +++++++++++- src/io/FIo_SerialPortImpl.cpp | 149 ++++++++++++++++++++++++++++-------------- src/io/FIo_SerialPortImpl.h | 19 ++++-- 4 files changed, 152 insertions(+), 57 deletions(-) diff --git a/src/io/CMakeLists.txt b/src/io/CMakeLists.txt index d8ca71a..3485c5d 100644 --- a/src/io/CMakeLists.txt +++ b/src/io/CMakeLists.txt @@ -7,6 +7,7 @@ INCLUDE_DIRECTORIES ( ${CMAKE_SOURCE_DIR}/src/app/inc ${CMAKE_SOURCE_DIR}/src/security/inc ${CMAKE_SOURCE_DIR}/src/system/inc + ${CMAKE_SOURCE_DIR}/src/system inc ) diff --git a/src/io/FIoSerialPort.cpp b/src/io/FIoSerialPort.cpp index e818997..ed1389a 100644 --- a/src/io/FIoSerialPort.cpp +++ b/src/io/FIoSerialPort.cpp @@ -42,23 +42,57 @@ SerialPort::SerialPort(void) SerialPort::~SerialPort(void) { + result r = E_SUCCESS; + if(__pSerialPortImpl != null) + { + if(__pSerialPortImpl->IsOpended() == true) + { + r = __pSerialPortImpl->SerialClose(); + } + else + { + SysLogException(NID_SYS, E_SYSTEM, "SerialPort is not open."); + } + } + else + { + SysLogException(NID_SYS, E_SYSTEM, "SerialPort instance is not ready."); + } } result SerialPort::Construct(ISerialPortEventListener& listener) { - SysAssertf(__pSerialPortImpl == null, "Already constructed. Calling Construct() twice or more on a same instance is not allowed for this class\n"); + result r = E_SUCCESS; + SysLog(NID_IO, "SerialPort Construct"); - __pSerialPortImpl = new (std::nothrow) _SerialPortImpl(listener); + __pSerialPortImpl = _SerialPortImpl::GetInstance(); SysTryReturnResult(NID_IO, __pSerialPortImpl != null, E_OUT_OF_MEMORY, "The memory is insufficient."); + SysTryReturnResult(NID_IO, __pSerialPortImpl->IsOpended() == false, E_SYSTEM, "SerialPort is already opened."); - return E_SUCCESS; + SysLog(NID_IO, "Try to open serialport"); + r = __pSerialPortImpl->SerialOpen(); + SysTryReturnResult(NID_IO, r == E_SUCCESS, E_SYSTEM, "It is failed to open serial port."); + + SysLog(NID_IO, "Try to register event"); + r = __pSerialPortImpl->SetSerialPortEventListener(listener); + if(r != E_SUCCESS) + { + SysLogException(NID_IO, E_SYSTEM, "It is failed to register event listener."); + r = __pSerialPortImpl->SerialClose(); + SysTryReturnResult(NID_IO, r == E_SUCCESS, E_SYSTEM, "It is failed to close serial port."); + + r = E_SYSTEM; + } + + return r; } result SerialPort::Write(const ByteBuffer& byteBuffer) { SysAssertf(__pSerialPortImpl != null, "Not yet constructed. Construct() should be called before use.\n"); + SysTryReturnResult(NID_IO, __pSerialPortImpl->IsOpended() == true, E_SYSTEM, "SerialPort is not open."); return __pSerialPortImpl->Write(byteBuffer); } diff --git a/src/io/FIo_SerialPortImpl.cpp b/src/io/FIo_SerialPortImpl.cpp index 69a5c02..a901edd 100644 --- a/src/io/FIo_SerialPortImpl.cpp +++ b/src/io/FIo_SerialPortImpl.cpp @@ -29,12 +29,14 @@ #include #include #include "FIo_SerialPortImpl.h" +#include "FSys_CommunicationDispatcherClient.h" using namespace std; using namespace Tizen::App; using namespace Tizen::Base; using namespace Tizen::Base::Runtime; using namespace Tizen::Base::Collection; +using namespace Tizen::System; namespace Tizen { namespace Io { @@ -80,75 +82,133 @@ protected: } else { - pListener->OnSerialPortDataReceivedN(*(pArg->__pBuffer)); + SysLog(NID_IO, "Forward byte data to application."); + ByteBuffer* pBuffer = pArg->__pBuffer; + pListener->OnSerialPortDataReceivedN(*pBuffer); } } } + + SysLog(NID_IO, "data is forwarded to application."); } }; -_SerialPortImpl::_SerialPortImpl(ISerialPortEventListener& listener) +_SerialPortImpl* _SerialPortImpl::__pSerialPortImpl = null; + +_SerialPortImpl* +_SerialPortImpl::GetInstance(void) +{ + SysLog(NID_IO, "Requires SerialPort instance"); + if(__pSerialPortImpl == null) + { + __pSerialPortImpl = new (std::nothrow) _SerialPortImpl(); + } + return __pSerialPortImpl; +} + +_SerialPortImpl::_SerialPortImpl() : __pIpcClient(null) , __pEvent(null) + , __isOpended(false) { + SysLog(NID_IO, "Initialize SerialPort"); result r = E_SUCCESS; - ArrayList request; - ArrayList response; + _CommunicationDispatcherClient* pCommunicationDispatcherClient = _CommunicationDispatcherClient::GetInstance(); + SysTryCatch(NID_IO, pCommunicationDispatcherClient != null, r = E_SYSTEM, r, "It is failed to get CommunicationDispatcherClient."); - __pIpcClient = new (std::nothrow) _IpcClient(); - SysTryReturnVoidResult(NID_IO, __pIpcClient != null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient."); - r = __pIpcClient->Construct(COMMUNICATION_DISPATCHER_IPC_ID, this); - SysTryReturnVoidResult(NID_IO, r == E_SUCCESS, r, "[%s] Propagated.", GetErrorMessage(r)); + r = pCommunicationDispatcherClient->RegisterCommunicationListener(ACCESSORY_MANAGER_SERVICE_ID, *this); + SysTryCatch(NID_IO, r == E_SUCCESS, r = E_SYSTEM, r, "It is failed to register on CommunicationDispatcherClient."); + + __pIpcClient = pCommunicationDispatcherClient->GetIpcClient(); + SysTryCatch(NID_IO, __pIpcClient != null, r = E_SYSTEM, r, "It is failed to get IpcClient from CommunicationDispatcherClient."); __pEvent = new (std::nothrow) _SerialPortEvent(); - SysTryReturnVoidResult(NID_IO, __pEvent != null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient."); + SysTryCatch(NID_IO, __pEvent != null, r = E_OUT_OF_MEMORY, r, "[E_OUT_OF_MEMORY] The memory is insufficient."); + +CATCH: + SetLastResult(r); +} - __pEvent->AddListener(listener); +_SerialPortImpl::~_SerialPortImpl(void) +{ + delete __pEvent; + + __pEvent = null; + __pIpcClient = null; +} + +result +_SerialPortImpl::SerialOpen(void) +{ + result r = E_SUCCESS; + ArrayList request; + ArrayList response; + String serviceId(ACCESSORY_MANAGER_SERVICE_ID); + String commandId(SERIAL_COMMAND_OPEN); + SysLog(NID_IO, "Open SerialPort"); + SysTryReturnResult(NID_IO, __pIpcClient != null, E_SYSTEM, "IPC is not ready."); r = request.Construct(); - SysTryReturnVoidResult(NID_IO, r == E_SUCCESS, r, "[%s] Propagated.", GetErrorMessage(r)); - r = request.Add(String(ACCESSORY_MANAGER_SERVICE_ID)); - SysTryReturnVoidResult(NID_IO, r == E_SUCCESS, r, "[%s] Propagated.", GetErrorMessage(r)); - r = request.Add(String(SERIAL_COMMAND_OPEN)); - SysTryReturnVoidResult(NID_IO, r == E_SUCCESS, r, "[%s] Propagated.", GetErrorMessage(r)); r = response.Construct(); - SysTryReturnVoidResult(NID_IO, r == E_SUCCESS, r, "[%s] Propagated.", GetErrorMessage(r)); + + r = request.Add(serviceId); + r = request.Add(commandId); unique_ptr pMsg(new (std::nothrow) IoService_Request(request, &response)); - SysTryReturnVoidResult(NID_IO, pMsg != NULL, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient."); + SysTryReturnResult(NID_IO, pMsg != NULL, r = E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient."); - r = __pIpcClient->SendRequest(pMsg.get()); - SysTryReturnVoidResult(NID_IO, r == E_SUCCESS, r, "[%s] Propagated.", GetErrorMessage(r)); + SysLog(NID_IO, "Try to send IPC message"); + r = __pIpcClient->SendRequest(*pMsg); + SysTryReturnResult(NID_IO, r == E_SUCCESS, E_SYSTEM, "[%s] Propagated.", GetErrorMessage(r)); + + SysLog(NID_IO, "Sent IPC message"); - SetLastResult(E_SUCCESS); + __isOpended = true; + return r; } -_SerialPortImpl::~_SerialPortImpl(void) +result +_SerialPortImpl::SerialClose(void) { result r = E_SUCCESS; ArrayList request; ArrayList response; + String serviceId(ACCESSORY_MANAGER_SERVICE_ID); + String commandId(SERIAL_COMMAND_CLOSE); - SysTryReturnVoidResult(NID_IO, __pIpcClient != null, E_SYSTEM, "[E_SYSTEM] IPC client is not ready."); + SysLog(NID_IO, "Close SerialPort"); + SysTryReturnResult(NID_IO, __pIpcClient != null, E_SYSTEM, "IPC client is not ready."); r = request.Construct(); - SysTryReturnVoidResult(NID_IO, r == E_SUCCESS, r, "[%s] Propagated.", GetErrorMessage(r)); - r = request.Add(String(ACCESSORY_MANAGER_SERVICE_ID)); - SysTryReturnVoidResult(NID_IO, r == E_SUCCESS, r, "[%s] Propagated.", GetErrorMessage(r)); - r = request.Add(String(SERIAL_COMMAND_CLOSE)); - SysTryReturnVoidResult(NID_IO, r == E_SUCCESS, r, "[%s] Propagated.", GetErrorMessage(r)); + r = request.Add(serviceId); + r = request.Add(commandId); r = response.Construct(); - SysTryReturnVoidResult(NID_IO, r == E_SUCCESS, r, "[%s] Propagated.", GetErrorMessage(r)); unique_ptr pMsg(new (std::nothrow) IoService_Request(request, &response)); - SysTryReturnVoidResult(NID_IO, pMsg != NULL, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient."); + SysTryReturnResult(NID_IO, pMsg != NULL, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient."); - r = __pIpcClient->SendRequest(pMsg.get()); - SysTryReturnVoidResult(NID_IO, r == E_SUCCESS, r, "[%s] Propagated.", GetErrorMessage(r)); + r = __pIpcClient->SendRequest(*pMsg); + SysTryReturnResult(NID_IO, r == E_SUCCESS, r, "[%s] Propagated.", GetErrorMessage(r)); - delete __pEvent; + __isOpended = false; + + return r; +} + +bool +_SerialPortImpl::IsOpended(void) +{ + return __isOpended; +} + +result +_SerialPortImpl::SetSerialPortEventListener(ISerialPortEventListener& listener) +{ + result r = E_SUCCESS; + SysTryReturnResult(NID_IO, __pEvent != null, E_SYSTEM, "Event is not ready."); + r = __pEvent->AddListener(listener); - SetLastResult(E_SUCCESS); + return r; } result @@ -158,6 +218,8 @@ _SerialPortImpl::Write(const Tizen::Base::ByteBuffer &byteBuffer) ByteBuffer* pByteBuffer = null; ArrayList request; ArrayList response; + String serviceId(ACCESSORY_MANAGER_SERVICE_ID); + String commandId(SERIAL_COMMAND_WRITE); SysTryReturnResult(NID_IO, byteBuffer.GetCapacity() < SERIAL_BUFFER_SIZE, E_MAX_EXCEEDED, "[E_MAX_EXCEEDED] The buffer size exceeded a limit of the current device."); @@ -166,15 +228,10 @@ _SerialPortImpl::Write(const Tizen::Base::ByteBuffer &byteBuffer) SysTryReturnResult(NID_IO, __pIpcClient != null, E_SYSTEM, "[E_SYSTEM] IPC client is not ready"); r = request.Construct(); - SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] Propagated.", GetErrorMessage(r)); - r = request.Add(String(ACCESSORY_MANAGER_SERVICE_ID)); - SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] Propagated.", GetErrorMessage(r)); - r = request.Add(String(SERIAL_COMMAND_WRITE)); - SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] Propagated.", GetErrorMessage(r)); + r = request.Add(serviceId); + r = request.Add(commandId); r = request.Add(*pByteBuffer); - SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] Propagated.", GetErrorMessage(r)); r = response.Construct(); - SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] Propagated.", GetErrorMessage(r)); unique_ptr pMsg(new (std::nothrow) IoService_Request(request, &response)); SysTryReturnResult(NID_IO, pMsg != null, E_OUT_OF_MEMORY, "The memory is insufficient."); @@ -192,19 +249,11 @@ _SerialPortImpl::GetWriteBufferSize(void) const } void -_SerialPortImpl::OnIpcResponseReceived(_IpcClient& client, const IPC::Message& message) -{ - IPC_BEGIN_MESSAGE_MAP(_SerialPortImpl, message) - IPC_MESSAGE_HANDLER_EX(IoService_Data, &client, OnDataReceived) - IPC_END_MESSAGE_MAP_EX() -} - -void _SerialPortImpl::OnDataReceived(const ArrayList& data) { ByteBuffer* pBuffer = null; - unique_ptr pCommand((String*)data.GetAt(SERIAL_DATA_HEAD)); + String* pCommand = (String*)(data.GetAt(SERIAL_DATA_HEAD)); SysTryReturnVoidResult(NID_APP, pCommand != null, E_SYSTEM, "[E_SYSTEM] There is no command"); if (pCommand->Equals(SERIAL_COMMAND_DATA, true)) @@ -212,6 +261,8 @@ _SerialPortImpl::OnDataReceived(const ArrayList& data) pBuffer = (ByteBuffer*)data.GetAt(SERIAL_DATA_BODY); if (pBuffer != null) { + ArrayList* pData = const_cast(&data); + pData->Remove(*pBuffer); _SerialPortEventArg* pEventArg= new (std::nothrow) _SerialPortEventArg(pBuffer); if(pEventArg != null) { diff --git a/src/io/FIo_SerialPortImpl.h b/src/io/FIo_SerialPortImpl.h index d3e690e..d973e23 100644 --- a/src/io/FIo_SerialPortImpl.h +++ b/src/io/FIo_SerialPortImpl.h @@ -29,6 +29,7 @@ #include #include #include +#include namespace Tizen { namespace Base { namespace Collection { class ArrayList; @@ -38,25 +39,33 @@ namespace Tizen { namespace Io { class _SerialPortImpl - : public _IIpcClientEventListener + : public Tizen::System::_ICommunicationDispatcherListener { -public: - _SerialPortImpl(ISerialPortEventListener& listener); - +private: + _SerialPortImpl(); virtual ~_SerialPortImpl(void); +public: + result SerialOpen(void); + result SerialClose(void); + bool IsOpended(void); + result SetSerialPortEventListener(ISerialPortEventListener& listener); result Write(const Tizen::Base::ByteBuffer &byteBuffer); int GetWriteBufferSize(void) const; - void OnIpcResponseReceived(_IpcClient& client, const IPC::Message& message); void OnDataReceived(const Tizen::Base::Collection::ArrayList& data); + static _SerialPortImpl* GetInstance(void); + private: _IpcClient* __pIpcClient; Tizen::Base::Runtime::Event* __pEvent; + bool __isOpended; _SerialPortImpl(_SerialPortImpl& serialPortImpl); _SerialPortImpl& operator =(const _SerialPortImpl& serialPortImpl); + + static _SerialPortImpl* __pSerialPortImpl; }; }} //Tizen::Io -- 2.7.4