/* channel.c generated by valac 0.16.1, the Vala compiler
 * generated from channel.vala, do not modify */

/*
 * This file is part of libgsm0710mux
 *
 * (C) 2009-2012 Michael 'Mickey' Lauer <mlauer@vanille-media.de>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
 *
 */
/*===========================================================================*/

#include <glib.h>
#include <glib-object.h>
#include <fsotransport.h>
#include <fsobasics.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <gsm/gsm0710.h>
#include <gobject/gvaluecollector.h>


#define TYPE_CHANNEL (channel_get_type ())
#define CHANNEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_CHANNEL, Channel))
#define CHANNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_CHANNEL, ChannelClass))
#define IS_CHANNEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_CHANNEL))
#define IS_CHANNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_CHANNEL))
#define CHANNEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_CHANNEL, ChannelClass))

typedef struct _Channel Channel;
typedef struct _ChannelClass ChannelClass;
typedef struct _ChannelPrivate ChannelPrivate;

#define TYPE_MULTIPLEXER (multiplexer_get_type ())
#define MULTIPLEXER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_MULTIPLEXER, Multiplexer))
#define MULTIPLEXER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_MULTIPLEXER, MultiplexerClass))
#define IS_MULTIPLEXER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_MULTIPLEXER))
#define IS_MULTIPLEXER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_MULTIPLEXER))
#define MULTIPLEXER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_MULTIPLEXER, MultiplexerClass))

typedef struct _Multiplexer Multiplexer;
typedef struct _MultiplexerClass MultiplexerClass;

#define CHANNEL_TYPE_STATUS (channel_status_get_type ())
#define _multiplexer_unref0(var) ((var == NULL) ? NULL : (var = (multiplexer_unref (var), NULL)))
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
#define _g_free0(var) (var = (g_free (var), NULL))

#define GSM0710MUX_TYPE_CHANNEL_INFO (gsm0710mux_channel_info_get_type ())
#define GSM0710MUX_CHANNEL_INFO(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GSM0710MUX_TYPE_CHANNEL_INFO, Gsm0710muxChannelInfo))
#define GSM0710MUX_CHANNEL_INFO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GSM0710MUX_TYPE_CHANNEL_INFO, Gsm0710muxChannelInfoClass))
#define GSM0710MUX_IS_CHANNEL_INFO(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GSM0710MUX_TYPE_CHANNEL_INFO))
#define GSM0710MUX_IS_CHANNEL_INFO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GSM0710MUX_TYPE_CHANNEL_INFO))
#define GSM0710MUX_CHANNEL_INFO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GSM0710MUX_TYPE_CHANNEL_INFO, Gsm0710muxChannelInfoClass))

typedef struct _Gsm0710muxChannelInfo Gsm0710muxChannelInfo;
typedef struct _Gsm0710muxChannelInfoClass Gsm0710muxChannelInfoClass;
typedef struct _Gsm0710muxChannelInfoPrivate Gsm0710muxChannelInfoPrivate;
typedef struct _ParamSpecChannel ParamSpecChannel;

struct _Channel {
	GTypeInstance parent_instance;
	volatile int ref_count;
	ChannelPrivate * priv;
};

struct _ChannelClass {
	GTypeClass parent_class;
	void (*finalize) (Channel *self);
};

typedef enum  {
	CHANNEL_STATUS_Requested,
	CHANNEL_STATUS_Acked,
	CHANNEL_STATUS_Open,
	CHANNEL_STATUS_Denied,
	CHANNEL_STATUS_Shutdown
} ChannelStatus;

struct _ChannelPrivate {
	Multiplexer* _multiplexer;
	ChannelStatus _status;
	FsoFrameworkTransport* transport;
	FsoFrameworkLogger* logger;
	gchar* _name;
	gint _number;
	gint _serial_status;
	GSourceFunc ackCallback;
	gpointer ackCallback_target;
	GDestroyNotify ackCallback_target_destroy_notify;
	guint ackTimeoutWatch;
};

struct _Gsm0710muxChannelInfo {
	GTypeInstance parent_instance;
	volatile int ref_count;
	Gsm0710muxChannelInfoPrivate * priv;
	gchar* consumer;
	gint number;
	FsoFrameworkTransport* transport;
};

