2 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 // Licensed under the Apache License, Version 2.0 (the License);
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
8 // http://floralicense.org/license/
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
18 * @file FIo_SerialPortImpl.cpp
19 * @brief This is the implementation file for _SerialPortImpl class.
22 #include <unique_ptr.h>
24 #include <FBaseErrors.h>
25 #include <FBaseSysLog.h>
26 #include <FBaseRtIEventArg.h>
28 #include <FIo_AppServiceIpcMessages.h>
29 #include <FIo_IpcClient.h>
30 #include "FIo_SerialPortImpl.h"
31 #include "FSys_CommunicationDispatcherClient.h"
34 using namespace Tizen::App;
35 using namespace Tizen::Base;
36 using namespace Tizen::Base::Runtime;
37 using namespace Tizen::Base::Collection;
38 using namespace Tizen::System;
40 namespace Tizen { namespace Io
43 const wchar_t ACCESSORY_MANAGER_SERVICE_ID[] = L"osp.accessorymanager.service";
44 const wchar_t SERIAL_COMMAND_OPEN[] = L"Open";
45 const wchar_t SERIAL_COMMAND_CLOSE[] = L"Close";
46 const wchar_t SERIAL_COMMAND_WRITE[] = L"Write";
47 const wchar_t SERIAL_COMMAND_DATA[] = L"Data";
48 const wchar_t SERIAL_COMMAND_ERROR[] = L"Error";
50 const int SERIAL_BUFFER_SIZE = 512 * 1024; //512KB
51 const int SERIAL_DATA_HEAD = 1;
52 const int SERIAL_DATA_BODY = 2;
54 class _SerialPortEventArg
58 _SerialPortEventArg(ByteBuffer* pBuffer)
62 ByteBuffer* __pBuffer;
65 class _SerialPortEvent
69 virtual void FireImpl(IEventListener& listener, const IEventArg& arg)
71 ISerialPortEventListener* pListener = dynamic_cast<ISerialPortEventListener*> (&listener);
72 if (pListener != null)
74 const _SerialPortEventArg* pArg = dynamic_cast<const _SerialPortEventArg*>(&arg);
77 if (pArg->__pBuffer == null)
79 pListener->OnSerialPortErrorOccured(E_SYSTEM);
83 SysLog(NID_IO, "Forward byte data to application.");
84 ByteBuffer* pBuffer = pArg->__pBuffer;
85 pListener->OnSerialPortDataReceivedN(*pBuffer);
90 SysLog(NID_IO, "data is forwarded to application.");
94 _SerialPortImpl* _SerialPortImpl::__pSerialPortImpl = null;
97 _SerialPortImpl::GetInstance(void)
99 SysLog(NID_IO, "Requires SerialPort instance");
100 if(__pSerialPortImpl == null)
102 __pSerialPortImpl = new (std::nothrow) _SerialPortImpl();
104 return __pSerialPortImpl;
107 _SerialPortImpl::_SerialPortImpl()
112 SysLog(NID_IO, "Initialize SerialPort");
113 result r = E_SUCCESS;
114 _CommunicationDispatcherClient* pCommunicationDispatcherClient = _CommunicationDispatcherClient::GetInstance();
115 SysTryCatch(NID_IO, pCommunicationDispatcherClient != null, r = E_SYSTEM, r, "It is failed to get CommunicationDispatcherClient.");
117 r = pCommunicationDispatcherClient->RegisterCommunicationListener(ACCESSORY_MANAGER_SERVICE_ID, *this);
118 SysTryCatch(NID_IO, r == E_SUCCESS, r = E_SYSTEM, r, "It is failed to register on CommunicationDispatcherClient.");
120 __pIpcClient = pCommunicationDispatcherClient->GetIpcClient();
121 SysTryCatch(NID_IO, __pIpcClient != null, r = E_SYSTEM, r, "It is failed to get IpcClient from CommunicationDispatcherClient.");
123 __pEvent = new (std::nothrow) _SerialPortEvent();
124 SysTryCatch(NID_IO, __pEvent != null, r = E_OUT_OF_MEMORY, r, "[E_OUT_OF_MEMORY] The memory is insufficient.");
130 _SerialPortImpl::~_SerialPortImpl(void)
139 _SerialPortImpl::SerialOpen(void)
141 result r = E_SUCCESS;
144 String serviceId(ACCESSORY_MANAGER_SERVICE_ID);
145 String commandId(SERIAL_COMMAND_OPEN);
146 SysLog(NID_IO, "Open SerialPort");
147 SysTryReturnResult(NID_IO, __pIpcClient != null, E_SYSTEM, "IPC is not ready.");
149 r = request.Construct();
150 r = response.Construct();
152 r = request.Add(serviceId);
153 r = request.Add(commandId);
155 unique_ptr<IoService_Request> pMsg(new (std::nothrow) IoService_Request(request, &response));
156 SysTryReturnResult(NID_IO, pMsg != NULL, r = E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
158 SysLog(NID_IO, "Try to send IPC message");
159 r = __pIpcClient->SendRequest(*pMsg);
160 SysTryReturnResult(NID_IO, r == E_SUCCESS, E_SYSTEM, "[%s] Propagated.", GetErrorMessage(r));
162 SysLog(NID_IO, "Sent IPC message");
169 _SerialPortImpl::SerialClose(void)
171 result r = E_SUCCESS;
174 String serviceId(ACCESSORY_MANAGER_SERVICE_ID);
175 String commandId(SERIAL_COMMAND_CLOSE);
177 SysLog(NID_IO, "Close SerialPort");
178 SysTryReturnResult(NID_IO, __pIpcClient != null, E_SYSTEM, "IPC client is not ready.");
180 r = request.Construct();
181 r = request.Add(serviceId);
182 r = request.Add(commandId);
183 r = response.Construct();
185 unique_ptr<IoService_Request> pMsg(new (std::nothrow) IoService_Request(request, &response));
186 SysTryReturnResult(NID_IO, pMsg != NULL, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
188 r = __pIpcClient->SendRequest(*pMsg);
189 SysTryReturnResult(NID_IO, r == E_SUCCESS, r, "[%s] Propagated.", GetErrorMessage(r));
197 _SerialPortImpl::IsOpended(void)
203 _SerialPortImpl::SetSerialPortEventListener(ISerialPortEventListener& listener)
205 result r = E_SUCCESS;
206 SysTryReturnResult(NID_IO, __pEvent != null, E_SYSTEM, "Event is not ready.");
207 r = __pEvent->AddListener(listener);
213 _SerialPortImpl::Write(const Tizen::Base::ByteBuffer &byteBuffer)
215 result r = E_SUCCESS;
216 ByteBuffer* pByteBuffer = null;
219 String serviceId(ACCESSORY_MANAGER_SERVICE_ID);
220 String commandId(SERIAL_COMMAND_WRITE);
222 SysTryReturnResult(NID_IO, byteBuffer.GetCapacity() < SERIAL_BUFFER_SIZE, E_MAX_EXCEEDED, "[E_MAX_EXCEEDED] The buffer size exceeded a limit of the current device.");
224 pByteBuffer = const_cast <ByteBuffer *> (&byteBuffer);
226 SysTryReturnResult(NID_IO, __pIpcClient != null, E_SYSTEM, "[E_SYSTEM] IPC client is not ready");
228 r = request.Construct();
229 r = request.Add(serviceId);
230 r = request.Add(commandId);
231 r = request.Add(*pByteBuffer);
232 r = response.Construct();
234 unique_ptr<IoService_Request> pMsg(new (std::nothrow) IoService_Request(request, &response));
235 SysTryReturnResult(NID_IO, pMsg != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
237 r = __pIpcClient->SendRequest(pMsg.get());
238 SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] Propagated.", GetErrorMessage(r));
244 _SerialPortImpl::GetWriteBufferSize(void) const
246 return SERIAL_BUFFER_SIZE;
250 _SerialPortImpl::OnDataReceived(const ArrayList& data)
252 ByteBuffer* pBuffer = null;
254 String* pCommand = (String*)(data.GetAt(SERIAL_DATA_HEAD));
255 SysTryReturnVoidResult(NID_APP, pCommand != null, E_SYSTEM, "[E_SYSTEM] There is no command");
257 if (pCommand->Equals(SERIAL_COMMAND_DATA, true))
259 pBuffer = (ByteBuffer*)data.GetAt(SERIAL_DATA_BODY);
263 ArrayList* pData = const_cast<ArrayList*>(&data);
264 pData->Remove(*pBuffer);
265 _SerialPortEventArg* pEventArg= new (std::nothrow) _SerialPortEventArg(pBuffer);
266 if(pEventArg != null)
268 SysLog(NID_IO, "_SerialPortImpl::OnDataReceived Event Fire");
269 __pEvent->Fire(*pEventArg);
273 else if (pCommand->Equals(SERIAL_COMMAND_ERROR, true))
275 _SerialPortEventArg* pEventArg= new (std::nothrow) _SerialPortEventArg(null);
276 if(pEventArg != null)
278 SysLog(NID_IO, "_SerialPortImpl::OnDataReceived Event Fire");
279 __pEvent->Fire(*pEventArg);