/*************************************************************************************************************
* This file contains channel functions
* 2012/10 by Dlxko
* Version 4.0
**************************************************************************************************************/
#include "Channel.h"

// For getting packets lenght
static char char_packet_lenght[LENGHT_SIZE+1];
static int int_packet_lenght;

// For GIOchannel
static GIOStatus giostat;
static gsize read_size;
static gchar gio_buffer[BUF_SIZE];
static GIOChannel *gich;
static guint event_id;

// Function to receive data from channel
void function_receive_socket( GIOChannel   *channel, GIOCondition  cond)
{
	// Clean sock_buffer and read lenght datas
	memset(gio_buffer, 0, BUF_SIZE);
	giostat = g_io_channel_read_chars(gich, gio_buffer, LENGHT_SIZE, &read_size, NULL);

	// Check if receiving was successful
	if (giostat == G_IO_STATUS_ERROR)
	{
		function_show_warning (LANG_RECEIVE_DATA_ERROR);
		return;
	}

	// Look for correct read size
	if (read_size != LENGHT_SIZE)
		return;

	// Look if not empty
	if(strlen(gio_buffer) < 2)
		return;

	// Get lenght data
	memset(char_packet_lenght, 0, LENGHT_SIZE);
	function_midcopy(gio_buffer, char_packet_lenght, 0, LENGHT_SIZE);

	// Convert len to integer and defcrease size
	int_packet_lenght = function_convert_packet_lenght(char_packet_lenght);
	int_packet_lenght -= LENGHT_SIZE;

	// Clean sock_buffer and read other datas
	memset(gio_buffer, 0, BUF_SIZE);
	giostat = g_io_channel_read_chars(gich, gio_buffer, int_packet_lenght, &read_size, NULL);

	// Check if receiving was successful
	if (giostat == G_IO_STATUS_ERROR)
	{
		function_show_warning (LANG_RECEIVE_DATA_ERROR);
		return;
	}

	// Process packet
	function_process_packet(gio_buffer, int_packet_lenght);
}

// Create channel with watchdog
bool create_channel()
{
	// Get channel
	gich = g_io_channel_win32_new_socket (s);
	if (!gich)
	{
		function_show_error(LANG_XCREATE_CHANNEL);
		return false;
	}

	// Set encoding
	if(g_io_channel_set_encoding(gich, NULL, NULL) != G_IO_STATUS_NORMAL)
	{
		function_show_error(LANG_XSET_CHANNEL_CODING);
		return false;
	}

	// Set close on unref
	g_io_channel_set_close_on_unref(gich, TRUE);

	// Add watchdog
	event_id = g_io_add_watch_full( gich, 0, G_IO_IN, (GIOFunc)function_receive_socket, NULL, NULL );
	if (!event_id)
	{
		function_show_error(LANG_XCREATE_WATCHDOG);
		return false;
	}

	return true;
}