struct _Gsm0710muxChannelInfoClass {
	GTypeClass parent_class;
	void (*finalize) (Gsm0710muxChannelInfo *self);
};

struct _ParamSpecChannel {
	GParamSpec parent_instance;
};


static gpointer channel_parent_class = NULL;
extern gboolean gsm0710mux_manager_leave_fc_alone;

gpointer channel_ref (gpointer instance);
void channel_unref (gpointer instance);
GParamSpec* param_spec_channel (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags);
void value_set_channel (GValue* value, gpointer v_object);
void value_take_channel (GValue* value, gpointer v_object);
gpointer value_get_channel (const GValue* value);
GType channel_get_type (void) G_GNUC_CONST;
gpointer multiplexer_ref (gpointer instance);
void multiplexer_unref (gpointer instance);
GParamSpec* param_spec_multiplexer (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags);
void value_set_multiplexer (GValue* value, gpointer v_object);
void value_take_multiplexer (GValue* value, gpointer v_object);
gpointer value_get_multiplexer (const GValue* value);
GType multiplexer_get_type (void) G_GNUC_CONST;
GType channel_status_get_type (void) G_GNUC_CONST;
#define CHANNEL_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TYPE_CHANNEL, ChannelPrivate))
enum  {
	CHANNEL_DUMMY_PROPERTY
};
gpointer gsm0710mux_channel_info_ref (gpointer instance);
void gsm0710mux_channel_info_unref (gpointer instance);
GParamSpec* gsm0710mux_param_spec_channel_info (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags);
void gsm0710mux_value_set_channel_info (GValue* value, gpointer v_object);
void gsm0710mux_value_take_channel_info (GValue* value, gpointer v_object);
gpointer gsm0710mux_value_get_channel_info (const GValue* value);
GType gsm0710mux_channel_info_get_type (void) G_GNUC_CONST;
Channel* channel_new (Multiplexer* multiplexer, Gsm0710muxChannelInfo* info, GSourceFunc ackCallback, void* ackCallback_target, guint ackTimeout);
Channel* channel_construct (GType object_type, Multiplexer* multiplexer, Gsm0710muxChannelInfo* info, GSourceFunc ackCallback, void* ackCallback_target, guint ackTimeout);
#define CONST_LIBGSM0710MUX_CONFIG_SECTION "libgsm0710mux"
#define CONST_LIBGSM0710MUX_LOGGING_DOMAIN "libgsm0710mux"
gchar* channel_repr (Channel* self);
static gchar* _channel_repr_repr_delegate (gpointer self);
#define CONST_TRANSPORT_READ_PRIORITY (-20)
#define CONST_TRANSPORT_WRITE_PRIORITY 0
void channel_onRead (Channel* self, FsoFrameworkTransport* transport);
static void _channel_onRead_fso_framework_transport_func (FsoFrameworkTransport* transport, gpointer self);
void channel_onHup (Channel* self, FsoFrameworkTransport* transport);
static void _channel_onHup_fso_framework_transport_func (FsoFrameworkTransport* transport, gpointer self);
gchar* channel_acked (Channel* self);
static gboolean ___lambda2_ (Channel* self);
static gboolean ____lambda2__gsource_func (gpointer self);
void channel_close (Channel* self);
void multiplexer_channel_closed (Multiplexer* self, gint channel);
void multiplexer_remove_channel (Multiplexer* self, gint channel);
gchar* channel_name (Channel* self);
gchar* channel_path (Channel* self);
gboolean channel_isAcked (Channel* self);
void channel_setSerialStatus (Channel* self, gint newstatus);
void channel_deliverData (Channel* self, void* data, gint len);
void multiplexer_submit_data (Multiplexer* self, gint channel, void* data, gint len);
static void channel_finalize (Channel* obj);


