PageRenderTime 53ms CodeModel.GetById 20ms app.highlight 17ms RepoModel.GetById 13ms app.codeStats 0ms

/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/*
 27 * History:
 28 * ================================================================
 29 * 2010-07-25 Li XianJing <xianjimli@hotmail.com> created
 30 *
 31 */
 32
 33#include "ftk_source.h"
 34#include "fbus_parcel.h"
 35#include "fbus_proxy.h"
 36#include "ftk_globals.h"
 37#include "ftk_main_loop.h"
 38#include "fbus_stream_socket.h"
 39#include "fbus_source_proxy.h"
 40#include "fbus_service_manager.h"
 41
 42struct _FBusProxy
 43{
 44	int busy;
 45	FBusParcel* parcel;
 46	FBusStream* stream;
 47	FtkSource* source;
 48	void* listener_ctx;
 49	FBusProxyListener listener;
 50};
 51
 52FBusProxy*  fbus_proxy_create(const char* service)
 53{
 54	Ret ret = RET_FAIL;
 55	FBusProxy* thiz = NULL;
 56	FBusStream* stream = NULL;
 57	FBusServiceInfo info = {0};
 58	
 59	return_val_if_fail(service != NULL, NULL);
 60
 61	if(strcmp(service, FBUS_SERVICE_MANAGER_NAME) != 0)
 62	{
 63		FBusServiceManager* service_manager = fbus_proxy_create(FBUS_SERVICE_MANAGER_NAME);
 64		if(service_manager != NULL)
 65		{
 66			ret = fbus_service_manager_start(service_manager, service);
 67			if(ret == RET_OK)
 68			{
 69				int i = 0;
 70				for(i = 0; i < 5; i++)
 71				{
 72					ret = fbus_service_manager_query(service_manager, service, &info);
 73					if(ret ==  RET_OK && info.status == FBUS_SERVICE_STARTED)
 74					{
 75						break;
 76					}
 77
 78					if(ret != RET_OK)
 79					{
 80						usleep(200000);
 81					}
 82				}
 83			}
 84			fbus_proxy_destroy(service_manager);
 85		}
 86	}
 87	else
 88	{
 89		strcpy(info.host, FBUS_LOCALHOST);
 90		info.port = FBUS_SERVICE_MANAGER_PORT;
 91	}
 92
 93	return_val_if_fail(info.port > 0, NULL);
 94
 95	stream = fbus_stream_socket_connect(info.host, info.port);
 96	return_val_if_fail(stream != NULL, NULL);
 97
 98	thiz = FTK_ZALLOC(sizeof(FBusProxy));
 99	if(thiz != NULL)
100	{
101		thiz->stream = stream;
102	}
103	else
104	{
105		fbus_stream_destroy(stream);
106	}
107
108	return thiz;
109}
110
111FBusParcel* fbus_proxy_get_parcel(FBusProxy* thiz)
112{
113	return_val_if_fail(thiz != NULL, NULL);
114
115	if(thiz->parcel == NULL)
116	{
117		thiz->parcel = fbus_parcel_create(256);
118	}
119	else
120	{
121		fbus_parcel_reset(thiz->parcel);
122	}
123
124	return thiz->parcel;
125}
126
127static Ret  fbus_proxy_send_request(FBusProxy* thiz, FBusParcel* parcel)
128{
129	int size = 0;
130	int ret = RET_FAIL;
131	return_val_if_fail(thiz != NULL && thiz->stream != NULL && parcel != NULL, RET_FAIL);
132
133	size = fbus_parcel_size(parcel);
134	ret = fbus_stream_write_n(thiz->stream, (const char*)&size, sizeof(size));
135	return_val_if_fail(ret == sizeof(size), RET_FAIL);
136
137	ret = fbus_stream_write_n(thiz->stream, fbus_parcel_data(parcel), size);
138	return_val_if_fail(ret == size, RET_FAIL);
139
140	return RET_OK;
141}
142
143static Ret  fbus_proxy_recv_response(FBusProxy* thiz, FBusParcel* parcel)
144{
145	int type = 0;
146	int trigger = 0;
147	int size = 0;
148	int ret = RET_FAIL;
149	return_val_if_fail(thiz != NULL && thiz->stream != NULL && parcel != NULL, RET_FAIL);
150
151	do
152	{
153		fbus_parcel_reset(parcel);
154		ret = fbus_stream_read_n(thiz->stream, (char*)&type, sizeof(type));
155		return_val_if_fail(ret == sizeof(type), RET_FAIL);
156		
157		if(type == FBUS_RESP_PUSH)
158		{
159			ret = fbus_stream_read_n(thiz->stream, (char*)&trigger, sizeof(trigger));
160			return_val_if_fail(ret == sizeof(trigger), RET_FAIL);
161		}
162		ret = fbus_stream_read_n(thiz->stream, (char*)&size, sizeof(size));
163		return_val_if_fail(ret == sizeof(size), RET_FAIL);
164		
165		fbus_parcel_extend(parcel, size);
166		fbus_parcel_set_size(parcel, size);
167		ret = fbus_stream_read_n(thiz->stream, fbus_parcel_data(parcel), size);
168		return_val_if_fail(ret == size, RET_FAIL);
169
170		if(type == FBUS_RESP_PUSH)
171		{
172			if(thiz->listener != NULL)
173			{
174				thiz->listener(thiz->listener_ctx, trigger, parcel);
175			}
176		}
177	}while(type != FBUS_RESP_NORMAL);
178	
179	return RET_OK;
180}
181
182Ret  fbus_proxy_set_notify_listener(FBusProxy* thiz, FBusProxyListener listener, void* ctx)
183{
184	return_val_if_fail(thiz != NULL, RET_FAIL);
185
186	thiz->listener = listener;
187	thiz->listener_ctx = ctx;
188	
189	if(thiz->source != NULL)
190	{
191		ftk_main_loop_remove_source(ftk_default_main_loop(), thiz->source);
192		thiz->source = NULL;
193	}
194
195	if(listener != NULL)
196	{
197		thiz->source = fbus_source_proxy_create(thiz, thiz->stream, listener, ctx);
198
199		if(thiz->source != NULL)
200		{
201			ftk_main_loop_add_source(ftk_default_main_loop(), thiz->source);
202		}
203	}
204
205	return RET_OK;
206}
207
208void fbus_proxy_destroy(FBusProxy* thiz)
209{
210	if(thiz != NULL)
211	{
212		if(thiz->source != NULL)
213		{
214			fbus_proxy_set_notify_listener(thiz, NULL, NULL);
215		}
216		fbus_stream_destroy(thiz->stream);
217		if(thiz->parcel != NULL)
218		{
219			fbus_parcel_destroy(thiz->parcel);
220		}
221
222		FTK_FREE(thiz);
223	}
224
225	return;
226}
227
228Ret fbus_proxy_request(FBusProxy* thiz, FBusParcel* req_resp)
229{
230	Ret ret = RET_FAIL;
231	return_val_if_fail(thiz != NULL && req_resp != NULL, RET_FAIL);
232	return_val_if_fail(thiz->busy == 0, RET_FAIL);
233
234	thiz->busy = 1;
235	if((ret = fbus_proxy_send_request(thiz, req_resp)) == RET_OK)
236	{
237		ret = fbus_proxy_recv_response(thiz, req_resp);
238	}
239	thiz->busy = 0;
240
241	return ret;
242}
243