Merge "Update deprecated libprivilege-control API functions." into tizen
[platform/framework/native/appfw.git] / src / io / FIo_SerialPortImpl.cpp
1 //
2 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
3 //
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
7 //
8 //     http://floralicense.org/license/
9 //
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.
15 //
16
17 /**
18  * @file        FIo_SerialPortImpl.cpp
19  * @brief       This is the implementation file for _SerialPortImpl class.
20  */
21 #include <serial.h>
22 #include <unique_ptr.h>
23
24 #include <FBaseErrors.h>
25 #include <FBaseSysLog.h>
26 #include <FBaseRtIEventArg.h>
27
28 #include <FIo_AppServiceIpcMessages.h>
29 #include <FIo_IpcClient.h>
30 #include "FIo_SerialPortImpl.h"
31 #include "FSys_CommunicationDispatcherClient.h"
32
33 using namespace std;
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;
39
40 namespace Tizen { namespace Io
41 {
42
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";
49
50 const int SERIAL_BUFFER_SIZE = 512 * 1024; //512KB
51 const int SERIAL_DATA_HEAD = 1;
52 const int SERIAL_DATA_BODY = 2;
53
54 class _SerialPortEventArg
55         : public IEventArg
56 {
57 public:
58         _SerialPortEventArg(ByteBuffer* pBuffer)
59                 : __pBuffer(pBuffer)
60         {
61         }
62         ByteBuffer* __pBuffer;
63 };
64
65 class _SerialPortEvent
66         : public Event
67 {
68 protected:
69         virtual void FireImpl(IEventListener& listener, const IEventArg& arg)
70         {
71                 ISerialPortEventListener* pListener = dynamic_cast<ISerialPortEventListener*> (&listener);
72                 if (pListener != null)
73                 {
74                         const _SerialPortEventArg* pArg = dynamic_cast<const _SerialPortEventArg*>(&arg);
75                         if (pArg != null)
76                         {
77                                 if (pArg->__pBuffer == null)
78                                 {
79                                         pListener->OnSerialPortErrorOccured(E_SYSTEM);
80                                 }
81                                 else
82                                 {
83                                         SysLog(NID_IO, "Forward byte data to application.");
84                                         ByteBuffer* pBuffer = pArg->__pBuffer;
85                                         pListener->OnSerialPortDataReceivedN(*pBuffer);
86                                 }
87                         }
88                 }
89
90                 SysLog(NID_IO, "data is forwarded to application.");
91         }
92 };
93
94 _SerialPortImpl* _SerialPortImpl::__pSerialPortImpl = null;
95
96 _SerialPortImpl*
97 _SerialPortImpl::GetInstance(void)
98 {
99         SysLog(NID_IO, "Requires SerialPort instance");
100         if(__pSerialPortImpl == null)
101         {
102                 __pSerialPortImpl = new (std::nothrow) _SerialPortImpl();
103         }
104         return __pSerialPortImpl;
105 }
106
107 _SerialPortImpl::_SerialPortImpl()
108         : __pIpcClient(null)
109         , __pEvent(null)
110         , __isOpended(false)
111 {
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.");
116
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.");
119
120         __pIpcClient = pCommunicationDispatcherClient->GetIpcClient();
121         SysTryCatch(NID_IO, __pIpcClient != null, r = E_SYSTEM, r, "It is failed to get IpcClient from CommunicationDispatcherClient.");
122
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.");
125
126 CATCH:
127         SetLastResult(r);
128 }
129
130 _SerialPortImpl::~_SerialPortImpl(void)
131 {
132         delete __pEvent;
133
134         __pEvent = null;
135         __pIpcClient = null;
136 }
137
138 result
139 _SerialPortImpl::SerialOpen(void)
140 {
141         result r = E_SUCCESS;
142         ArrayList request;
143         ArrayList response;
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.");
148
149         r = request.Construct();
150         r = response.Construct();
151
152         r = request.Add(serviceId);
153         r = request.Add(commandId);
154
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.");
157
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));
161
162         SysLog(NID_IO, "Sent IPC message");
163
164         __isOpended = true;
165         return r;
166 }
167
168 result
169 _SerialPortImpl::SerialClose(void)
170 {
171         result r = E_SUCCESS;
172         ArrayList request;
173         ArrayList response;
174         String serviceId(ACCESSORY_MANAGER_SERVICE_ID);
175         String commandId(SERIAL_COMMAND_CLOSE);
176
177         SysLog(NID_IO, "Close SerialPort");
178         SysTryReturnResult(NID_IO, __pIpcClient != null, E_SYSTEM, "IPC client is not ready.");
179
180         r = request.Construct();
181         r = request.Add(serviceId);
182         r = request.Add(commandId);
183         r = response.Construct();
184
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.");
187
188         r = __pIpcClient->SendRequest(*pMsg);
189         SysTryReturnResult(NID_IO, r == E_SUCCESS, r, "[%s] Propagated.", GetErrorMessage(r));
190
191         __isOpended = false;
192
193         return r;
194 }
195
196 bool
197 _SerialPortImpl::IsOpended(void)
198 {
199         return __isOpended;
200 }
201
202 result
203 _SerialPortImpl::SetSerialPortEventListener(ISerialPortEventListener& listener)
204 {
205         result r = E_SUCCESS;
206         SysTryReturnResult(NID_IO, __pEvent != null, E_SYSTEM, "Event is not ready.");
207         r = __pEvent->AddListener(listener);
208
209         return r;
210 }
211
212 result
213 _SerialPortImpl::Write(const Tizen::Base::ByteBuffer &byteBuffer)
214 {
215         result r = E_SUCCESS;
216         ByteBuffer* pByteBuffer = null;
217         ArrayList request;
218         ArrayList response;
219         String serviceId(ACCESSORY_MANAGER_SERVICE_ID);
220         String commandId(SERIAL_COMMAND_WRITE);
221
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.");
223
224         pByteBuffer = const_cast <ByteBuffer *> (&byteBuffer);
225
226         SysTryReturnResult(NID_IO, __pIpcClient != null, E_SYSTEM, "[E_SYSTEM] IPC client is not ready");
227
228         r = request.Construct();
229         r = request.Add(serviceId);
230         r = request.Add(commandId);
231         r = request.Add(*pByteBuffer);
232         r = response.Construct();
233
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.");
236
237         r = __pIpcClient->SendRequest(pMsg.get());
238         SysTryReturn(NID_IO, r == E_SUCCESS, r, r, "[%s] Propagated.", GetErrorMessage(r));
239
240         String* pResult = dynamic_cast< String* >(response.GetAt(0));
241         if (pResult != null && pResult->Equals(String(L"E_SUCCESS")) == false)
242         {
243                 SysLog(NID_IO, "server result: %ls", pResult->GetPointer());
244                 return E_SYSTEM;
245         }
246
247         return E_SUCCESS;
248 }
249
250 int
251 _SerialPortImpl::GetWriteBufferSize(void) const
252 {
253         return SERIAL_BUFFER_SIZE;
254 }
255
256 void
257 _SerialPortImpl::OnDataReceived(const ArrayList& data)
258 {
259         ByteBuffer* pBuffer = null;
260
261         String* pCommand = (String*)(data.GetAt(SERIAL_DATA_HEAD));
262         SysTryReturnVoidResult(NID_APP, pCommand != null, E_SYSTEM, "[E_SYSTEM] There is no command");
263
264         if (pCommand->Equals(SERIAL_COMMAND_DATA, true))
265         {
266                 pBuffer = (ByteBuffer*)data.GetAt(SERIAL_DATA_BODY);
267                 if (pBuffer != null)
268                 {
269                         pBuffer->Flip();
270                         ArrayList* pData = const_cast<ArrayList*>(&data);
271                         pData->Remove(*pBuffer);
272                         _SerialPortEventArg* pEventArg= new (std::nothrow) _SerialPortEventArg(pBuffer);
273                         if(pEventArg != null)
274                         {
275                                 SysLog(NID_IO, "_SerialPortImpl::OnDataReceived Event Fire");
276                                 __pEvent->Fire(*pEventArg);
277                         }
278                 }
279         }
280         else if (pCommand->Equals(SERIAL_COMMAND_ERROR, true))
281         {
282                 _SerialPortEventArg* pEventArg= new (std::nothrow) _SerialPortEventArg(null);
283                  if(pEventArg != null)
284                  {
285                         SysLog(NID_IO, "_SerialPortImpl::OnDataReceived Event Fire");
286                         __pEvent->Fire(*pEventArg);
287                  }
288         }
289 }
290 }} // Tizen::Io
291