GType channel_status_get_type (void) {
	static volatile gsize channel_status_type_id__volatile = 0;
	if (g_once_init_enter (&channel_status_type_id__volatile)) {
		static const GEnumValue values[] = {{CHANNEL_STATUS_Requested, "CHANNEL_STATUS_Requested", "requested"}, {CHANNEL_STATUS_Acked, "CHANNEL_STATUS_Acked", "acked"}, {CHANNEL_STATUS_Open, "CHANNEL_STATUS_Open", "open"}, {CHANNEL_STATUS_Denied, "CHANNEL_STATUS_Denied", "denied"}, {CHANNEL_STATUS_Shutdown, "CHANNEL_STATUS_Shutdown", "shutdown"}, {0, NULL, NULL}};
		GType channel_status_type_id;
		channel_status_type_id = g_enum_register_static ("ChannelStatus", values);
		g_once_init_leave (&channel_status_type_id__volatile, channel_status_type_id);
	}
	return channel_status_type_id__volatile;
}


static gchar* _channel_repr_repr_delegate (gpointer self) {
	gchar* result;
	result = channel_repr (self);
	return result;
}


static gpointer _multiplexer_ref0 (gpointer self) {
	return self ? multiplexer_ref (self) : NULL;
}


static gpointer _g_object_ref0 (gpointer self) {
	return self ? g_object_ref (self) : NULL;
}


static void _channel_onRead_fso_framework_transport_func (FsoFrameworkTransport* transport, gpointer self) {
	channel_onRead (self, transport);
}


static void _channel_onHup_fso_framework_transport_func (FsoFrameworkTransport* transport, gpointer self) {
	channel_onHup (self, transport);
}


Channel* channel_construct (GType object_type, Multiplexer* multiplexer, Gsm0710muxChannelInfo* info, GSourceFunc ackCallback, void* ackCallback_target, guint ackTimeout) {
	Channel* self = NULL;
	FsoFrameworkSmartKeyFile* _tmp0_;
	FsoFrameworkLogger* _tmp1_ = NULL;
	FsoFrameworkLogger* _tmp2_;
	Multiplexer* _tmp3_;
	Multiplexer* _tmp4_;
	Gsm0710muxChannelInfo* _tmp5_;
	const gchar* _tmp6_;
	gchar* _tmp7_;
	Gsm0710muxChannelInfo* _tmp8_;
	gint _tmp9_;
	Gsm0710muxChannelInfo* _tmp10_;
	FsoFrameworkTransport* _tmp11_;
	FsoFrameworkTransport* _tmp12_;
	FsoFrameworkTransport* _tmp13_;
	FsoFrameworkTransport* _tmp14_;
	FsoFrameworkLogger* _tmp15_;
	gboolean _tmp16_ = FALSE;
	guint _tmp17_;
	GSourceFunc _tmp21_;
	void* _tmp21__target;
	g_return_val_if_fail (info != NULL, NULL);
	self = (Channel*) g_type_create_instance (object_type);
	_tmp0_ = fso_framework_theConfig;
	_tmp1_ = fso_framework_logger_createFromKeyFile (_tmp0_, CONST_LIBGSM0710MUX_CONFIG_SECTION, CONST_LIBGSM0710MUX_LOGGING_DOMAIN);
	_g_object_unref0 (self->priv->logger);
	self->priv->logger = _tmp1_;
	_tmp2_ = self->priv->logger;
	fso_framework_logger_setReprDelegate (_tmp2_, _channel_repr_repr_delegate, self);
	_tmp3_ = multiplexer;
	_tmp4_ = _multiplexer_ref0 (_tmp3_);
	_multiplexer_unref0 (self->priv->_multiplexer);
	self->priv->_multiplexer = _tmp4_;
	self->priv->_status = CHANNEL_STATUS_Requested;
	_tmp5_ = info;
	_tmp6_ = _tmp5_->consumer;
	_tmp7_ = g_strdup (_tmp6_);
	_g_free0 (self->priv->_name);
	self->priv->_name = _tmp7_;
	_tmp8_ = info;
	_tmp9_ = _tmp8_->number;
	self->priv->_number = _tmp9_;
	_tmp10_ = info;
	_tmp11_ = _tmp10_->transport;
	_tmp12_ = _g_object_ref0 (_tmp11_);
	_g_object_unref0 (self->priv->transport);
	self->priv->transport = _tmp12_;
	_tmp13_ = self->priv->transport;
	fso_framework_transport_setPriorities (_tmp13_, CONST_TRANSPORT_READ_PRIORITY, CONST_TRANSPORT_WRITE_PRIORITY);
	_tmp14_ = self->priv->transport;
	fso_framework_transport_setDelegates (_tmp14_, _channel_onRead_fso_framework_transport_func, self, _channel_onHup_fso_framework_transport_func, self);
	_tmp15_ = self->priv->logger;
	_tmp16_ = fso_framework_logger_debug (_tmp15_, "Constructed");
	g_assert (_tmp16_);
	_tmp17_ = ackTimeout;
	if (_tmp17_ > ((guint) 0)) {
		guint _tmp18_;
		GSourceFunc _tmp19_;
		void* _tmp19__target;
		guint _tmp20_ = 0U;
		_tmp18_ = ackTimeout;
		_tmp19_ = ackCallback;
		_tmp19__target = ackCallback_target;
		_tmp20_ = g_timeout_add_seconds_full (G_PRIORITY_DEFAULT, _tmp18_, _tmp19_, _tmp19__target, NULL);
		self->priv->ackTimeoutWatch = _tmp20_;
	}
	_tmp21_ = ackCallback;
	_tmp21__target = ackCallback_target;
	(self->priv->ackCallback_target_destroy_notify == NULL) ? NULL : (self->priv->ackCallback_target_destroy_notify (self->priv->ackCallback_target), NULL);
	self->priv->ackCallback = NULL;
	self->priv->ackCallback_target = NULL;
	self->priv->ackCallback_target_destroy_notify = NULL;
	self->priv->ackCallback = _tmp21_;
	self->priv->ackCallback_target = _tmp21__target;
	self->priv->ackCallback_target_destroy_notify = NULL;
	return self;
}


