/fbus/fbus_proxy.c

http://ftk.googlecode.com/ · C · 243 lines · 176 code · 37 blank · 30 comment · 62 complexity · de876ed06461278ec5b44ab72081d6ee MD5 · raw file

  1. /*
  2. * File: fbus_proxy.c
  3. * Author: Li XianJing <xianjimli@hotmail.com>
  4. * Brief: the proxy object in client side, help you to access remote
  5. * object in server side.
  6. *
  7. * Copyright (c) 2009 - 2010 Li XianJing <xianjimli@hotmail.com>
  8. *
  9. * Licensed under the Academic Free License version 2.1
  10. *
  11. * This program is free software; you can redistribute it and/or modify
  12. * it under the terms of the GNU General Public License as published by
  13. * the Free Software Foundation; either version 2 of the License, or
  14. * (at your option) any later version.
  15. *
  16. * This program is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. * GNU General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU General Public License
  22. * along with this program; if not, write to the Free Software
  23. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  24. */
  25. /*
  26. * History:
  27. * ================================================================
  28. * 2010-07-25 Li XianJing <xianjimli@hotmail.com> created
  29. *
  30. */
  31. #include "ftk_source.h"
  32. #include "fbus_parcel.h"
  33. #include "fbus_proxy.h"
  34. #include "ftk_globals.h"
  35. #include "ftk_main_loop.h"
  36. #include "fbus_stream_socket.h"
  37. #include "fbus_source_proxy.h"
  38. #include "fbus_service_manager.h"
  39. struct _FBusProxy
  40. {
  41. int busy;
  42. FBusParcel* parcel;
  43. FBusStream* stream;
  44. FtkSource* source;
  45. void* listener_ctx;
  46. FBusProxyListener listener;
  47. };
  48. FBusProxy* fbus_proxy_create(const char* service)
  49. {
  50. Ret ret = RET_FAIL;
  51. FBusProxy* thiz = NULL;
  52. FBusStream* stream = NULL;
  53. FBusServiceInfo info = {0};
  54. return_val_if_fail(service != NULL, NULL);
  55. if(strcmp(service, FBUS_SERVICE_MANAGER_NAME) != 0)
  56. {
  57. FBusServiceManager* service_manager = fbus_proxy_create(FBUS_SERVICE_MANAGER_NAME);
  58. if(service_manager != NULL)
  59. {
  60. ret = fbus_service_manager_start(service_manager, service);
  61. if(ret == RET_OK)
  62. {
  63. int i = 0;
  64. for(i = 0; i < 5; i++)
  65. {
  66. ret = fbus_service_manager_query(service_manager, service, &info);
  67. if(ret == RET_OK && info.status == FBUS_SERVICE_STARTED)
  68. {
  69. break;
  70. }
  71. if(ret != RET_OK)
  72. {
  73. usleep(200000);
  74. }
  75. }
  76. }
  77. fbus_proxy_destroy(service_manager);
  78. }
  79. }
  80. else
  81. {
  82. strcpy(info.host, FBUS_LOCALHOST);
  83. info.port = FBUS_SERVICE_MANAGER_PORT;
  84. }
  85. return_val_if_fail(info.port > 0, NULL);
  86. stream = fbus_stream_socket_connect(info.host, info.port);
  87. return_val_if_fail(stream != NULL, NULL);
  88. thiz = FTK_ZALLOC(sizeof(FBusProxy));
  89. if(thiz != NULL)
  90. {
  91. thiz->stream = stream;
  92. }
  93. else
  94. {
  95. fbus_stream_destroy(stream);
  96. }
  97. return thiz;
  98. }
  99. FBusParcel* fbus_proxy_get_parcel(FBusProxy* thiz)
  100. {
  101. return_val_if_fail(thiz != NULL, NULL);
  102. if(thiz->parcel == NULL)
  103. {
  104. thiz->parcel = fbus_parcel_create(256);
  105. }
  106. else
  107. {
  108. fbus_parcel_reset(thiz->parcel);
  109. }
  110. return thiz->parcel;
  111. }
  112. static Ret fbus_proxy_send_request(FBusProxy* thiz, FBusParcel* parcel)
  113. {
  114. int size = 0;
  115. int ret = RET_FAIL;
  116. return_val_if_fail(thiz != NULL && thiz->stream != NULL && parcel != NULL, RET_FAIL);
  117. size = fbus_parcel_size(parcel);
  118. ret = fbus_stream_write_n(thiz->stream, (const char*)&size, sizeof(size));
  119. return_val_if_fail(ret == sizeof(size), RET_FAIL);
  120. ret = fbus_stream_write_n(thiz->stream, fbus_parcel_data(parcel), size);
  121. return_val_if_fail(ret == size, RET_FAIL);
  122. return RET_OK;
  123. }
  124. static Ret fbus_proxy_recv_response(FBusProxy* thiz, FBusParcel* parcel)
  125. {
  126. int type = 0;
  127. int trigger = 0;
  128. int size = 0;
  129. int ret = RET_FAIL;
  130. return_val_if_fail(thiz != NULL && thiz->stream != NULL && parcel != NULL, RET_FAIL);
  131. do
  132. {
  133. fbus_parcel_reset(parcel);
  134. ret = fbus_stream_read_n(thiz->stream, (char*)&type, sizeof(type));
  135. return_val_if_fail(ret == sizeof(type), RET_FAIL);
  136. if(type == FBUS_RESP_PUSH)
  137. {
  138. ret = fbus_stream_read_n(thiz->stream, (char*)&trigger, sizeof(trigger));
  139. return_val_if_fail(ret == sizeof(trigger), RET_FAIL);
  140. }
  141. ret = fbus_stream_read_n(thiz->stream, (char*)&size, sizeof(size));
  142. return_val_if_fail(ret == sizeof(size), RET_FAIL);
  143. fbus_parcel_extend(parcel, size);
  144. fbus_parcel_set_size(parcel, size);
  145. ret = fbus_stream_read_n(thiz->stream, fbus_parcel_data(parcel), size);
  146. return_val_if_fail(ret == size, RET_FAIL);
  147. if(type == FBUS_RESP_PUSH)
  148. {
  149. if(thiz->listener != NULL)
  150. {
  151. thiz->listener(thiz->listener_ctx, trigger, parcel);
  152. }
  153. }
  154. }while(type != FBUS_RESP_NORMAL);
  155. return RET_OK;
  156. }
  157. Ret fbus_proxy_set_notify_listener(FBusProxy* thiz, FBusProxyListener listener, void* ctx)
  158. {
  159. return_val_if_fail(thiz != NULL, RET_FAIL);
  160. thiz->listener = listener;
  161. thiz->listener_ctx = ctx;
  162. if(thiz->source != NULL)
  163. {
  164. ftk_main_loop_remove_source(ftk_default_main_loop(), thiz->source);
  165. thiz->source = NULL;
  166. }
  167. if(listener != NULL)
  168. {
  169. thiz->source = fbus_source_proxy_create(thiz, thiz->stream, listener, ctx);
  170. if(thiz->source != NULL)
  171. {
  172. ftk_main_loop_add_source(ftk_default_main_loop(), thiz->source);
  173. }
  174. }
  175. return RET_OK;
  176. }
  177. void fbus_proxy_destroy(FBusProxy* thiz)
  178. {
  179. if(thiz != NULL)
  180. {
  181. if(thiz->source != NULL)
  182. {
  183. fbus_proxy_set_notify_listener(thiz, NULL, NULL);
  184. }
  185. fbus_stream_destroy(thiz->stream);
  186. if(thiz->parcel != NULL)
  187. {
  188. fbus_parcel_destroy(thiz->parcel);
  189. }
  190. FTK_FREE(thiz);
  191. }
  192. return;
  193. }
  194. Ret fbus_proxy_request(FBusProxy* thiz, FBusParcel* req_resp)
  195. {
  196. Ret ret = RET_FAIL;
  197. return_val_if_fail(thiz != NULL && req_resp != NULL, RET_FAIL);
  198. return_val_if_fail(thiz->busy == 0, RET_FAIL);
  199. thiz->busy = 1;
  200. if((ret = fbus_proxy_send_request(thiz, req_resp)) == RET_OK)
  201. {
  202. ret = fbus_proxy_recv_response(thiz, req_resp);
  203. }
  204. thiz->busy = 0;
  205. return ret;
  206. }