/fbus/fbus_service.c

http://ftk.googlecode.com/ · C · 296 lines · 216 code · 50 blank · 30 comment · 71 complexity · 10c132d4e99d073c3dd888d7d8c4a5a8 MD5 · raw file

  1. /*
  2. * File: fbus_service.c
  3. * Author: Li XianJing <xianjimli@hotmail.com>
  4. * Brief: service interface and some helper functions.
  5. *
  6. * Copyright (c) 2009 - 2010 Li XianJing <xianjimli@hotmail.com>
  7. *
  8. * Licensed under the Academic Free License version 2.1
  9. *
  10. * This program is free software; you can redistribute it and/or modify
  11. * it under the terms of the GNU General Public License as published by
  12. * the Free Software Foundation; either version 2 of the License, or
  13. * (at your option) any later version.
  14. *
  15. * This program is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. * GNU General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU General Public License
  21. * along with this program; if not, write to the Free Software
  22. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  23. */
  24. /*
  25. * History:
  26. * ================================================================
  27. * 2010-07-25 Li XianJing <xianjimli@hotmail.com> created
  28. *
  29. */
  30. #include "ftk.h"
  31. #include "fbus_service.h"
  32. #include "ftk_source_primary.h"
  33. #include "fbus_source_listen.h"
  34. #include "fbus_service_manager.h"
  35. #include "ftk_allocator_default.h"
  36. typedef struct _ServiceData
  37. {
  38. FtkSource* listener;
  39. FBusStream* clients[FBUS_SERVICE_MAX_CLIENTS];
  40. }ServiceData;
  41. static Ret fbus_service_register_source(FBusService* thiz, int port)
  42. {
  43. ServiceData* data = NULL;
  44. return_val_if_fail(thiz != NULL && thiz->data != NULL, RET_FAIL);
  45. data = thiz->data;
  46. return_val_if_fail(data->listener == NULL, RET_FAIL);
  47. if((data->listener = fbus_source_listen_create(thiz, port)) != NULL)
  48. {
  49. ftk_main_loop_add_source(ftk_default_main_loop(), data->listener);
  50. }
  51. return RET_OK;
  52. }
  53. Ret fbus_service_register(FBusService* thiz)
  54. {
  55. int port = 0;
  56. Ret ret = RET_OK;
  57. ServiceData* data = NULL;
  58. const char* name = NULL;
  59. return_val_if_fail(thiz != NULL && thiz->data == NULL, RET_FAIL);
  60. name = fbus_service_get_name(thiz);
  61. return_val_if_fail(name != NULL, RET_FAIL);
  62. data = FTK_ZALLOC(sizeof(ServiceData));
  63. thiz->data = data;
  64. return_val_if_fail(thiz->data != NULL, RET_FAIL);
  65. if(strcmp(name, FBUS_SERVICE_MANAGER_NAME) != 0)
  66. {
  67. FBusServiceInfo info = {0};
  68. FBusServiceManager* service_manager = fbus_service_manager_create();
  69. if(service_manager != NULL)
  70. {
  71. if((ret = fbus_service_manager_register(service_manager, name, &info)) == RET_OK)
  72. {
  73. port = info.port;
  74. }
  75. fbus_service_manager_destroy(service_manager);
  76. }
  77. }
  78. else
  79. {
  80. port = FBUS_SERVICE_MANAGER_PORT;
  81. }
  82. return_val_if_fail(port > 0, RET_FAIL);
  83. return fbus_service_register_source(thiz, port);
  84. }
  85. Ret fbus_service_unregister(FBusService* thiz)
  86. {
  87. int i = 0;
  88. Ret ret = RET_OK;
  89. ServiceData* data = NULL;
  90. const char* name = NULL;
  91. return_val_if_fail(thiz != NULL && thiz->data != NULL, RET_FAIL);
  92. data = thiz->data;
  93. if(strcmp(name, FBUS_SERVICE_MANAGER_NAME) != 0)
  94. {
  95. FBusServiceManager* service_manager = fbus_service_manager_create();
  96. if(service_manager != NULL)
  97. {
  98. ret = fbus_service_manager_unregister(service_manager, name);
  99. fbus_service_manager_destroy(service_manager);
  100. }
  101. }
  102. ret = ftk_main_loop_remove_source(ftk_default_main_loop(), data->listener);
  103. data->listener = NULL;
  104. name = fbus_service_get_name(thiz);
  105. return_val_if_fail(name != NULL, RET_FAIL);
  106. for(i = 0; i < FBUS_SERVICE_MAX_CLIENTS; i++)
  107. {
  108. if(data->clients[i] != NULL)
  109. {
  110. fbus_stream_destroy(data->clients[i]);
  111. data->clients[i] = NULL;
  112. }
  113. }
  114. FTK_ZFREE(data, sizeof(ServiceData));
  115. thiz->data = NULL;
  116. return ret;
  117. }
  118. Ret fbus_service_notify(FBusService* thiz, int target_id, int trigger_id, FBusParcel* notify)
  119. {
  120. int i = 0;
  121. int ret = RET_FAIL;
  122. int type = FBUS_RESP_PUSH;
  123. ServiceData* data = NULL;
  124. int trigger = FBUS_TRIGGER_BY_SELF;
  125. return_val_if_fail(thiz != NULL && thiz->data != NULL && notify != NULL, RET_FAIL);
  126. data = thiz->data;
  127. for(i = 0; i < FBUS_SERVICE_MAX_CLIENTS; i++)
  128. {
  129. FBusStream* stream = data->clients[i];
  130. if(stream != NULL && (fbus_stream_get_fd(stream) == target_id || target_id < 0))
  131. {
  132. size_t size = fbus_parcel_size(notify);
  133. if(trigger_id <= 0)
  134. {
  135. trigger = FBUS_TRIGGER_BY_SERVICE;
  136. }
  137. else
  138. {
  139. if(trigger_id == fbus_stream_get_fd(stream))
  140. {
  141. trigger = FBUS_TRIGGER_BY_SELF;
  142. }
  143. else
  144. {
  145. trigger = FBUS_TRIGGER_BY_OTHER;
  146. }
  147. }
  148. ret = fbus_stream_write_n(stream, (char*)&type, sizeof(type));
  149. ret = fbus_stream_write_n(stream, (char*)&trigger, sizeof(trigger));
  150. ret = fbus_stream_write_n(stream, (char*)&size, sizeof(size));
  151. ret = fbus_stream_write_n(stream, fbus_parcel_data(notify), size);
  152. }
  153. }
  154. return ret;
  155. }
  156. Ret fbus_service_notify_all(FBusService* thiz, int trigger_id, FBusParcel* notify)
  157. {
  158. return fbus_service_notify(thiz, -1, trigger_id, notify);
  159. }
  160. Ret fbus_service_on_client_connect(FBusService* thiz, FBusStream* client)
  161. {
  162. int i = 0;
  163. Ret ret = RET_OK;
  164. ServiceData* data = NULL;
  165. return_val_if_fail(thiz != NULL && thiz->data != NULL, RET_FAIL);
  166. data = thiz->data;
  167. if(thiz->on_client_connect != NULL)
  168. {
  169. ret = thiz->on_client_connect(thiz, fbus_stream_get_fd(client));
  170. }
  171. ftk_logd("%s: client_id=%d\n", __func__, fbus_stream_get_fd(client));
  172. if(ret == RET_OK)
  173. {
  174. for(i = 0; i < FBUS_SERVICE_MAX_CLIENTS; i++)
  175. {
  176. if(data->clients[i] == NULL)
  177. {
  178. data->clients[i] = client;
  179. break;
  180. }
  181. }
  182. if(i == FBUS_SERVICE_MAX_CLIENTS)
  183. {
  184. ret = RET_OUT_OF_SPACE;
  185. ftk_logd("%s: %s no space for client.\n", __func__, fbus_service_get_name(thiz));
  186. }
  187. }
  188. return ret;
  189. }
  190. Ret fbus_service_on_client_disconnect(FBusService* thiz, FBusStream* client)
  191. {
  192. int i = 0;
  193. Ret ret = RET_OK;
  194. ServiceData* data = NULL;
  195. int client_id = fbus_stream_get_fd(client);
  196. return_val_if_fail(thiz != NULL && thiz->data != NULL, RET_FAIL);
  197. data = thiz->data;
  198. if(thiz->on_client_disconnect != NULL)
  199. {
  200. ret = thiz->on_client_disconnect(thiz, client_id);
  201. }
  202. for(i = 0; i < FBUS_SERVICE_MAX_CLIENTS; i++)
  203. {
  204. if(data->clients[i] != NULL && fbus_stream_get_fd(data->clients[i]) == client_id)
  205. {
  206. data->clients[i] = NULL;
  207. break;
  208. }
  209. }
  210. ftk_logd("%s: client_id=%d\n", __func__, client_id);
  211. return ret;
  212. }
  213. void fbus_service_destroy(FBusService* thiz)
  214. {
  215. if(thiz != NULL && thiz->destroy != NULL)
  216. {
  217. if(thiz->data != NULL)
  218. {
  219. fbus_service_unregister(thiz);
  220. }
  221. thiz->destroy(thiz);
  222. }
  223. return;
  224. }
  225. /****************************************************/
  226. Ret fbus_service_init(int argc, char* argv[])
  227. {
  228. ftk_platform_init(argc, argv);
  229. #ifndef USE_STD_MALLOC
  230. ftk_set_allocator((ftk_allocator_default_create()));
  231. #endif
  232. ftk_set_sources_manager(ftk_sources_manager_create(64));
  233. ftk_set_main_loop(ftk_main_loop_create(ftk_default_sources_manager()));
  234. ftk_set_primary_source(ftk_source_primary_create(NULL, NULL));
  235. ftk_sources_manager_add(ftk_default_sources_manager(), ftk_primary_source());
  236. return RET_OK;
  237. }
  238. Ret fbus_service_run(void)
  239. {
  240. return ftk_run();
  241. }
  242. void fbus_service_quit(void)
  243. {
  244. ftk_quit();
  245. return;
  246. }