Channel* channel_new (Multiplexer* multiplexer, Gsm0710muxChannelInfo* info, GSourceFunc ackCallback, void* ackCallback_target, guint ackTimeout) {
	return channel_construct (TYPE_CHANNEL, multiplexer, info, ackCallback, ackCallback_target, ackTimeout);
}


gchar* channel_repr (Channel* self) {
	gchar* result = NULL;
	gchar* _tmp0_ = NULL;
	FsoFrameworkTransport* _tmp1_;
	gint _tmp5_;
	const gchar* _tmp6_;
	const gchar* _tmp7_;
	gchar* _tmp8_ = NULL;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp1_ = self->priv->transport;
	if (_tmp1_ != NULL) {
		FsoFrameworkTransport* _tmp2_;
		gchar* _tmp3_ = NULL;
		_tmp2_ = self->priv->transport;
		_tmp3_ = fso_framework_transport_getName (_tmp2_);
		_g_free0 (_tmp0_);
		_tmp0_ = _tmp3_;
	} else {
		gchar* _tmp4_;
		_tmp4_ = g_strdup ("(none)");
		_g_free0 (_tmp0_);
		_tmp0_ = _tmp4_;
	}
	_tmp5_ = self->priv->_number;
	_tmp6_ = self->priv->_name;
	_tmp7_ = _tmp0_;
	_tmp8_ = g_strdup_printf ("<%d (%s) connected via %s>", _tmp5_, _tmp6_, _tmp7_);
	result = _tmp8_;
	_g_free0 (_tmp0_);
	return result;
}


static gboolean ___lambda2_ (Channel* self) {
	gboolean result = FALSE;
	GSourceFunc _tmp0_;
	void* _tmp0__target;
	_tmp0_ = self->priv->ackCallback;
	_tmp0__target = self->priv->ackCallback_target;
	_tmp0_ (_tmp0__target);
	result = FALSE;
	return result;
}


static gboolean ____lambda2__gsource_func (gpointer self) {
	gboolean result;
	result = ___lambda2_ (self);
	return result;
}


