bug fix: TC-1152
[profile/ivi/ico-uxf-homescreen.git] / src / onscreen / CicoOSClient.cpp
1 /*
2  * Copyright (c) 2013, TOYOTA MOTOR CORPORATION.
3  *
4  * This program is licensed under the terms and conditions of the
5  * Apache License, version 2.0.  The full text of the Apache License is at
6  * http://www.apache.org/licenses/LICENSE-2.0
7  *
8  */
9
10 //==========================================================================
11 /**
12  *  @file   CicoOSClient.cpp
13  *
14  *  @brief  This file implementation of CicoOSClient class
15  */
16 //==========================================================================
17
18 #include <iostream>
19 #include <sstream>
20 #include <string>
21 #include <boost/property_tree/ptree.hpp>
22 #include <boost/property_tree/json_parser.hpp>
23 #include <boost/foreach.hpp>
24 #include <boost/optional.hpp>
25 #include <sys/types.h>
26 #include <unistd.h>
27
28 using namespace boost::property_tree;
29 using namespace std;
30
31 #include "CicoOSClient.h"
32
33 #include <ico_log.h>
34 #include "ico_syc_error.h"
35 #include "ico_syc_msg_cmd_def.h"
36
37 //==========================================================================
38 //  private static variable
39 //==========================================================================
40 CicoOSClient* CicoOSClient::ms_myInstance = NULL;
41
42 //--------------------------------------------------------------------------
43 /**
44  *  @brief  default constructor
45  */
46 //--------------------------------------------------------------------------
47 CicoOSClient::CicoOSClient()
48     :m_uwsContext(NULL), m_id(NULL), m_seqNum(seqMin)
49 {
50 }
51
52 //--------------------------------------------------------------------------
53 /**
54  *  @brief  destructor
55  */
56 //--------------------------------------------------------------------------
57 CicoOSClient::~CicoOSClient()
58 {
59     if (NULL != m_uwsContext) {
60         ico_uws_close(m_uwsContext);
61     }
62 }
63
64 //--------------------------------------------------------------------------
65 /**
66  *  @brief   get CicoOSClient instance
67  *
68  *  @return CicoOSClient instance
69  */
70 //--------------------------------------------------------------------------
71 CicoOSClient*
72 CicoOSClient::getInstance()
73 {
74     if (NULL == ms_myInstance) {
75         ms_myInstance = new CicoOSClient();
76     }
77
78     return ms_myInstance;
79 }
80
81 //--------------------------------------------------------------------------
82 /**
83  *  @brief   connect
84  *
85  *  @param [in] port        websocket port
86  *  @param [in] protocol    websocket protocol name
87  *
88  *  @return ICO_SYC_EOK on success, other on error
89  *  @retval ICO_SYC_EOK     success
90  *  @retval ICO_SYC_ENOSYS  error(connection fail)
91  */
92 //--------------------------------------------------------------------------
93 bool
94 CicoOSClient::connect()
95 {
96     ICO_TRA("CicoOSClient::connect Enter");
97
98     /* create context */
99     m_uwsContext = ico_uws_create_context(DEF_WS_CLI_HS_PORT,
100                                           DEF_WS_CLI_HS_PROTOCOL);
101     if (NULL == m_uwsContext) {
102         ICO_ERR("ico_uws_create_context() failed.");
103         ICO_TRA("CicoOSClient::connect Leave false");
104         return false;
105     }
106
107     /* set callback */
108     int ret = ico_uws_set_event_cb(m_uwsContext, uwsReceiveEventCB,
109                                    (void *)this);
110     if (ret != ICO_UWS_ERR_NONE) {
111         ICO_ERR("ico_uws_set_event_cb() failed(%d).", ret);
112         ICO_TRA("CicoOSClient::connect Leave false");
113         return false;
114     }
115
116     ecore_timer_add(timerCount, CicoOSClient::ecoreTimerCB, this);
117
118     ICO_TRA("CicoOSClient::connect Leave ture");
119
120     return true;
121 }
122
123 //--------------------------------------------------------------------------
124 /**
125  *  @brief  control sequence number
126  */
127 //--------------------------------------------------------------------------
128 void CicoOSClient::updateSeqNum()
129 {
130     m_seqNum++;
131     if (seqMax < m_seqNum) {
132         m_seqNum = seqMin;
133     }
134 }
135
136 //--------------------------------------------------------------------------
137 /**
138  *  @brief  get sequence number
139  */
140 //--------------------------------------------------------------------------
141 int CicoOSClient::getSeqNum() const
142 {
143     return m_seqNum;
144 }
145
146 //--------------------------------------------------------------------------
147 /**
148  *  @brief   send message to application client
149  *
150  *  @param [in] appid   application id of destination
151  *  @param [in] msg     message
152  *
153  *  @return ICO_SYC_EOK on success, other on error
154  */
155 //--------------------------------------------------------------------------
156 bool
157 CicoOSClient::sendLaunchMessage(const string& op_app)
158 {
159     ICO_TRA("CicoOSClient::sendMessage Enter(%s)", op_app.c_str());
160     if ((NULL == m_uwsContext) && (NULL == m_id)) {
161         ICO_TRA("CicoOSClient::sendMessage Leave(false)");
162         return false;
163     }
164     ico_uws_service(m_uwsContext);
165
166     ptree pt;
167     pt.put("command", MSG_CMD_WIN_CHANGE);
168     pt.put("source.pid",    (int)getpid());
169     pt.put("source.seq_no", getSeqNum());
170     updateSeqNum();
171     pt.put("arg.appid",   op_app);
172     pt.put("arg.zone",    "Center");
173     pt.put("arg.visible", 1);
174     stringstream ss;
175     write_json(ss, pt, false);
176     string m = ss.str();
177
178     size_t  l = m.length();
179     char b[l+1];
180     strcpy(b, m.c_str());
181     ICO_DBG("msg:%d, %s", l, b);
182     ico_uws_send(m_uwsContext, (void*)m_id, (unsigned char*)b, l);
183     ico_uws_service(m_uwsContext);
184 #if 0
185     usleep(200);
186 #endif
187
188     ICO_TRA("CicoOSClient::sendMessage Leave(true)");
189     return true;
190 }
191
192 //--------------------------------------------------------------------------
193 /*
194  *  @brief  websocket utility callback function
195  *
196  *  @param [in] context     context
197  *  @param [in] event       event kinds
198  *  @param [in] id          client id
199  *  @param [in] detail      event detail
200  *  @param [in] data        user data
201  */
202 //--------------------------------------------------------------------------
203 void
204 CicoOSClient::uwsReceiveEventCB(const struct ico_uws_context* context,
205                                 const ico_uws_evt_e           event,
206                                 const void*                   id,
207                                 const ico_uws_detail*         detail,
208                                 void*                         user_data)
209 {
210     if (NULL == user_data) {
211         ICO_ERR("user_data is NULL");
212         return;
213     }
214
215     CicoOSClient* cosc = static_cast<CicoOSClient*>(user_data);
216     cosc->receiveEventCB(context, event, id, detail, user_data);
217 }
218
219 //--------------------------------------------------------------------------
220 /**
221  *  @brief   websocket callback function
222  *
223  *  @param [in] context     websocket context
224  *  @param [in] event       changed event
225  *  @param [in] id          source applicatin id
226  *  @param [in] detail      event detail information
227  *  @param [in] user_data   user data
228  */
229 //--------------------------------------------------------------------------
230 void
231 CicoOSClient::receiveEventCB(const struct ico_uws_context* context,
232                              const ico_uws_evt_e           event,
233                              const void*                   id,
234                              const ico_uws_detail*         detail,
235                              void*                         user_data)
236 {
237 //    ICO_TRA("CicoOSClient::receiveEventCB Enter");
238
239     switch (event) {
240     case ICO_UWS_EVT_CLOSE:
241         ICO_DBG(">>>RECV ICO_UWS_EVT_CLOSE(id=%p)", id);
242 //        ICO_TRA("CicoOSClient::receiveEventCB Leave");
243         return;
244     case ICO_UWS_EVT_ERROR:
245         ICO_DBG(">>>RECV ICO_UWS_EVT_ERROR(id=%p, err=%d)",
246                 id, detail->_ico_uws_error.code);
247 //        ICO_TRA("CicoOSClient::receiveEventCB Leave");
248         return;
249     default:
250         break;
251     }
252
253     if (id != m_id) {
254         ICO_DBG(">>>CHANGE id %x -> %x", m_id, id);
255         m_id = id;
256     }
257
258     switch (event) {
259     case ICO_UWS_EVT_OPEN:
260         ICO_DBG(">>>RECV ICO_UWS_EVT_OPEN(id=%p)", id);
261         break;
262     case ICO_UWS_EVT_CLOSE:
263         ICO_DBG(">>>RECV ICO_UWS_EVT_CLOSE(id=%p)", id);
264         break;
265     case ICO_UWS_EVT_RECEIVE:
266     {
267         ICO_DBG(">>>RECV ICO_UWS_EVT_RECEIVE(id=%p, msg=%s, len=%d)",
268                 id, (char *)detail->_ico_uws_message.recv_data,
269                 detail->_ico_uws_message.recv_len);
270         break;
271     }
272     case ICO_UWS_EVT_ADD_FD:
273         ICO_DBG(">>>RECV ICO_UWS_EVT_ADD_FD(id=%p, fd=%d)",
274                 id, detail->_ico_uws_fd.fd);
275         break;
276     case ICO_UWS_EVT_DEL_FD:
277         ICO_DBG(">>>RECV ICO_UWS_EVT_DEL_FD(id=%p, fd=%d)",
278                 id, detail->_ico_uws_fd.fd);
279         break;
280     default:
281         break;
282     }
283 //    ICO_TRA("CicoOSClient::receiveEventCB Leave");
284 }
285
286 Eina_Bool
287 CicoOSClient::ecoreTimerCB(void *data)
288 {
289     CicoOSClient* cosc = (CicoOSClient*)data;
290     cosc->refresh();
291     return ECORE_CALLBACK_RENEW;
292 }
293
294 bool
295 CicoOSClient::refresh()
296 {
297     if (NULL == m_uwsContext) {
298         ICO_TRA("NG refresh");
299         return false;
300     }
301     ico_uws_service(m_uwsContext);
302     return true;
303 }
304
305 // vim:set expandtab ts=4 sw=4: