/services/fconf/fconf_service.c

http://ftk.googlecode.com/ · C · 328 lines · 246 code · 53 blank · 29 comment · 64 complexity · 4a202b22bb7370f7ad3bf8d536dbf9e8 MD5 · raw file

  1. /*
  2. * File: fconf_service.c
  3. * Author: Li XianJing <xianjimli@hotmail.com>
  4. * Brief: FConf Service.
  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-08-01 Li XianJing <xianjimli@hotmail.com> created
  28. *
  29. */
  30. #include "fconf.h"
  31. #include "fconf_xml.h"
  32. #include "fconf_share.h"
  33. #include "ftk_globals.h"
  34. #include "ftk_main_loop.h"
  35. #include "fconf_service.h"
  36. #include "ftk_source_timer.h"
  37. typedef struct _PrivInfo
  38. {
  39. FConf* impl;
  40. int client_id;
  41. int peer_id; /*the port in client side*/
  42. FBusParcel* parcel;
  43. FtkSource* timer_save;
  44. }PrivInfo;
  45. static Ret fconf_marshal_lock(FBusService* thiz, FBusParcel* req_resp)
  46. {
  47. Ret ret = RET_FAIL;
  48. DECL_PRIV(thiz, priv);
  49. return_val_if_fail(priv != NULL && priv->impl != NULL && req_resp != NULL, RET_FAIL);
  50. if((ret = fconf_lock(priv->impl)) == RET_OK)
  51. {
  52. fbus_parcel_reset(req_resp);
  53. fbus_parcel_write_int(req_resp, ret);
  54. }
  55. return ret;
  56. }
  57. static Ret fconf_marshal_unlock(FBusService* thiz, FBusParcel* req_resp)
  58. {
  59. Ret ret = RET_FAIL;
  60. DECL_PRIV(thiz, priv);
  61. return_val_if_fail(priv != NULL && priv->impl != NULL && req_resp != NULL, RET_FAIL);
  62. if((ret = fconf_unlock(priv->impl)) == RET_OK)
  63. {
  64. fbus_parcel_reset(req_resp);
  65. fbus_parcel_write_int(req_resp, ret);
  66. }
  67. return ret;
  68. }
  69. static Ret fconf_marshal_remove(FBusService* thiz, FBusParcel* req_resp)
  70. {
  71. const char* xpath = {0};
  72. Ret ret = RET_FAIL;
  73. DECL_PRIV(thiz, priv);
  74. return_val_if_fail(priv != NULL && priv->impl != NULL && req_resp != NULL, RET_FAIL);
  75. xpath = fbus_parcel_get_string(req_resp);
  76. if((ret = fconf_remove(priv->impl, xpath)) == RET_OK)
  77. {
  78. fbus_parcel_reset(req_resp);
  79. fbus_parcel_write_int(req_resp, ret);
  80. }
  81. return ret;
  82. }
  83. static Ret fconf_marshal_set(FBusService* thiz, FBusParcel* req_resp)
  84. {
  85. const char* xpath = {0};
  86. const char* value = {0};
  87. Ret ret = RET_FAIL;
  88. DECL_PRIV(thiz, priv);
  89. return_val_if_fail(priv != NULL && priv->impl != NULL && req_resp != NULL, RET_FAIL);
  90. xpath = fbus_parcel_get_string(req_resp);
  91. value = fbus_parcel_get_string(req_resp);
  92. if((ret = fconf_set(priv->impl, xpath, value)) == RET_OK)
  93. {
  94. fbus_parcel_reset(req_resp);
  95. fbus_parcel_write_int(req_resp, ret);
  96. }
  97. return ret;
  98. }
  99. static Ret fconf_marshal_get(FBusService* thiz, FBusParcel* req_resp)
  100. {
  101. const char* xpath = {0};
  102. char* value = {0};
  103. Ret ret = RET_FAIL;
  104. DECL_PRIV(thiz, priv);
  105. return_val_if_fail(priv != NULL && priv->impl != NULL && req_resp != NULL, RET_FAIL);
  106. xpath = fbus_parcel_get_string(req_resp);
  107. if((ret = fconf_get(priv->impl, xpath, &value)) == RET_OK)
  108. {
  109. fbus_parcel_reset(req_resp);
  110. fbus_parcel_write_int(req_resp, ret);
  111. if(ret == RET_OK)
  112. {
  113. fbus_parcel_write_string(req_resp, value);
  114. }
  115. }
  116. return ret;
  117. }
  118. static Ret fconf_marshal_get_child_count(FBusService* thiz, FBusParcel* req_resp)
  119. {
  120. const char* xpath = {0};
  121. int count = {0};
  122. Ret ret = RET_FAIL;
  123. DECL_PRIV(thiz, priv);
  124. return_val_if_fail(priv != NULL && priv->impl != NULL && req_resp != NULL, RET_FAIL);
  125. xpath = fbus_parcel_get_string(req_resp);
  126. if((ret = fconf_get_child_count(priv->impl, xpath, &count)) == RET_OK)
  127. {
  128. fbus_parcel_reset(req_resp);
  129. fbus_parcel_write_int(req_resp, ret);
  130. if(ret == RET_OK)
  131. {
  132. fbus_parcel_write_int(req_resp, count);
  133. }
  134. }
  135. return ret;
  136. }
  137. static Ret fconf_marshal_get_child(FBusService* thiz, FBusParcel* req_resp)
  138. {
  139. const char* xpath = {0};
  140. int index = {0};
  141. char* child = {0};
  142. Ret ret = RET_FAIL;
  143. DECL_PRIV(thiz, priv);
  144. return_val_if_fail(priv != NULL && priv->impl != NULL && req_resp != NULL, RET_FAIL);
  145. xpath = fbus_parcel_get_string(req_resp);
  146. index = fbus_parcel_get_int(req_resp);
  147. if((ret = fconf_get_child(priv->impl, xpath, index, &child)) == RET_OK)
  148. {
  149. fbus_parcel_reset(req_resp);
  150. fbus_parcel_write_int(req_resp, ret);
  151. if(ret == RET_OK)
  152. {
  153. fbus_parcel_write_string(req_resp, child);
  154. }
  155. }
  156. return ret;
  157. }
  158. static const char* fconf_service_get_name(FBusService* thiz)
  159. {
  160. return FBUS_SERVICE_FCONF;
  161. }
  162. static Ret fconf_service_on_client_connect(FBusService* thiz, int client_id)
  163. {
  164. return RET_OK;
  165. }
  166. static Ret fconf_service_on_client_disconnect(FBusService* thiz, int client_id)
  167. {
  168. return RET_OK;
  169. }
  170. static Ret fconf_service_handle_request(FBusService* thiz, int client_id, FBusParcel* req_resp)
  171. {
  172. DECL_PRIV(thiz, priv);
  173. int req_code = fbus_parcel_get_int(req_resp);
  174. priv->client_id = client_id;
  175. switch(req_code)
  176. {
  177. case FCONF_LOCK:
  178. {
  179. fconf_marshal_lock(thiz, req_resp);
  180. break;
  181. }
  182. case FCONF_UNLOCK:
  183. {
  184. fconf_marshal_unlock(thiz, req_resp);
  185. break;
  186. }
  187. case FCONF_REMOVE:
  188. {
  189. fconf_marshal_remove(thiz, req_resp);
  190. break;
  191. }
  192. case FCONF_SET:
  193. {
  194. fconf_marshal_set(thiz, req_resp);
  195. break;
  196. }
  197. case FCONF_GET:
  198. {
  199. fconf_marshal_get(thiz, req_resp);
  200. break;
  201. }
  202. case FCONF_GET_CHILD_COUNT:
  203. {
  204. fconf_marshal_get_child_count(thiz, req_resp);
  205. break;
  206. }
  207. case FCONF_GET_CHILD:
  208. {
  209. fconf_marshal_get_child(thiz, req_resp);
  210. break;
  211. }
  212. default:break;
  213. }
  214. if(fconf_xml_is_dirty(priv->impl) && priv->timer_save->ref < 2)
  215. {
  216. ftk_logd("%s: timer save %d\n", __func__, priv->timer_save->ref);
  217. ftk_source_ref(priv->timer_save);
  218. ftk_main_loop_add_source(ftk_default_main_loop(), priv->timer_save);
  219. }
  220. return RET_OK;
  221. }
  222. static void fconf_service_destroy(FBusService* thiz)
  223. {
  224. if(thiz != NULL)
  225. {
  226. DECL_PRIV(thiz, priv);
  227. ftk_source_disable(priv->timer_save);
  228. ftk_source_unref(priv->timer_save);
  229. fbus_parcel_destroy(priv->parcel);
  230. fconf_destroy(priv->impl);
  231. FTK_FREE(thiz);
  232. }
  233. return;
  234. }
  235. static Ret on_changed(void* ctx, int change_by_self, FConfChangeType type, const char* xpath, const char* value)
  236. {
  237. FBusService* thiz = ctx;
  238. DECL_PRIV(thiz, priv);
  239. fbus_parcel_reset(priv->parcel);
  240. fbus_parcel_write_int(priv->parcel, type);
  241. fbus_parcel_write_string(priv->parcel, xpath);
  242. if(value != NULL)
  243. {
  244. fbus_parcel_write_string(priv->parcel, value);
  245. }
  246. fbus_service_notify_all(thiz, priv->client_id, priv->parcel);
  247. ftk_logd("%s: client_id=%d %d %d %s %s\n", __func__, priv->client_id, change_by_self, type, xpath, value);
  248. return RET_OK;
  249. }
  250. static Ret timer_save_func(void* ctx)
  251. {
  252. FBusService* thiz = ctx;
  253. DECL_PRIV(thiz, priv);
  254. fconf_xml_save(priv->impl);
  255. return RET_REMOVE;
  256. }
  257. FBusService* fconf_service_create(void)
  258. {
  259. FBusService* thiz = FTK_ZALLOC(sizeof(FBusService)+sizeof(PrivInfo));
  260. if(thiz != NULL)
  261. {
  262. DECL_PRIV(thiz, priv);
  263. priv->parcel = fbus_parcel_create(1024);
  264. priv->timer_save = ftk_source_timer_create(10000, timer_save_func, thiz);
  265. priv->impl = fconf_xml_create(DATA_DIR"/config");
  266. thiz->get_name = fconf_service_get_name;
  267. thiz->on_client_connect = fconf_service_on_client_connect;
  268. thiz->on_client_disconnect = fconf_service_on_client_disconnect;
  269. thiz->handle_request = fconf_service_handle_request;
  270. thiz->destroy = fconf_service_destroy;
  271. fbus_service_register(thiz);
  272. fconf_reg_changed_notify(priv->impl, on_changed, thiz);
  273. }
  274. return thiz;
  275. }