gchar* channel_acked (Channel* self) {
	gchar* result = NULL;
	guint _tmp0_;
	FsoFrameworkLogger* _tmp2_;
	gboolean _tmp3_ = FALSE;
	FsoFrameworkTransport* _tmp4_;
	gboolean _tmp5_ = FALSE;
	GSourceFunc _tmp12_;
	void* _tmp12__target;
	FsoFrameworkTransport* _tmp17_;
	gchar* _tmp18_ = NULL;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->ackTimeoutWatch;
	if (_tmp0_ > ((guint) 0)) {
		guint _tmp1_;
		_tmp1_ = self->priv->ackTimeoutWatch;
		g_source_remove (_tmp1_);
	}
	_tmp2_ = self->priv->logger;
	_tmp3_ = fso_framework_logger_debug (_tmp2_, "Acked");
	g_assert (_tmp3_);
	_tmp4_ = self->priv->transport;
	_tmp5_ = fso_framework_transport_open (_tmp4_);
	if (!_tmp5_) {
		FsoFrameworkLogger* _tmp6_;
		gint _tmp7_;
		const gchar* _tmp8_ = NULL;
		gchar* _tmp9_ = NULL;
		gchar* _tmp10_;
		gchar* _tmp11_;
		_tmp6_ = self->priv->logger;
		_tmp7_ = errno;
		_tmp8_ = strerror (_tmp7_);
		_tmp9_ = g_strdup_printf ("Could not open transport: %s", _tmp8_);
		_tmp10_ = _tmp9_;
		fso_framework_logger_error (_tmp6_, _tmp10_);
		_g_free0 (_tmp10_);
		_tmp11_ = g_strdup ("");
		result = _tmp11_;
		return result;
	}
	self->priv->_status = CHANNEL_STATUS_Acked;
	_tmp12_ = self->priv->ackCallback;
	_tmp12__target = self->priv->ackCallback_target;
	if (_tmp12_ != NULL) {
		FsoFrameworkLogger* _tmp13_;
		gboolean _tmp14_ = FALSE;
		_tmp13_ = self->priv->logger;
		_tmp14_ = fso_framework_logger_debug (_tmp13_, "AckCallback is set, calling");
		g_assert (_tmp14_);
		g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, ____lambda2__gsource_func, channel_ref (self), channel_unref);
	} else {
		FsoFrameworkLogger* _tmp15_;
		gboolean _tmp16_ = FALSE;
		_tmp15_ = self->priv->logger;
		_tmp16_ = fso_framework_logger_debug (_tmp15_, "AckCallback NOT set");
		g_assert (_tmp16_);
	}
	_tmp17_ = self->priv->transport;
	_tmp18_ = fso_framework_transport_getName (_tmp17_);
	result = _tmp18_;
	return result;
}


void channel_close (Channel* self) {
	FsoFrameworkLogger* _tmp0_;
	gboolean _tmp1_ = FALSE;
	ChannelStatus _tmp2_;
	ChannelStatus oldstatus;
	ChannelStatus _tmp3_;
	FsoFrameworkTransport* _tmp7_;
	Multiplexer* _tmp9_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->logger;
	_tmp1_ = fso_framework_logger_debug (_tmp0_, "Closing");
	g_assert (_tmp1_);
	_tmp2_ = self->priv->_status;
	oldstatus = _tmp2_;
	self->priv->_status = CHANNEL_STATUS_Shutdown;
	_tmp3_ = oldstatus;
	if (_tmp3_ != CHANNEL_STATUS_Requested) {
		Multiplexer* _tmp4_;
		_tmp4_ = self->priv->_multiplexer;
		if (_tmp4_ != NULL) {
			Multiplexer* _tmp5_;
			gint _tmp6_;
			_tmp5_ = self->priv->_multiplexer;
			_tmp6_ = self->priv->_number;
			multiplexer_channel_closed (_tmp5_, _tmp6_);
		}
	}
	_tmp7_ = self->priv->transport;
	if (_tmp7_ != NULL) {
		FsoFrameworkTransport* _tmp8_;
		_tmp8_ = self->priv->transport;
		fso_framework_transport_close (_tmp8_);
		_g_object_unref0 (self->priv->transport);
		self->priv->transport = NULL;
	}
	_tmp9_ = self->priv->_multiplexer;
	if (_tmp9_ != NULL) {
		Multiplexer* _tmp10_;
		gint _tmp11_;
		_tmp10_ = self->priv->_multiplexer;
		_tmp11_ = self->priv->_number;
		multiplexer_remove_channel (_tmp10_, _tmp11_);
	}
}


gchar* channel_name (Channel* self) {
	gchar* result = NULL;
	const gchar* _tmp0_;
	gchar* _tmp1_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->_name;
	_tmp1_ = g_strdup (_tmp0_);
	result = _tmp1_;
	return result;
}


gchar* channel_path (Channel* self) {
	gchar* result = NULL;
	FsoFrameworkTransport* _tmp0_;
	gchar* _tmp1_ = NULL;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->transport;
	_tmp1_ = fso_framework_transport_getName (_tmp0_);
	result = _tmp1_;
	return result;
}


gboolean channel_isAcked (Channel* self) {
	gboolean result = FALSE;
	ChannelStatus _tmp0_;
	g_return_val_if_fail (self != NULL, FALSE);
	_tmp0_ = self->priv->_status;
	result = _tmp0_ != CHANNEL_STATUS_Requested;
	return result;
}


void channel_setSerialStatus (Channel* self, gint newstatus) {
	FsoFrameworkLogger* _tmp0_;
	gboolean _tmp1_ = FALSE;
	gint _tmp2_;
	gint oldstatus;
	gint _tmp3_;
	gboolean _tmp4_;
	gboolean _tmp5_ = FALSE;
	gint _tmp6_;
	gboolean _tmp8_;
	gboolean _tmp11_ = FALSE;
	gint _tmp12_;
	gboolean _tmp14_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->logger;
	_tmp1_ = fso_framework_logger_debug (_tmp0_, "setSerialStatus()");
	g_assert (_tmp1_);
	_tmp2_ = self->priv->_serial_status;
	oldstatus = _tmp2_;
	_tmp3_ = newstatus;
	self->priv->_serial_status = _tmp3_;
	_tmp4_ = gsm0710mux_manager_leave_fc_alone;
	if (_tmp4_) {
		return;
	}
	_tmp6_ = oldstatus;
	if ((_tmp6_ & GSM0710_FC) == 0) {
		gint _tmp7_;
		_tmp7_ = newstatus;
		_tmp5_ = (_tmp7_ & GSM0710_FC) == ((gint) GSM0710_FC);
	} else {
		_tmp5_ = FALSE;
	}
	_tmp8_ = _tmp5_;
	if (_tmp8_) {
		FsoFrameworkLogger* _tmp9_;
		FsoFrameworkTransport* _tmp10_;
		_tmp9_ = self->priv->logger;
		fso_framework_logger_warning (_tmp9_, "FC has been set. Disabling read from PTY");
		_tmp10_ = self->priv->transport;
		fso_framework_transport_freeze (_tmp10_);
	}
	_tmp12_ = oldstatus;
	if ((_tmp12_ & GSM0710_FC) == ((gint) GSM0710_FC)) {
		gint _tmp13_;
		_tmp13_ = newstatus;
		_tmp11_ = (_tmp13_ & GSM0710_FC) == 0;
	} else {
		_tmp11_ = FALSE;
	}
	_tmp14_ = _tmp11_;
	if (_tmp14_) {
		FsoFrameworkLogger* _tmp15_;
		FsoFrameworkTransport* _tmp16_;
		_tmp15_ = self->priv->logger;
		fso_framework_logger_warning (_tmp15_, "FC has been cleared. Reenabling read from PTY");
		_tmp16_ = self->priv->transport;
		fso_framework_transport_thaw (_tmp16_);
	}
}


void channel_deliverData (Channel* self, void* data, gint len) {
	FsoFrameworkTransport* _tmp0_;
	void* _tmp1_;
	gint _tmp2_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->transport;
	_tmp1_ = data;
	_tmp2_ = len;
	fso_framework_transport_write (_tmp0_, _tmp1_, _tmp2_);
}


