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; }