Scheduled maintenance on Saturday, 27 September 2025, from 07:00 AM to 4:00 PM GMT (09:00 AM to 6:00 PM CEST) - some services may be unavailable -

Skip to content
Snippets Groups Projects
pathComp_RESTapi.c 75.2 KiB
Newer Older
  • Learn to ignore specific revisions
  • 		// Stop all the operations over that PATH COMP client bound channel
    		struct pathComp_client *pathComp_client = NULL;
    		gint fd = g_io_channel_unix_get_fd (source);
    		GList *found = g_list_find_custom (RESTapi_tcp_client_list, &fd, find_rl_client_by_fd);
    
    Ricardo Martínez's avatar
    Ricardo Martínez committed
    		if (found != NULL) 	{
    
    			pathComp_client = (struct pathComp_client*)(found->data);
    			// remove client
    			RESTapi_client_close(pathComp_client);
    			// Stop operations over that channel
    			RESTapi_close_operations(source);
    			close (fd);
    			return FALSE;
    		}		
    	}
    
    Ricardo Martínez's avatar
    Ricardo Martínez committed
    	if (cond == G_IO_IN) 	{
    
    		gint new = accept(g_io_channel_unix_get_fd(source), (struct sockaddr*)&client_addr, &client);
    
    Ricardo Martínez's avatar
    Ricardo Martínez committed
    		if (new < 0) {
    
    			//DEBUG_PC ("Unable to accept new connection");
    			return FALSE;
    		}
    
    
    Ricardo Martínez's avatar
    Ricardo Martínez committed
    		// new channel
    
    		GIOChannel * new_channel = g_io_channel_unix_new (new);		
    		//DEBUG_PC ("TCP Connection (REST API) is UP; (socket: %d)", new);
    
    Ricardo Martínez's avatar
    Ricardo Martínez committed
    		// create pathComp client		
    
    		struct pathComp_client *new_client = RESTapi_client_create (new_channel, new);
    		
    
    Ricardo Martínez's avatar
    Ricardo Martínez committed
    		// force binary encoding with NULL
    
    Ricardo Martínez's avatar
    Ricardo Martínez committed
    		if ( g_io_channel_set_encoding (new_channel, NULL, &error) != G_IO_STATUS_NORMAL) {		
    
    			DEBUG_PC ("Error: %s", error->message);
    			exit (-1);
    		}
    		g_io_channel_set_close_on_unref (new_channel, TRUE);
    		// On unbuffered channels, it is safe to mix read
    		// & write calls from the new and old APIs.
    		g_io_channel_set_buffered (new_channel, FALSE);
    
    Ricardo Martínez's avatar
    Ricardo Martínez committed
    		if (g_io_channel_set_flags (new_channel, G_IO_FLAG_NONBLOCK, &error) != G_IO_STATUS_NORMAL ) {
    
    			DEBUG_PC ("Error: %s", error->message);
    			exit (-1);
    		}
    		//Adds the new channel into the main event loop.
    		g_io_add_watch (new_channel, G_IO_IN, RESTapi_activity, new_client);
        }	
    	return TRUE;
    }
    
    ///////////////////////////////////////////////////////////////////////////////////////
    /**
     * 	@file pathComp_RESTapi.c
     * 	@brief enabling the reuse of the addr for the Server TCP
     * 	
     * 	@param sock
     *
     *	@author Ricardo Martínez <ricardo.martinez@cttc.es>
     *	@date 2022
     */
    /////////////////////////////////////////////////////////////////////////////////////////
    void RESTapi_tcp_enable_reuseaddr (gint sock)
    {
    	gint tmp = 1;
    	if (sock < 0)
    	{
    		DEBUG_PC (" socket: %d !!!",sock);
    		exit (-1);
    	}
    	if (setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, (gchar *)&tmp, sizeof (tmp)) == -1)
    	{
    		DEBUG_PC ("bad setsockopt ...");
    		exit (-1);
    	}
    	return;
    }
    
    ////////////////////////////////////////////////////////////////////////////////////////
    /**
     * 	@file pathComp_RESTapi.c
     * 	@brief Main function for the creating / maintaining TCP session for the REST API
     *
     *  @ port 
     * 
     *	@author Ricardo Martínez <ricardo.martinez@cttc.es>
     *	@date 2022
     */
    /////////////////////////////////////////////////////////////////////////////////////////
    void RESTapi_init(gint port)
    {     
        DEBUG_PC ("REST API PORT (listening): %d", port);     
    	
    	// File Descriptor - FD - for the socket
    	gint s = socket (AF_INET, SOCK_STREAM, 0);
    	if (s == -1)
    	{
    		DEBUG_PC ("Socket creation: FAILED!!");
    		exit (-1);
    	}
    	DEBUG_PC (" CREATED TCP Connection [@fd: %d]", s);
    
    	// Re-bind
    	RESTapi_tcp_enable_reuseaddr(s);	
    	struct sockaddr_in addr;
    	memset (&addr, 0, sizeof (addr));
    	addr.sin_family       = AF_INET;
    	addr.sin_port         = htons ((u_short)port);
    	addr.sin_addr.s_addr  = INADDR_ANY;      
    
    	// Associate IP address and Port to the created socket
    	if (bind (s, (struct sockaddr *)&addr, sizeof(addr)) == -1)
    	{
    		close (s);
    		DEBUG_PC ("Socket bind: FAILED!!");
    		exit (-1);
    	}
    	DEBUG_PC ("Bind to Fd: %d DONE!!", s);
    
    	/** Set up queue for incoming connections */
    	if (listen (s, 10) == -1)
    	{
    		close (s);
    		DEBUG_PC ("Socket listen: FAILED!!");
    		exit (-1);
    	}
    	
    	//DEBUG_PC ("Listen (up to 10) to Fd: %d Done", s);
    
    	/** Create NEW channel to handle the socket operations*/
    	GIOChannel *channel = g_io_channel_unix_new (s);
    	gsize buffersize = g_io_channel_get_buffer_size (channel);
    	//DEBUG_PC ("GIOChannel with Buffer Size: %d", (gint)buffersize);
    
    	gsize newBufferSize = MAX_GIO_CHANNEL_BUFFER_SIZE;
    	g_io_channel_set_buffer_size (channel, newBufferSize);
    	buffersize = g_io_channel_get_buffer_size (channel);
    
    	//DEBUG_PC ("GIOChannel with Buffer Size: %d", (gint)buffersize);
    	//DEBUG_PC ("Channel associated to fd: %d is created", s);
    	
    	// Adds the new channel into the main event loop.
    	g_io_add_watch (channel, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL, RESTapi_tcp_new_connection, NULL);
    	return;     
    }