Exemplo n.º 1
0
int main (int argc, char* argv[])
{

	pthread_t thread_read_serial;

	printf("Starting application...\n");
	int i = open_device();
	printf("Serial port open %d\n", i);
	printf("=> Send device_status() : ");
	i = device_status();
	printf("%d\n", i);

	i = get_network_status();
	printf("Get network status sent\n");

	i = get_children_amount();
	printf("Get children amount sent\n");
	return 0;


	/* i = serial_write_byte('a'); */
	/* char temp; */
	/* unsigned char *ptr_tmp; */
	/* ptr_tmp = (unsigned char *) malloc(2*sizeof(unsigned char)); */
	/* *ptr_tmp = 0xEE; */
	/* *(ptr_tmp + 1) = 0xBB; */

	/* //data_from_network(); */
	/* char c[20]; */
	/* //serial_read_file(c, 1); */

	/*
	if (device_status() == 0)
		printf("Dispositivo presente\n");
	printf ("Direccion de red : %x\n", get_network_status());
	printf ("Nodos conectados : %d\n", get_children_amount());
	*/

	/* while(!(i = serial_read_byte(c, 1))); */


	/* //i = recv_data(); */

	/* printf("El valor de i : %d c %x\n", i, c[0]); */

	/* pthread_create(&thread_read_serial, NULL, serial_recv, NULL); */
	/* //serial_write_byte('A'); */
	/* //printf("Se escribio el byte\n"); */

	/* while (1) */
	/* 	sleep(1); */
	return 0;
}
void *run_manage_download_server(void *args)
{
	int listenfd = 0;	// main socket to be albe to listen the new connection
	int maxfd;
	int ret = 0;
	fd_set rset, exceptset;
	struct timeval timeout;
	long flexible_timeout;
	download_clientinfo_slot *clientinfo_list;
	int searchslot = 0;
	unsigned active_count = 0;
	download_clientinfo *request_clientinfo;
	int check_retry = 1;
	int i = 0;
	int is_timeout = 0;

	socklen_t clientlen;
	struct sockaddr_un listenaddr, clientaddr;

	GMainLoop *mainloop = (GMainLoop *) args;

	ret = _init_agent();
	if (ret != DOWNLOAD_ERROR_NONE) {
		TRACE_DEBUG_MSG("failed to init agent");
		TerminateDaemon(SIGTERM);
		return 0;
	}
	clear_downloadinginfo_appfw_notification();

	if ((listenfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
		TRACE_DEBUG_MSG("failed to create socket");
		TerminateDaemon(SIGTERM);
		return 0;
	}

	bzero(&listenaddr, sizeof(listenaddr));
	listenaddr.sun_family = AF_UNIX;
	strcpy(listenaddr.sun_path, DOWNLOAD_PROVIDER_IPC);

	if (bind(listenfd, (struct sockaddr *)&listenaddr, sizeof listenaddr) !=
		0) {
		TRACE_DEBUG_MSG("failed to call bind");
		TerminateDaemon(SIGTERM);
		return 0;
	}

	if (chmod(listenaddr.sun_path, 0777) < 0) {
		TRACE_DEBUG_MSG
			("failed to change the permission of socket file");
		TerminateDaemon(SIGTERM);
		return 0;
	}

	if (listen(listenfd, MAX_CLIENT) != 0) {
		TRACE_DEBUG_MSG("failed to call listen");
		TerminateDaemon(SIGTERM);
		return 0;
	}

	maxfd = listenfd;
	TRACE_DEBUG_INFO_MSG("Ready to listen IPC [%d][%s]", listenfd,
			DOWNLOAD_PROVIDER_IPC);

	// allocation the array structure for managing the clients.
	clientinfo_list =
		(download_clientinfo_slot *) calloc(MAX_CLIENT,
							sizeof(download_clientinfo_slot));
	if (clientinfo_list == NULL) {
		TRACE_DEBUG_MSG("failed to allocate the memory for client list");
		TerminateDaemon(SIGTERM);
		return 0;
	}

	if (pthread_attr_init(&g_download_provider_thread_attr) != 0) {
		TRACE_DEBUG_MSG("failed to call pthread_attr_init for client");
		TerminateDaemon(SIGTERM);
		return 0;
	}
	if (pthread_attr_setdetachstate(&g_download_provider_thread_attr,
									PTHREAD_CREATE_DETACHED) != 0) {
		TRACE_DEBUG_MSG("failed to set detach option");
		TerminateDaemon(SIGTERM);
		return 0;
	}

	flexible_timeout = DOWNLOAD_PROVIDER_CARE_CLIENT_MIN_INTERVAL;

	FD_ZERO(&g_download_provider_socket_readset);
	FD_ZERO(&g_download_provider_socket_exceptset);
	FD_SET(listenfd, &g_download_provider_socket_readset);
	FD_SET(listenfd, &g_download_provider_socket_exceptset);

	while (g_main_loop_is_running(mainloop)) {

		// clean slots
		for (i = 0; i < MAX_CLIENT; i++) {
			if (!clientinfo_list[i].clientinfo)
				continue;
			// clear slot.
			if (clientinfo_list[i].clientinfo->state >= DOWNLOAD_STATE_FINISHED) {
				if (clientinfo_list[i].clientinfo->clientfd <= 0)
					clear_clientinfoslot(&clientinfo_list[i]);
				continue;
			}
		}

		is_timeout = 1;
		rset = g_download_provider_socket_readset;
		exceptset = g_download_provider_socket_exceptset;

		memset(&timeout, 0x00, sizeof(struct timeval));
		timeout.tv_sec = flexible_timeout;

		if (select((maxfd + 1), &rset, 0, &exceptset, &timeout) < 0) {
			TRACE_DEBUG_MSG
				("select error, provider can't receive any request from client.");
			TerminateDaemon(SIGTERM);
			break;
		}

		for (i = 0; i < MAX_CLIENT; i++) {  // find the socket received the packet.
			if (!clientinfo_list[i].clientinfo)
				continue;
			//Even if no socket, downloading should be progressed.
			if (clientinfo_list[i].clientinfo->clientfd <= 0)
				continue;
			if (FD_ISSET(clientinfo_list[i].clientinfo->clientfd, &rset) > 0) {
				// ignore it is not started yet.
				if (clientinfo_list[i].clientinfo->state <= DOWNLOAD_STATE_READY)
					continue;
				TRACE_DEBUG_INFO_MSG("FD_ISSET [%d] readset slot[%d]",
					clientinfo_list[i].clientinfo->clientfd, i);
				_handle_client_request(clientinfo_list[i].clientinfo);
				if (is_timeout)
					is_timeout = 0;
			} else if (FD_ISSET(clientinfo_list[i].clientinfo->clientfd, &exceptset) > 0) {
				TRACE_DEBUG_MSG("FD_ISSET [%d] exceptset slot[%d]", clientinfo_list[i].clientinfo->clientfd, i);
				clear_clientinfoslot(&clientinfo_list[i]);
			}
		} // MAX_CLIENT

		if (FD_ISSET(listenfd, &exceptset) > 0) {
			TRACE_DEBUG_MSG("meet listenfd Exception of socket");
			TerminateDaemon(SIGTERM);
			break;
		} else if (FD_ISSET(listenfd, &rset) > 0) { // new connection
			TRACE_DEBUG_INFO_MSG("FD_ISSET listenfd rset");
			if (is_timeout)
				is_timeout = 0;
			// reset timeout.
			flexible_timeout =
				DOWNLOAD_PROVIDER_CARE_CLIENT_MIN_INTERVAL;
			// ready the buffer.
			request_clientinfo =
				(download_clientinfo *) calloc(1,
							sizeof(download_clientinfo));
			if (!request_clientinfo) {
				TRACE_DEBUG_MSG
					("download-provider can't allocate the memory, try later");
				clientlen = sizeof(clientaddr);
				int clientfd = accept(listenfd,
					(struct sockaddr *)&clientaddr, &clientlen);
				close(clientfd);	// disconnect.
				sleep(5);	// provider need the time of refresh.
				continue;
			}
			// accept client.
			clientlen = sizeof(clientaddr);
			request_clientinfo->clientfd = accept(listenfd,
								(struct sockaddr*)&clientaddr,
								&clientlen);
			if (request_clientinfo->clientfd < 0) {
				clear_clientinfo(request_clientinfo);
				sleep(5);	// provider need the time of refresh.
				continue;
			}
			if (_handle_new_connection(clientinfo_list, request_clientinfo) < 0) {
				sleep(1);
				continue;
			}
			// after starting the download by DA, event thread will start to get the event from client.
			if (request_clientinfo && request_clientinfo->clientfd > 0) {
				FD_SET(request_clientinfo->clientfd, &g_download_provider_socket_readset);	// add new descriptor to set
				FD_SET(request_clientinfo->clientfd, &g_download_provider_socket_exceptset);
				if (request_clientinfo->clientfd > maxfd )
					maxfd = request_clientinfo->clientfd;	/* for select */
			}
		}

		if (is_timeout) { // timeout
			// If there is better solution to be able to know
			// the number of downloading threads, replace below rough codes.
			active_count = get_downloading_count(clientinfo_list);
			// check whether the number of downloading is already maximum.
			if (active_count >= DA_MAX_DOWNLOAD_REQ_AT_ONCE)
				continue;

			unsigned free_slot_count
					= DA_MAX_DOWNLOAD_REQ_AT_ONCE - active_count;
			int pendedslot = get_pended_slot_index(clientinfo_list);
			if(pendedslot >= 0) {
				TRACE_DEBUG_INFO_MSG ("Free Space [%d]", free_slot_count);
				for (;free_slot_count > 0 && pendedslot >= 0; free_slot_count--) {
					TRACE_DEBUG_INFO_MSG ("start pended job [%d]", pendedslot);
					if (_create_download_thread(&clientinfo_list[pendedslot]) > 0)
						active_count++;
					pendedslot = get_pended_slot_index(clientinfo_list);
				}
			}

			if (check_retry && free_slot_count > 0) {
				// Auto re-download feature. 
				// ethernet may be connected with other downloading items.
				if (get_network_status() < 0)
					continue;

				// check auto-retrying list regardless state. pended state is also included to checking list.
				int i = 0;
				download_dbinfo_list *db_list =
					download_provider_db_get_list(DOWNLOAD_STATE_NONE);
				if (!db_list || db_list->count <= 0) {
					TRACE_DEBUG_INFO_MSG
						("provider does not need to check DB anymore. in this life.");
					// provider does not need to check DB anymore. in this life.
					check_retry = 0;
					if (db_list)
						download_provider_db_list_free(db_list);
					continue;
				}
				for (i = 0;
					active_count <
					DA_MAX_DOWNLOAD_REQ_AT_ONCE
					&& i < db_list->count; i++) {
					if (db_list->item[i].requestid <= 0)
						continue;
					if (get_same_request_slot_index
						(clientinfo_list,db_list->item[i].requestid) < 0) {
						// not found requestid in memory
						TRACE_DEBUG_INFO_MSG
							("Retry download [%d]",
							db_list->item[i].requestid);
						//search empty slot. copy db info to slot.
						searchslot =
							get_empty_slot_index(clientinfo_list);
						if (searchslot < 0) {
							TRACE_DEBUG_INFO_MSG
								("download-provider is busy, try later");
							flexible_timeout =
								flexible_timeout * 2;
							break;
						}
						// allocte requestinfo to empty slot.
						request_clientinfo =
							(download_clientinfo *)
							calloc(1, sizeof(download_clientinfo));
						if (!request_clientinfo)
							continue;
						request_clientinfo->requestinfo
							=
							download_provider_db_get_requestinfo
							(&db_list->item[i]);
						if (!request_clientinfo->requestinfo) {
							free(request_clientinfo);
							request_clientinfo = NULL;
							continue;
						}

						CLIENT_MUTEX_INIT(&(request_clientinfo->client_mutex), NULL);
						request_clientinfo->state = DOWNLOAD_STATE_READY;
						clientinfo_list[searchslot].clientinfo =
							request_clientinfo;

						TRACE_DEBUG_INFO_MSG
							("Retry download [%d/%d][%d/%d]",
							searchslot, MAX_CLIENT,
							active_count,
							DA_MAX_DOWNLOAD_REQ_AT_ONCE);
						if (_create_download_thread(&clientinfo_list[searchslot]) > 0)
							active_count++;
					}
				}
				if (i >= db_list->count)	// do not search anymore.
					check_retry = 0;
				download_provider_db_list_free(db_list);
			}

			// save system resource (CPU)
			if (check_retry == 0 && active_count == 0
				&& flexible_timeout <
				DOWNLOAD_PROVIDER_CARE_CLIENT_MAX_INTERVAL)
				flexible_timeout = flexible_timeout * 2;
			if (flexible_timeout >
				DOWNLOAD_PROVIDER_CARE_CLIENT_MAX_INTERVAL)
				flexible_timeout =
					DOWNLOAD_PROVIDER_CARE_CLIENT_MAX_INTERVAL;
			TRACE_DEBUG_INFO_MSG("Next Timeout after [%ld] sec",
					flexible_timeout);

		} // if (i >= MAX_CLIENT) { // timeout
	}

	FD_CLR(listenfd, &rset);
	FD_CLR(listenfd, &exceptset);
	FD_CLR(listenfd, &g_download_provider_socket_readset);
	FD_CLR(listenfd, &g_download_provider_socket_exceptset);

	// close accept socket.
	if (listenfd)
		close(listenfd);

	_deinit_agent();

	// close all sockets for client. .. 
	// client thread will terminate by itself through catching this closing.
	for (searchslot = 0; searchslot < MAX_CLIENT; searchslot++)
		if (clientinfo_list[searchslot].clientinfo)
			clear_clientinfoslot(&clientinfo_list[searchslot]);

	if (clientinfo_list)
		free(clientinfo_list);

	pthread_exit(NULL);
	return 0;
}