void channel_onRead (Channel* self, FsoFrameworkTransport* transport) {
	FsoFrameworkLogger* _tmp0_;
	gboolean _tmp1_ = FALSE;
	Multiplexer* _tmp2_;
	gint _tmp3_;
	gchar* _tmp5_ = NULL;
	gchar* buffer;
	gint buffer_length1;
	gint _buffer_size_;
	FsoFrameworkTransport* _tmp6_;
	gint _tmp7_ = 0;
	gint bytesread;
	FsoFrameworkLogger* _tmp8_;
	gchar* _tmp9_ = NULL;
	gchar* _tmp10_;
	gchar* _tmp11_ = NULL;
	gchar* _tmp12_;
	gboolean _tmp13_ = FALSE;
	Multiplexer* _tmp14_;
	gint _tmp15_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (transport != NULL);
	_tmp0_ = self->priv->logger;
	_tmp1_ = fso_framework_logger_debug (_tmp0_, "onRead() from Transport; reading.");
	g_assert (_tmp1_);
	_tmp2_ = self->priv->_multiplexer;
	g_assert (_tmp2_ != NULL);
	_tmp3_ = self->priv->_serial_status;
	if ((_tmp3_ & GSM0710_FC) == ((gint) GSM0710_FC)) {
		FsoFrameworkLogger* _tmp4_;
		_tmp4_ = self->priv->logger;
		fso_framework_logger_warning (_tmp4_, "FC active... reading anyways...");
	}
	_tmp5_ = g_new0 (gchar, 8192);
	buffer = _tmp5_;
	buffer_length1 = 8192;
	_buffer_size_ = buffer_length1;
	_tmp6_ = transport;
	_tmp7_ = fso_framework_transport_read (_tmp6_, buffer, 8192);
	bytesread = _tmp7_;
	_tmp8_ = self->priv->logger;
	_tmp9_ = g_strdup_printf ("%i", bytesread);
	_tmp10_ = _tmp9_;
	_tmp11_ = g_strconcat ("Read ", _tmp10_, " bytes", NULL);
	_tmp12_ = _tmp11_;
	_tmp13_ = fso_framework_logger_debug (_tmp8_, _tmp12_);
	g_assert (_tmp13_);
	_g_free0 (_tmp12_);
	_g_free0 (_tmp10_);
	_tmp14_ = self->priv->_multiplexer;
	_tmp15_ = self->priv->_number;
	multiplexer_submit_data (_tmp14_, _tmp15_, buffer, (gint) bytesread);
	buffer = (g_free (buffer), NULL);
}


void channel_onHup (Channel* self, FsoFrameworkTransport* transport) {
	FsoFrameworkLogger* _tmp0_;
	gboolean _tmp1_ = FALSE;
	g_return_if_fail (self != NULL);
	g_return_if_fail (transport != NULL);
	_tmp0_ = self->priv->logger;
	_tmp1_ = fso_framework_logger_debug (_tmp0_, "onHup() from Transport; closing.");
	g_assert (_tmp1_);
	channel_close (self);
}


static void value_channel_init (GValue* value) {
	value->data[0].v_pointer = NULL;
}


static void value_channel_free_value (GValue* value) {
	if (value->data[0].v_pointer) {
		channel_unref (value->data[0].v_pointer);
	}
}


static void value_channel_copy_value (const GValue* src_value, GValue* dest_value) {
	if (src_value->data[0].v_pointer) {
		dest_value->data[0].v_pointer = channel_ref (src_value->data[0].v_pointer);
	} else {
		dest_value->data[0].v_pointer = NULL;
	}
}


static gpointer value_channel_peek_pointer (const GValue* value) {
	return value->data[0].v_pointer;
}


static gchar* value_channel_collect_value (GValue* value, guint n_collect_values, GTypeCValue* collect_values, guint collect_flags) {
	if (collect_values[0].v_pointer) {
		Channel* object;
		object = collect_values[0].v_pointer;
		if (object->parent_instance.g_class == NULL) {
			return g_strconcat ("invalid unclassed object pointer for value type `", G_VALUE_TYPE_NAME (value), "'", NULL);
		} else if (!g_value_type_compatible (G_TYPE_FROM_INSTANCE (object), G_VALUE_TYPE (value))) {
			return g_strconcat ("invalid object type `", g_type_name (G_TYPE_FROM_INSTANCE (object)), "' for value type `", G_VALUE_TYPE_NAME (value), "'", NULL);
		}
		value->data[0].v_pointer = channel_ref (object);
	} else {
		value->data[0].v_pointer = NULL;
	}
	return NULL;
}


static gchar* value_channel_lcopy_value (const GValue* value, guint n_collect_values, GTypeCValue* collect_values, guint collect_flags) {
	Channel** object_p;
	object_p = collect_values[0].v_pointer;
	if (!object_p) {
		return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
	}
	if (!value->data[0].v_pointer) {
		*object_p = NULL;
	} else if (collect_flags & G_VALUE_NOCOPY_CONTENTS) {
		*object_p = value->data[0].v_pointer;
	} else {
		*object_p = channel_ref (value->data[0].v_pointer);
	}
	return NULL;
}


