2 * Copyright (c) 2013, TOYOTA MOTOR CORPORATION.
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
10 * @brief library to communicate with outer process
18 #include "CicoSCServer.h"
19 #include "CicoSCCommandParser.h"
20 #include "CicoSCMessage.h"
22 #include "ico_syc_error.h"
23 #include "ico_syc_msg_cmd_def.h"
24 #include "CicoSCWindowController.h"
25 #include "CicoSCInputController.h"
26 #include "CicoSCUserManager.h"
27 #include "CicoSCUser.h"
28 #include "CicoSCResourceManager.h"
34 : uwsContext(NULL), id(NULL), fd(-1), serviceFlag(false),
35 ecoreFdHandler(NULL), appid("") {}
36 void dump(void) const {
37 ICO_DBG("uwsContext=%08X fd=%d service=%s ecoreFdHandler=%08X appid=%s",
38 uwsContext, fd, serviceFlag ? "true" : "false",
39 ecoreFdHandler, appid.c_str());
41 struct ico_uws_context *uwsContext;
45 Ecore_Fd_Handler *ecoreFdHandler;
49 CicoSCServer* CicoSCServer::ms_myInstance = NULL;
51 CicoSCServer::CicoSCServer()
52 : m_uwsContext(NULL), m_windowCtrl(NULL),
53 m_inputCtrl(NULL) , m_userMgr(NULL)
57 CicoSCServer::~CicoSCServer()
62 CicoSCServer::getInstance(void)
64 if (NULL == ms_myInstance) {
65 ms_myInstance = new CicoSCServer();
72 CicoSCServer::setWindowCtrl(CicoSCWindowController *windowCtrl)
74 m_windowCtrl = windowCtrl;
78 CicoSCServer::setInputCtrl(CicoSCInputController *inputCtrl)
80 m_inputCtrl= inputCtrl;
84 CicoSCServer::setUserMgr(CicoSCUserManager *userMgr)
89 //--------------------------------------------------------------------------
91 * @brief startup server
93 * @param [IN] port websocket port
94 * @param [IN] protocol websocket protocol name
96 * @retval ICO_SYC_EOK success
97 * @retval ICO_SYC_ENOSYS error(connection faile)
99 //--------------------------------------------------------------------------
101 CicoSCServer::setResourceMgr(CicoSCResourceManager *resourceMgr)
103 m_resourceMgr = resourceMgr;
106 //--------------------------------------------------------------------------
108 * @brief startup server
110 * @param [IN] port websocket port
111 * @param [IN] protocol websocket protocol name
113 * @retval ICO_SYC_EOK success
114 * @retval ICO_SYC_ENOSYS error(connection faile)
116 //--------------------------------------------------------------------------
118 CicoSCServer::startup(int port, const char *protocol)
120 /* create uir string ":PORT" */
125 ICO_DBG("ico_uws_create_context(%s,%s) called.",
126 uri.str().c_str(), protocol);
127 m_uwsContext = ico_uws_create_context(uri.str().c_str(), protocol);
128 if (NULL == m_uwsContext) {
129 ICO_ERR("ico_uws_create_context() failed.");
130 return ICO_SYC_ENOSYS;
132 ico_uws_service(m_uwsContext);
135 int ret = ico_uws_set_event_cb(m_uwsContext, uwsCallback, (void *)this);
136 if (ret != ICO_UWS_ERR_NONE) {
137 ICO_ERR("ico_uws_set_event_cb() failed(%d).", ret);
138 return ICO_SYC_ENOSYS;
140 ico_uws_service(m_uwsContext);
146 CicoSCServer::findUwsHandler(const struct ico_uws_context *context,
149 list<CicoSCUwsHandle*>::iterator itr;
150 itr = m_uwsHandlerList.begin();
151 for (; itr != m_uwsHandlerList.end(); ++itr) {
152 ICO_DBG("handle->context=%p handle->id=%p context=%p id=%p",
153 (*itr)->uwsContext, (*itr)->id, context, id);
154 if (((*itr)->uwsContext == context) &&
155 ((*itr)->id == id)) {
163 CicoSCServer::findUwsHandler(const Ecore_Fd_Handler *ecoreFdHandler)
165 list<CicoSCUwsHandle*>::iterator itr;
166 itr = m_uwsHandlerList.begin();
167 for (; itr != m_uwsHandlerList.end(); ++itr) {
168 if ((*itr)->ecoreFdHandler == ecoreFdHandler) {
176 CicoSCServer::findUwsHandler(const string & appid)
178 list<CicoSCUwsHandle*>::iterator itr;
179 itr = m_uwsHandlerList.begin();
180 for (; itr != m_uwsHandlerList.end(); ++itr) {
181 ICO_DBG("handle->id=%p handle->appid=%s appid=%s",
182 (*itr)->id, (*itr)->appid.c_str(), appid.c_str());
183 if ((*itr)->appid == appid) {
191 CicoSCServer::addPollFd(CicoSCUwsHandle *handle)
193 ICO_DBG("CicoSCServer::addPollFd Enter(fd=%d)", handle->fd);
194 Ecore_Fd_Handler_Flags flags = (Ecore_Fd_Handler_Flags)(ECORE_FD_READ | ECORE_FD_ERROR);
196 handle->ecoreFdHandler = ecore_main_fd_handler_add(handle->fd, flags,
199 ICO_DBG("CicoSCServer::addPollFd Leave");
203 CicoSCServer::delPollFd(CicoSCUwsHandle *handle)
205 ICO_DBG("CicoSCServer::delPollFd Enter");
206 ecore_main_fd_handler_del(handle->ecoreFdHandler);
207 handle->ecoreFdHandler = NULL;
208 ICO_DBG("CicoSCServer::delPollFd Enter");
212 CicoSCServer::ecoreFdCallback(void *data, Ecore_Fd_Handler *handler)
214 ICO_DBG("CicoSCServer::ecoreFdCallback Enter");
218 Eina_Bool flag = ecore_main_fd_handler_active_get(handler, ECORE_FD_READ);
219 if (Eina_True == flag) {
220 fdFlags |= ECORE_FD_READ;
223 Eina_Bool flag = ecore_main_fd_handler_active_get(handler, ECORE_FD_ERROR);
224 if (Eina_True == flag) {
225 fdFlags |= ECORE_FD_ERROR;
228 Eina_Bool flag = ecore_main_fd_handler_active_get(handler, ECORE_FD_WRITE);
229 if (Eina_True == flag) {
230 fdFlags |= ECORE_FD_WRITE;
234 CicoSCUwsHandle *handle = NULL;
235 handle = static_cast<CicoSCServer*>(data)->findUwsHandler(handler);
236 if (NULL != handle) {
237 static_cast<CicoSCServer*>(data)->dispatch(handle, fdFlags);
240 ICO_DBG("CicoSCServer::ecoreFdCallback Leave");
241 return ECORE_CALLBACK_RENEW;
245 CicoSCServer::dispatch(const CicoSCUwsHandle *handle, int flags)
247 ICO_DBG("CicoSCServer::dispatch Enter");
249 if (NULL == handle) {
250 ICO_WRN("handle is null");
251 ICO_DBG("CicoSCServer::dispatch Leave");
254 handle->dump(); //TODO
256 ico_uws_service(handle->uwsContext);
258 list<CicoSCCommand*>::iterator itr;
259 itr = m_recvCmdQueue.begin();
260 while(itr != m_recvCmdQueue.end()) {
261 ICO_DBG("Deque command(0x%08X)", (*itr)->cmdid);
262 CicoSCCommand *cmd = *itr;
263 itr = m_recvCmdQueue.erase(itr);
264 switch (cmd->cmdid & MSG_CMD_TYPE_MASK) {
265 case MSG_CMD_TYPE_WINCTRL:
266 ICO_DBG("command : MSG_CMD_TYPE_WINCTRL");
267 m_windowCtrl->handleCommand(cmd);
269 case MSG_CMD_TYPE_INPUTCTRL:
270 ICO_DBG("command : MSG_CMD_TYPE_INPUTCTRL");
271 m_inputCtrl->handleCommand(cmd);
273 case MSG_CMD_TYPE_USERMGR:
274 ICO_DBG("command : MSG_CMD_TYPE_USERMGR");
275 m_userMgr->handleCommand(cmd);
277 case MSG_CMD_TYPE_RESOURCEMGR:
278 ICO_DBG("command : MSG_CMD_TYPE_RESOURCEMGR");
279 m_resourceMgr->handleCommand(*cmd);
282 ICO_DBG("command : unknown");
288 if (NULL == handle->ecoreFdHandler) {
289 ICO_ERR("ecoreFdHandler is null");
290 ICO_DBG("CicoSCServer::dispatch Leave");
294 Eina_Bool flag = ecore_main_fd_handler_active_get(handle->ecoreFdHandler,
296 if (EINA_TRUE == flag) {
297 ICO_DBG("start send message");
298 list<CicoSCMessage*>::iterator send_itr;
299 send_itr = m_sendMsgQueue.begin();
300 while (send_itr != m_sendMsgQueue.end()) {
301 ICO_DBG("m_sendMsgQueue.size=%d", m_sendMsgQueue.size());
302 CicoSCMessage* msg = *send_itr;
303 CicoSCUwsHandle *sendHandle = findUwsHandler(msg->getSendToAppid());
304 if (handle != sendHandle) {
308 send_itr = m_sendMsgQueue.erase(send_itr);
309 ICO_DBG("Deque Message(id=%d)", msg->getId());
310 if ((NULL != sendHandle) && (true == sendHandle->serviceFlag)) {
312 ICO_DBG("<<<SEND id=%08X msg=%s",
313 sendHandle->id, msg->getData());
314 ICO_DBG("ico_usw_send called.");
315 ico_uws_send(sendHandle->uwsContext, sendHandle->id,
316 (unsigned char *)msg->getData(),
317 strlen(msg->getData()));
324 ecore_main_fd_handler_active_set(handle->ecoreFdHandler,
325 (Ecore_Fd_Handler_Flags)(ECORE_FD_READ | ECORE_FD_ERROR));
328 ICO_DBG("CicoSCServer::dispatch Leave");
332 CicoSCServer::sendMessage(const string & appid, CicoSCMessage* msg)
334 ICO_DBG("CicoSCServer::sendMessage Enter(appid=%s, msg=%s)",
335 appid.c_str(), msg->getData());
337 msg->setSendToAppid(appid);
338 ICO_DBG("Enque Message(id=%d)", msg->getId());
339 m_sendMsgQueue.push_back(msg);
341 CicoSCUwsHandle *handle = findUwsHandler(appid);
342 if (NULL != handle) {
343 ecore_main_fd_handler_active_set(handle->ecoreFdHandler,
344 (Ecore_Fd_Handler_Flags)(ECORE_FD_READ |
350 ICO_DBG("CicoSCServer::sendMessage Leave(EOK)");
355 CicoSCServer::sendMessageToHomeScreen(CicoSCMessage* msg)
357 const CicoSCUser *loginUser = m_userMgr->getLoginUser();
358 if (NULL == loginUser) {
359 ICO_WRN("homescree unknow");
360 return ICO_SYC_ENOENT;
362 return sendMessage(loginUser->homescreen, msg);
366 CicoSCServer::uwsCallbackImpl(const struct ico_uws_context *context,
367 const ico_uws_evt_e event,
369 const ico_uws_detail *detail,
372 ICO_DBG("CicoSCServer::uwsCallbackImpl Enter");
375 CicoSCUwsHandle *handle = findUwsHandler(context, id);
376 // If not found handle, create new handle
377 if (NULL == handle) {
378 handle = new CicoSCUwsHandle();
379 m_uwsHandlerList.push_back(handle);
380 handle->uwsContext = (struct ico_uws_context*)context;
381 handle->id = (void*)(id);
382 handle->serviceFlag = false;
386 case ICO_UWS_EVT_OPEN:
388 ICO_DBG(">>>RECV ICO_UWS_EVT_OPEN(id=%08x)", (int)id);
391 case ICO_UWS_EVT_CLOSE:
392 ICO_DBG(">>>RECV ICO_UWS_EVT_CLOSE(id=%08x)", (int)id);
395 case ICO_UWS_EVT_RECEIVE:
397 ICO_DBG(">>>RECV ICO_UWS_EVT_RECEIVE(id=%08x, msg=%s, len=%d)",
398 (int)id, (char *)detail->_ico_uws_message.recv_data,
399 detail->_ico_uws_message.recv_len);
401 // convert message to command
402 CicoSCCommand *cmd = new CicoSCCommand();
403 CicoSCCommandParser cmdParser;
404 cmdParser.parse((const char*)detail->_ico_uws_message.recv_data, *cmd);
406 // update handle appid
407 if (cmd->cmdid == MSG_CMD_SEND_APPID) {
408 if (0 == cmd->appid.length()) {
409 ICO_WRN("command argument invalid appid null");
412 handle->appid = cmd->appid;
413 handle->serviceFlag = true;
414 ICO_DBG("handle.appid=%s", handle->appid.c_str());
415 ecore_main_fd_handler_active_set(handle->ecoreFdHandler,
416 (Ecore_Fd_Handler_Flags)(ECORE_FD_READ |
425 ICO_DBG("Enque command(0x%08X)", cmd->cmdid);
426 m_recvCmdQueue.push_back(cmd);
429 case ICO_UWS_EVT_ERROR:
430 ICO_DBG(">>>RECV ICO_UWS_EVT_ERROR(id=%08x, err=%d)",
431 (int)id, detail->_ico_uws_error.code);
433 case ICO_UWS_EVT_ADD_FD:
434 ICO_DBG(">>>RECV ICO_UWS_EVT_ADD_FD(id=%08x, fd=%d)",
435 (int)id, detail->_ico_uws_fd.fd);
436 handle->fd = detail->_ico_uws_fd.fd;
440 case ICO_UWS_EVT_DEL_FD:
441 ICO_DBG(">>>RECV ICO_UWS_EVT_DEL_FD(id=%d, fd=%d)",
442 (int)id, detail->_ico_uws_fd.fd);
449 ICO_DBG("CicoSCServer::uwsCallbackImpl Leave");
452 /*--------------------------------------------------------------------------*/
454 * @brief callback_uws
455 * callback function from UWS
457 * @param[in] context context * @param[in] event event kinds
458 * @param[in] id client id
459 * @param[in] detail event detail
460 * @param[in] data user data
463 /*--------------------------------------------------------------------------*/
465 CicoSCServer::uwsCallback(const struct ico_uws_context *context,
466 const ico_uws_evt_e event,
468 const ico_uws_detail *detail,
471 ICO_DBG("callback_uws: context=%08x id=%08x", (int)context, (int)id);
473 CicoSCServer* server = static_cast<CicoSCServer*>(user_data);
474 server->uwsCallbackImpl(context, event, id, detail, user_data);
476 // vim:set expandtab ts=4 sw=4: