PageRenderTime 854ms CodeModel.GetById 139ms app.highlight 291ms RepoModel.GetById 383ms app.codeStats 1ms

/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/*
 26 * History:
 27 * ================================================================
 28 * 2010-07-25 Li XianJing <xianjimli@hotmail.com> created
 29 *
 30 */
 31
 32#include "ftk.h"
 33#include "fbus_service.h"
 34#include "ftk_source_primary.h"
 35#include "fbus_source_listen.h"
 36#include "fbus_service_manager.h"
 37#include "ftk_allocator_default.h"
 38
 39typedef struct _ServiceData
 40{
 41	FtkSource*  listener;
 42	FBusStream* clients[FBUS_SERVICE_MAX_CLIENTS];
 43}ServiceData;
 44
 45static Ret fbus_service_register_source(FBusService* thiz, int port)
 46{
 47	ServiceData* data = NULL;
 48	return_val_if_fail(thiz != NULL && thiz->data != NULL, RET_FAIL);
 49
 50	data = thiz->data;
 51	return_val_if_fail(data->listener == NULL, RET_FAIL);
 52
 53	if((data->listener = fbus_source_listen_create(thiz, port)) != NULL)
 54	{
 55		ftk_main_loop_add_source(ftk_default_main_loop(), data->listener);
 56	}
 57
 58	return RET_OK;
 59}
 60
 61Ret fbus_service_register(FBusService* thiz)
 62{
 63	int port = 0;
 64	Ret ret = RET_OK;
 65	ServiceData* data = NULL;
 66	const char* name = NULL;
 67	return_val_if_fail(thiz != NULL && thiz->data == NULL, RET_FAIL);
 68
 69	name = fbus_service_get_name(thiz);
 70	return_val_if_fail(name != NULL, RET_FAIL);
 71	
 72	data = FTK_ZALLOC(sizeof(ServiceData));
 73	thiz->data = data;
 74	return_val_if_fail(thiz->data != NULL, RET_FAIL);
 75	
 76	if(strcmp(name, FBUS_SERVICE_MANAGER_NAME) != 0)
 77	{
 78		FBusServiceInfo info = {0};
 79		FBusServiceManager* service_manager = fbus_service_manager_create();
 80		if(service_manager != NULL)
 81		{
 82			if((ret = fbus_service_manager_register(service_manager, name, &info)) == RET_OK)
 83			{
 84				port = info.port;
 85			}
 86			fbus_service_manager_destroy(service_manager);
 87		}
 88	}
 89	else 
 90	{
 91		port = FBUS_SERVICE_MANAGER_PORT;
 92	}
 93
 94	return_val_if_fail(port > 0, RET_FAIL);
 95
 96	return fbus_service_register_source(thiz, port);
 97}
 98
 99Ret fbus_service_unregister(FBusService* thiz)
100{
101	int i = 0;
102	Ret ret = RET_OK;
103	ServiceData* data = NULL;
104	const char* name = NULL;
105
106	return_val_if_fail(thiz != NULL && thiz->data != NULL, RET_FAIL);
107
108	data = thiz->data;
109	if(strcmp(name, FBUS_SERVICE_MANAGER_NAME) != 0)
110	{
111		FBusServiceManager* service_manager = fbus_service_manager_create();
112		if(service_manager != NULL)
113		{
114			ret = fbus_service_manager_unregister(service_manager, name);
115			fbus_service_manager_destroy(service_manager);
116		}
117	}
118
119	ret = ftk_main_loop_remove_source(ftk_default_main_loop(), data->listener);
120	data->listener = NULL;
121
122	name = fbus_service_get_name(thiz);
123	return_val_if_fail(name != NULL, RET_FAIL);
124
125	for(i = 0; i < FBUS_SERVICE_MAX_CLIENTS; i++)
126	{
127		if(data->clients[i] != NULL)
128		{
129			fbus_stream_destroy(data->clients[i]);
130			data->clients[i] = NULL;
131		}
132	}
133
134	FTK_ZFREE(data, sizeof(ServiceData));
135	thiz->data = NULL;
136
137	return ret;
138}
139
140Ret  fbus_service_notify(FBusService* thiz, int target_id, int trigger_id, FBusParcel* notify)
141{
142	int i = 0;
143	int ret = RET_FAIL;
144	int type = FBUS_RESP_PUSH;
145	ServiceData* data = NULL;
146	int trigger = FBUS_TRIGGER_BY_SELF;
147
148	return_val_if_fail(thiz != NULL && thiz->data != NULL && notify != NULL, RET_FAIL);
149
150	data = thiz->data;
151	for(i = 0; i < FBUS_SERVICE_MAX_CLIENTS; i++)
152	{
153		FBusStream* stream = data->clients[i];
154		if(stream != NULL && (fbus_stream_get_fd(stream) == target_id || target_id < 0))
155		{
156			size_t size = fbus_parcel_size(notify);
157	
158			if(trigger_id <= 0)
159			{
160				trigger = FBUS_TRIGGER_BY_SERVICE;
161			}
162			else
163			{
164				if(trigger_id == fbus_stream_get_fd(stream))
165				{
166					trigger = FBUS_TRIGGER_BY_SELF;
167				}
168				else
169				{
170					trigger = FBUS_TRIGGER_BY_OTHER;
171				}
172			}
173
174			ret = fbus_stream_write_n(stream, (char*)&type, sizeof(type));
175			ret = fbus_stream_write_n(stream, (char*)&trigger, sizeof(trigger));
176			ret = fbus_stream_write_n(stream, (char*)&size, sizeof(size));
177			ret = fbus_stream_write_n(stream, fbus_parcel_data(notify), size);
178		}
179	}
180
181	return ret;
182}
183
184Ret  fbus_service_notify_all(FBusService* thiz, int trigger_id, FBusParcel* notify)
185{
186	return fbus_service_notify(thiz, -1, trigger_id, notify);
187}
188
189Ret fbus_service_on_client_connect(FBusService* thiz, FBusStream* client)
190{
191	int i = 0;
192	Ret ret = RET_OK;
193	ServiceData* data = NULL;
194	
195	return_val_if_fail(thiz != NULL && thiz->data != NULL, RET_FAIL);
196
197	data = thiz->data;
198	if(thiz->on_client_connect != NULL)
199	{
200		ret = thiz->on_client_connect(thiz, fbus_stream_get_fd(client));
201	}
202
203	ftk_logd("%s: client_id=%d\n", __func__, fbus_stream_get_fd(client));
204	if(ret == RET_OK)
205	{
206		for(i = 0; i < FBUS_SERVICE_MAX_CLIENTS; i++)
207		{
208			if(data->clients[i] == NULL)
209			{
210				data->clients[i] = client;
211				break;
212			}
213		}
214
215		if(i == FBUS_SERVICE_MAX_CLIENTS)
216		{
217			ret = RET_OUT_OF_SPACE;
218			ftk_logd("%s: %s no space for client.\n", __func__, fbus_service_get_name(thiz));
219		}
220	}
221
222	return ret;
223}
224
225Ret fbus_service_on_client_disconnect(FBusService* thiz, FBusStream* client)
226{
227	int i = 0;
228	Ret ret = RET_OK;
229	ServiceData* data = NULL;
230	int client_id = fbus_stream_get_fd(client);
231
232	return_val_if_fail(thiz != NULL && thiz->data != NULL, RET_FAIL);
233
234	data = thiz->data;
235	if(thiz->on_client_disconnect != NULL)
236	{
237		ret = thiz->on_client_disconnect(thiz, client_id);
238	}
239	
240	for(i = 0; i < FBUS_SERVICE_MAX_CLIENTS; i++)
241	{
242		if(data->clients[i] != NULL && fbus_stream_get_fd(data->clients[i]) == client_id)
243		{
244			data->clients[i] = NULL;
245			break;
246		}
247	}
248
249	ftk_logd("%s: client_id=%d\n", __func__, client_id);
250
251	return ret;
252}
253
254void fbus_service_destroy(FBusService* thiz)
255{
256	if(thiz != NULL && thiz->destroy != NULL)
257	{
258		if(thiz->data != NULL)
259		{
260			fbus_service_unregister(thiz);
261		}
262		thiz->destroy(thiz);
263	}
264
265	return;
266}
267
268/****************************************************/
269
270Ret fbus_service_init(int argc, char* argv[])
271{
272	ftk_platform_init(argc, argv);
273
274#ifndef USE_STD_MALLOC
275	ftk_set_allocator((ftk_allocator_default_create()));
276#endif
277	ftk_set_sources_manager(ftk_sources_manager_create(64));
278	ftk_set_main_loop(ftk_main_loop_create(ftk_default_sources_manager()));
279	ftk_set_primary_source(ftk_source_primary_create(NULL, NULL));
280	ftk_sources_manager_add(ftk_default_sources_manager(), ftk_primary_source());
281
282	return RET_OK;
283}
284
285Ret fbus_service_run(void)
286{
287	return ftk_run();
288}
289
290void fbus_service_quit(void)
291{
292	ftk_quit();
293
294	return;
295}
296