GParamSpec* param_spec_channel (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags) {
	ParamSpecChannel* spec;
	g_return_val_if_fail (g_type_is_a (object_type, TYPE_CHANNEL), NULL);
	spec = g_param_spec_internal (G_TYPE_PARAM_OBJECT, name, nick, blurb, flags);
	G_PARAM_SPEC (spec)->value_type = object_type;
	return G_PARAM_SPEC (spec);
}


gpointer value_get_channel (const GValue* value) {
	g_return_val_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, TYPE_CHANNEL), NULL);
	return value->data[0].v_pointer;
}


void value_set_channel (GValue* value, gpointer v_object) {
	Channel* old;
	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, TYPE_CHANNEL));
	old = value->data[0].v_pointer;
	if (v_object) {
		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, TYPE_CHANNEL));
		g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value)));
		value->data[0].v_pointer = v_object;
		channel_ref (value->data[0].v_pointer);
	} else {
		value->data[0].v_pointer = NULL;
	}
	if (old) {
		channel_unref (old);
	}
}


void value_take_channel (GValue* value, gpointer v_object) {
	Channel* old;
	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, TYPE_CHANNEL));
	old = value->data[0].v_pointer;
	if (v_object) {
		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, TYPE_CHANNEL));
		g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value)));
		value->data[0].v_pointer = v_object;
	} else {
		value->data[0].v_pointer = NULL;
	}
	if (old) {
		channel_unref (old);
	}
}


static void channel_class_init (ChannelClass * klass) {
	channel_parent_class = g_type_class_peek_parent (klass);
	CHANNEL_CLASS (klass)->finalize = channel_finalize;
	g_type_class_add_private (klass, sizeof (ChannelPrivate));
}


static void channel_instance_init (Channel * self) {
	self->priv = CHANNEL_GET_PRIVATE (self);
	self->ref_count = 1;
}


static void channel_finalize (Channel* obj) {
	Channel * self;
	FsoFrameworkLogger* _tmp0_;
	gboolean _tmp1_ = FALSE;
	self = CHANNEL (obj);
	_tmp0_ = self->priv->logger;
	_tmp1_ = fso_framework_logger_debug (_tmp0_, "Destructed");
	g_assert (_tmp1_);
	_multiplexer_unref0 (self->priv->_multiplexer);
	_g_object_unref0 (self->priv->transport);
	_g_object_unref0 (self->priv->logger);
	_g_free0 (self->priv->_name);
	(self->priv->ackCallback_target_destroy_notify == NULL) ? NULL : (self->priv->ackCallback_target_destroy_notify (self->priv->ackCallback_target), NULL);
	self->priv->ackCallback = NULL;
	self->priv->ackCallback_target = NULL;
	self->priv->ackCallback_target_destroy_notify = NULL;
}


GType channel_get_type (void) {
	static volatile gsize channel_type_id__volatile = 0;
	if (g_once_init_enter (&channel_type_id__volatile)) {
		static const GTypeValueTable g_define_type_value_table = { value_channel_init, value_channel_free_value, value_channel_copy_value, value_channel_peek_pointer, "p", value_channel_collect_value, "p", value_channel_lcopy_value };
		static const GTypeInfo g_define_type_info = { sizeof (ChannelClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) channel_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (Channel), 0, (GInstanceInitFunc) channel_instance_init, &g_define_type_value_table };
		static const GTypeFundamentalInfo g_define_type_fundamental_info = { (G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE) };
		GType channel_type_id;
		channel_type_id = g_type_register_fundamental (g_type_fundamental_next (), "Channel", &g_define_type_info, &g_define_type_fundamental_info, 0);
		g_once_init_leave (&channel_type_id__volatile, channel_type_id);
	}
	return channel_type_id__volatile;
}


gpointer channel_ref (gpointer instance) {
	Channel* self;
	self = instance;
	g_atomic_int_inc (&self->ref_count);
	return instance;
}


void channel_unref (gpointer instance) {
	Channel* self;
	self = instance;
	if (g_atomic_int_dec_and_test (&self->ref_count)) {
		CHANNEL_GET_CLASS (self)->finalize (self);
		g_type_free_instance ((GTypeInstance *) self);
	}
}



