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

/*
 * Copyright (C) 2011-2012 Michael 'Mickey' Lauer <mlauer@vanille-media.de>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.

 * This library 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
 * Lesser General Public License for more details.

 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; 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 <gio/gio.h>
#include <stdlib.h>
#include <string.h>
#include <fsobasics.h>
#include <fcntl.h>
#include <sys/types.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <linux/gsmmux.h>
#include <sys/stat.h>
#include <unistd.h>


#define FSO_FRAMEWORK_TYPE_TRANSPORT (fso_framework_transport_get_type ())
#define FSO_FRAMEWORK_TRANSPORT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), FSO_FRAMEWORK_TYPE_TRANSPORT, FsoFrameworkTransport))
#define FSO_FRAMEWORK_TRANSPORT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), FSO_FRAMEWORK_TYPE_TRANSPORT, FsoFrameworkTransportClass))
#define FSO_FRAMEWORK_IS_TRANSPORT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), FSO_FRAMEWORK_TYPE_TRANSPORT))
#define FSO_FRAMEWORK_IS_TRANSPORT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), FSO_FRAMEWORK_TYPE_TRANSPORT))
#define FSO_FRAMEWORK_TRANSPORT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), FSO_FRAMEWORK_TYPE_TRANSPORT, FsoFrameworkTransportClass))

typedef struct _FsoFrameworkTransport FsoFrameworkTransport;
typedef struct _FsoFrameworkTransportClass FsoFrameworkTransportClass;
typedef struct _FsoFrameworkTransportPrivate FsoFrameworkTransportPrivate;

#define FSO_FRAMEWORK_TYPE_BASE_TRANSPORT (fso_framework_base_transport_get_type ())
#define FSO_FRAMEWORK_BASE_TRANSPORT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), FSO_FRAMEWORK_TYPE_BASE_TRANSPORT, FsoFrameworkBaseTransport))
#define FSO_FRAMEWORK_BASE_TRANSPORT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), FSO_FRAMEWORK_TYPE_BASE_TRANSPORT, FsoFrameworkBaseTransportClass))
#define FSO_FRAMEWORK_IS_BASE_TRANSPORT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), FSO_FRAMEWORK_TYPE_BASE_TRANSPORT))
#define FSO_FRAMEWORK_IS_BASE_TRANSPORT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), FSO_FRAMEWORK_TYPE_BASE_TRANSPORT))
#define FSO_FRAMEWORK_BASE_TRANSPORT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), FSO_FRAMEWORK_TYPE_BASE_TRANSPORT, FsoFrameworkBaseTransportClass))

typedef struct _FsoFrameworkBaseTransport FsoFrameworkBaseTransport;
typedef struct _FsoFrameworkBaseTransportClass FsoFrameworkBaseTransportClass;
typedef struct _FsoFrameworkBaseTransportPrivate FsoFrameworkBaseTransportPrivate;

#define FSO_FRAMEWORK_TYPE_NGSM_TRANSPORT (fso_framework_ngsm_transport_get_type ())
#define FSO_FRAMEWORK_NGSM_TRANSPORT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), FSO_FRAMEWORK_TYPE_NGSM_TRANSPORT, FsoFrameworkNgsmTransport))
#define FSO_FRAMEWORK_NGSM_TRANSPORT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), FSO_FRAMEWORK_TYPE_NGSM_TRANSPORT, FsoFrameworkNgsmTransportClass))
#define FSO_FRAMEWORK_IS_NGSM_TRANSPORT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), FSO_FRAMEWORK_TYPE_NGSM_TRANSPORT))
#define FSO_FRAMEWORK_IS_NGSM_TRANSPORT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), FSO_FRAMEWORK_TYPE_NGSM_TRANSPORT))
#define FSO_FRAMEWORK_NGSM_TRANSPORT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), FSO_FRAMEWORK_TYPE_NGSM_TRANSPORT, FsoFrameworkNgsmTransportClass))

typedef struct _FsoFrameworkNgsmTransport FsoFrameworkNgsmTransport;
typedef struct _FsoFrameworkNgsmTransportClass FsoFrameworkNgsmTransportClass;
typedef struct _FsoFrameworkNgsmTransportPrivate FsoFrameworkNgsmTransportPrivate;
#define _g_free0(var) (var = (g_free (var), NULL))

#define FSO_FRAMEWORK_TYPE_NGSM_BASIC_MUX_TRANSPORT (fso_framework_ngsm_basic_mux_transport_get_type ())
#define FSO_FRAMEWORK_NGSM_BASIC_MUX_TRANSPORT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), FSO_FRAMEWORK_TYPE_NGSM_BASIC_MUX_TRANSPORT, FsoFrameworkNgsmBasicMuxTransport))
#define FSO_FRAMEWORK_NGSM_BASIC_MUX_TRANSPORT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), FSO_FRAMEWORK_TYPE_NGSM_BASIC_MUX_TRANSPORT, FsoFrameworkNgsmBasicMuxTransportClass))
#define FSO_FRAMEWORK_IS_NGSM_BASIC_MUX_TRANSPORT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), FSO_FRAMEWORK_TYPE_NGSM_BASIC_MUX_TRANSPORT))
#define FSO_FRAMEWORK_IS_NGSM_BASIC_MUX_TRANSPORT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), FSO_FRAMEWORK_TYPE_NGSM_BASIC_MUX_TRANSPORT))
#define FSO_FRAMEWORK_NGSM_BASIC_MUX_TRANSPORT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), FSO_FRAMEWORK_TYPE_NGSM_BASIC_MUX_TRANSPORT, FsoFrameworkNgsmBasicMuxTransportClass))

typedef struct _FsoFrameworkNgsmBasicMuxTransport FsoFrameworkNgsmBasicMuxTransport;
typedef struct _FsoFrameworkNgsmBasicMuxTransportClass FsoFrameworkNgsmBasicMuxTransportClass;
typedef struct _FsoFrameworkNgsmBasicMuxTransportPrivate FsoFrameworkNgsmBasicMuxTransportPrivate;

#define FSO_FRAMEWORK_TYPE_NGSM_ADVANCED_MUX_TRANSPORT (fso_framework_ngsm_advanced_mux_transport_get_type ())
#define FSO_FRAMEWORK_NGSM_ADVANCED_MUX_TRANSPORT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), FSO_FRAMEWORK_TYPE_NGSM_ADVANCED_MUX_TRANSPORT, FsoFrameworkNgsmAdvancedMuxTransport))
#define FSO_FRAMEWORK_NGSM_ADVANCED_MUX_TRANSPORT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), FSO_FRAMEWORK_TYPE_NGSM_ADVANCED_MUX_TRANSPORT, FsoFrameworkNgsmAdvancedMuxTransportClass))
#define FSO_FRAMEWORK_IS_NGSM_ADVANCED_MUX_TRANSPORT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), FSO_FRAMEWORK_TYPE_NGSM_ADVANCED_MUX_TRANSPORT))
#define FSO_FRAMEWORK_IS_NGSM_ADVANCED_MUX_TRANSPORT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), FSO_FRAMEWORK_TYPE_NGSM_ADVANCED_MUX_TRANSPORT))
#define FSO_FRAMEWORK_NGSM_ADVANCED_MUX_TRANSPORT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), FSO_FRAMEWORK_TYPE_NGSM_ADVANCED_MUX_TRANSPORT, FsoFrameworkNgsmAdvancedMuxTransportClass))

typedef struct _FsoFrameworkNgsmAdvancedMuxTransport FsoFrameworkNgsmAdvancedMuxTransport;
typedef struct _FsoFrameworkNgsmAdvancedMuxTransportClass FsoFrameworkNgsmAdvancedMuxTransportClass;
typedef struct _FsoFrameworkNgsmAdvancedMuxTransportPrivate FsoFrameworkNgsmAdvancedMuxTransportPrivate;

typedef void (*FsoFrameworkTransportFunc) (FsoFrameworkTransport* transport, void* user_data);
struct _FsoFrameworkTransport {
	GObject parent_instance;
	FsoFrameworkTransportPrivate * priv;
	FsoFrameworkLogger* logger;
};

struct _FsoFrameworkTransportClass {
	GObjectClass parent_class;
	gboolean (*isOpen) (FsoFrameworkTransport* self);
	void (*openAsync) (FsoFrameworkTransport* self, GAsyncReadyCallback _callback_, gpointer _user_data_);
	gboolean (*openAsync_finish) (FsoFrameworkTransport* self, GAsyncResult* _res_);
	gboolean (*open) (FsoFrameworkTransport* self);
	void (*close) (FsoFrameworkTransport* self);
	gchar* (*getName) (FsoFrameworkTransport* self);
	void (*setDelegates) (FsoFrameworkTransport* self, FsoFrameworkTransportFunc readfunc, void* readfunc_target, FsoFrameworkTransportFunc hupfunc, void* hupfunc_target);
	void (*getDelegates) (FsoFrameworkTransport* self, FsoFrameworkTransportFunc* readfun, void** readfun_target, GDestroyNotify* readfun_target_destroy_notify, FsoFrameworkTransportFunc* hupfun, void** hupfun_target, GDestroyNotify* hupfun_target_destroy_notify);
	void (*setPriorities) (FsoFrameworkTransport* self, gint rp, gint wp);
	void (*setBuffered) (FsoFrameworkTransport* self, gboolean on);
	gint (*writeAndRead) (FsoFrameworkTransport* self, void* wdata, gint wlength, void* rdata, gint rlength, gint maxWait);
	gint (*read) (FsoFrameworkTransport* self, void* data, gint length);
	gint (*write) (FsoFrameworkTransport* self, void* data, gint length);
	gint (*freeze) (FsoFrameworkTransport* self);
	void (*thaw) (FsoFrameworkTransport* self);
	void (*drain) (FsoFrameworkTransport* self);
	void (*flush) (FsoFrameworkTransport* self);
	gboolean (*suspend) (FsoFrameworkTransport* self);
	void (*resume) (FsoFrameworkTransport* self);
};

struct _FsoFrameworkBaseTransport {
	FsoFrameworkTransport parent_instance;
	FsoFrameworkBaseTransportPrivate * priv;
	gchar* name;
	guint speed;
	gboolean raw;
	gboolean hard;
	gint fd;
	FsoFrameworkTransportFunc hupfunc;
	gpointer hupfunc_target;
	GDestroyNotify hupfunc_target_destroy_notify;
	FsoFrameworkTransportFunc readfunc;
	gpointer readfunc_target;
	GDestroyNotify readfunc_target_destroy_notify;
	GByteArray* buffer;
};

struct _FsoFrameworkBaseTransportClass {
	FsoFrameworkTransportClass parent_class;
	gssize (*_real_write) (FsoFrameworkBaseTransport* self, gint fd, void* data, gint len);
	void (*configure) (FsoFrameworkBaseTransport* self);
	gchar* (*repr) (FsoFrameworkBaseTransport* self);
	gssize (*_real_read) (FsoFrameworkBaseTransport* self, gint fd, void* data, gint len);
};

struct _FsoFrameworkNgsmTransport {
	FsoFrameworkBaseTransport parent_instance;
	FsoFrameworkNgsmTransportPrivate * priv;
};

struct _FsoFrameworkNgsmTransportClass {
	FsoFrameworkBaseTransportClass parent_class;
};

struct _FsoFrameworkNgsmTransportPrivate {
	gint oldisc;
	guint mode;
	guint framesize;
};

struct _FsoFrameworkNgsmBasicMuxTransport {
	FsoFrameworkNgsmTransport parent_instance;
	FsoFrameworkNgsmBasicMuxTransportPrivate * priv;
};

struct _FsoFrameworkNgsmBasicMuxTransportClass {
	FsoFrameworkNgsmTransportClass parent_class;
};

struct _FsoFrameworkNgsmAdvancedMuxTransport {
	FsoFrameworkNgsmTransport parent_instance;
	FsoFrameworkNgsmAdvancedMuxTransportPrivate * priv;
};

struct _FsoFrameworkNgsmAdvancedMuxTransportClass {
	FsoFrameworkNgsmTransportClass parent_class;
};


static gpointer fso_framework_ngsm_transport_parent_class = NULL;
static gpointer fso_framework_ngsm_basic_mux_transport_parent_class = NULL;
static gpointer fso_framework_ngsm_advanced_mux_transport_parent_class = NULL;

#define LINE_DISCIPLINE_N_GSM 21
#define MKNOD_TTYGSM_MAJOR ((guchar) 249)
GType fso_framework_transport_get_type (void) G_GNUC_CONST;
GType fso_framework_base_transport_get_type (void) G_GNUC_CONST;
GType fso_framework_ngsm_transport_get_type (void) G_GNUC_CONST;
#define FSO_FRAMEWORK_NGSM_TRANSPORT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), FSO_FRAMEWORK_TYPE_NGSM_TRANSPORT, FsoFrameworkNgsmTransportPrivate))
enum  {
	FSO_FRAMEWORK_NGSM_TRANSPORT_DUMMY_PROPERTY
};
FsoFrameworkNgsmTransport* fso_framework_ngsm_transport_new (const gchar* portname, guint portspeed, gboolean advanced, guint framesize);
FsoFrameworkNgsmTransport* fso_framework_ngsm_transport_construct (GType object_type, const gchar* portname, guint portspeed, gboolean advanced, guint framesize);
FsoFrameworkBaseTransport* fso_framework_base_transport_new (const gchar* name, guint speed, gboolean raw, gboolean hard);
FsoFrameworkBaseTransport* fso_framework_base_transport_construct (GType object_type, const gchar* name, guint speed, gboolean raw, gboolean hard);
static gboolean fso_framework_ngsm_transport_real_open (FsoFrameworkTransport* base);
void fso_framework_base_transport_configure (FsoFrameworkBaseTransport* self);
gboolean fso_framework_transport_open (FsoFrameworkTransport* self);
static gboolean fso_framework_ngsm_transport_enterMuxMode (FsoFrameworkNgsmTransport* self);
gint fso_framework_transport_writeAndRead (FsoFrameworkTransport* self, void* wdata, gint wlength, void* rdata, gint rlength, gint maxWait);
gint fso_framework_transport_freeze (FsoFrameworkTransport* self);
static void fso_framework_ngsm_transport_real_close (FsoFrameworkTransport* base);
void fso_framework_transport_thaw (FsoFrameworkTransport* self);
void fso_framework_transport_close (FsoFrameworkTransport* self);
static gchar* fso_framework_ngsm_transport_real_repr (FsoFrameworkBaseTransport* base);
static void fso_framework_ngsm_transport_finalize (GObject* obj);
GType fso_framework_ngsm_basic_mux_transport_get_type (void) G_GNUC_CONST;
enum  {
	FSO_FRAMEWORK_NGSM_BASIC_MUX_TRANSPORT_DUMMY_PROPERTY
};
FsoFrameworkNgsmBasicMuxTransport* fso_framework_ngsm_basic_mux_transport_new (const gchar* portname, guint portspeed, guint framesize);
FsoFrameworkNgsmBasicMuxTransport* fso_framework_ngsm_basic_mux_transport_construct (GType object_type, const gchar* portname, guint portspeed, guint framesize);
GType fso_framework_ngsm_advanced_mux_transport_get_type (void) G_GNUC_CONST;
enum  {
	FSO_FRAMEWORK_NGSM_ADVANCED_MUX_TRANSPORT_DUMMY_PROPERTY
};
FsoFrameworkNgsmAdvancedMuxTransport* fso_framework_ngsm_advanced_mux_transport_new (const gchar* portname, guint portspeed, guint framesize);
FsoFrameworkNgsmAdvancedMuxTransport* fso_framework_ngsm_advanced_mux_transport_construct (GType object_type, const gchar* portname, guint portspeed, guint framesize);


FsoFrameworkNgsmTransport* fso_framework_ngsm_transport_construct (GType object_type, const gchar* portname, guint portspeed, gboolean advanced, guint framesize) {
	FsoFrameworkNgsmTransport * self = NULL;
	const gchar* _tmp0_;
	guint _tmp1_;
	guint _tmp2_;
	gint _tmp3_ = 0;
	gboolean _tmp4_;
	gint _tmp5_;
	g_return_val_if_fail (portname != NULL, NULL);
	_tmp0_ = portname;
	_tmp1_ = portspeed;
	self = (FsoFrameworkNgsmTransport*) fso_framework_base_transport_construct (object_type, _tmp0_, _tmp1_, TRUE, TRUE);
	_tmp2_ = framesize;
	self->priv->framesize = _tmp2_;
	_tmp4_ = advanced;
	if (_tmp4_) {
		_tmp3_ = 1;
	} else {
		_tmp3_ = 0;
	}
	_tmp5_ = _tmp3_;
	self->priv->mode = (guint) _tmp5_;
	return self;
}


FsoFrameworkNgsmTransport* fso_framework_ngsm_transport_new (const gchar* portname, guint portspeed, gboolean advanced, guint framesize) {
	return fso_framework_ngsm_transport_construct (FSO_FRAMEWORK_TYPE_NGSM_TRANSPORT, portname, portspeed, advanced, framesize);
}


static gboolean fso_framework_ngsm_transport_real_open (FsoFrameworkTransport* base) {
	FsoFrameworkNgsmTransport * self;
	gboolean result = FALSE;
	const gchar* _tmp0_;
	gint _tmp1_ = 0;
	gint _tmp2_;
	gboolean _tmp9_ = FALSE;
	gboolean _tmp10_ = FALSE;
	self = (FsoFrameworkNgsmTransport*) base;
	_tmp0_ = ((FsoFrameworkBaseTransport*) self)->name;
	_tmp1_ = open (_tmp0_, (O_RDWR | O_NOCTTY) | O_NONBLOCK, (mode_t) 0);
	((FsoFrameworkBaseTransport*) self)->fd = _tmp1_;
	_tmp2_ = ((FsoFrameworkBaseTransport*) self)->fd;
	if (_tmp2_ == (-1)) {
		FsoFrameworkLogger* _tmp3_;
		const gchar* _tmp4_;
		gint _tmp5_;
		const gchar* _tmp6_ = NULL;
		gchar* _tmp7_ = NULL;
		gchar* _tmp8_;
		_tmp3_ = ((FsoFrameworkTransport*) self)->logger;
		_tmp4_ = ((FsoFrameworkBaseTransport*) self)->name;
		_tmp5_ = errno;
		_tmp6_ = strerror (_tmp5_);
		_tmp7_ = g_strdup_printf ("Could not open %s: %s", _tmp4_, _tmp6_);
		_tmp8_ = _tmp7_;
		fso_framework_logger_warning (_tmp3_, _tmp8_);
		_g_free0 (_tmp8_);
		result = FALSE;
		return result;
	}
	fso_framework_base_transport_configure ((FsoFrameworkBaseTransport*) self);
	_tmp9_ = FSO_FRAMEWORK_TRANSPORT_CLASS (fso_framework_ngsm_transport_parent_class)->open ((FsoFrameworkTransport*) FSO_FRAMEWORK_BASE_TRANSPORT (self));
	if (!_tmp9_) {
		result = FALSE;
		return result;
	}
	_tmp10_ = fso_framework_ngsm_transport_enterMuxMode (self);
	if (!_tmp10_) {
		result = FALSE;
		return result;
	}
	result = TRUE;
	return result;
}


static gchar* string_strip (const gchar* self) {
	gchar* result = NULL;
	gchar* _tmp0_ = NULL;
	gchar* _result_;
	const gchar* _tmp1_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = g_strdup (self);
	_result_ = _tmp0_;
	_tmp1_ = _result_;
	g_strstrip (_tmp1_);
	result = _result_;
	return result;
}


static const gchar* string_to_string (const gchar* self) {
	const gchar* result = NULL;
	g_return_val_if_fail (self != NULL, NULL);
	result = self;
	return result;
}


static gboolean fso_framework_ngsm_transport_enterMuxMode (FsoFrameworkNgsmTransport* self) {
	gboolean result = FALSE;
	FsoFrameworkLogger* _tmp0_;
	gboolean _tmp1_ = FALSE;
	gchar* _tmp2_ = NULL;
	gchar* buffer;
	gint buffer_length1;
	gint _buffer_size_;
	gchar* _tmp3_;
	gchar* command;
	const gchar* _tmp4_;
	const gchar* _tmp5_;
	gint _tmp6_;
	gint _tmp7_;
	gchar* _tmp8_;
	gint _tmp8__length1;
	gint _tmp9_ = 0;
	gint bread;
	gchar* _tmp10_ = NULL;
	guint _tmp11_;
	const gchar* _tmp15_;
	gchar* _tmp16_;
	const gchar* _tmp17_;
	const gchar* _tmp18_;
	gint _tmp19_;
	gint _tmp20_;
	gchar* _tmp21_;
	gint _tmp21__length1;
	gint _tmp22_ = 0;
	gchar* _tmp23_;
	gint _tmp23__length1;
	gint _tmp24_;
	gchar _tmp25_;
	gchar* _tmp26_;
	gint _tmp26__length1;
	gchar* _tmp27_ = NULL;
	gchar* response;
	const gchar* _tmp28_;
	FsoFrameworkLogger* _tmp34_;
	gboolean _tmp35_ = FALSE;
	gint ldisc;
	gint _tmp36_;
	gint _tmp37_ = 0;
	gint _tmp44_;
	gint _tmp45_ = 0;
	struct gsm_config muxconfig = {0};
	gint _tmp52_;
	gint _tmp53_ = 0;
	guint _tmp61_;
	gint _tmp62_;
	gint _tmp63_ = 0;
	FsoFrameworkLogger* _tmp71_;
	gboolean _tmp72_ = FALSE;
	FsoFrameworkLogger* _tmp84_;
	gboolean _tmp85_ = FALSE;
	g_return_val_if_fail (self != NULL, FALSE);
	_tmp0_ = ((FsoFrameworkTransport*) self)->logger;
	_tmp1_ = fso_framework_logger_debug (_tmp0_, "Entering MUX mode...");
	g_assert (_tmp1_);
	_tmp2_ = g_new0 (gchar, 128);
	buffer = _tmp2_;
	buffer_length1 = 128;
	_buffer_size_ = buffer_length1;
	_tmp3_ = g_strdup ("\r\nATE0Q0V1\r\n");
	command = _tmp3_;
	_tmp4_ = command;
	_tmp5_ = command;
	_tmp6_ = strlen (_tmp5_);
	_tmp7_ = _tmp6_;
	_tmp8_ = buffer;
	_tmp8__length1 = buffer_length1;
	_tmp9_ = fso_framework_transport_writeAndRead ((FsoFrameworkTransport*) self, _tmp4_, _tmp7_, _tmp8_, 128, 5000);
	bread = _tmp9_;
	_tmp11_ = self->priv->mode;
	if (_tmp11_ == ((guint) 0)) {
		gchar* _tmp12_;
		_tmp12_ = g_strdup ("AT+CMUX=0\r\n");
		_g_free0 (_tmp10_);
		_tmp10_ = _tmp12_;
	} else {
		guint _tmp13_;
		gchar* _tmp14_ = NULL;
		_tmp13_ = self->priv->framesize;
		_tmp14_ = g_strdup_printf ("AT+CMUX=1,0,5,%u\r\n", _tmp13_);
		_g_free0 (_tmp10_);
		_tmp10_ = _tmp14_;
	}
	_tmp15_ = _tmp10_;
	_tmp16_ = g_strdup (_tmp15_);
	_g_free0 (command);
	command = _tmp16_;
	_tmp17_ = command;
	_tmp18_ = command;
	_tmp19_ = strlen (_tmp18_);
	_tmp20_ = _tmp19_;
	_tmp21_ = buffer;
	_tmp21__length1 = buffer_length1;
	_tmp22_ = fso_framework_transport_writeAndRead ((FsoFrameworkTransport*) self, _tmp17_, _tmp20_, _tmp21_, 128, 5000);
	bread = _tmp22_;
	_tmp23_ = buffer;
	_tmp23__length1 = buffer_length1;
	_tmp24_ = bread;
	_tmp23_[_tmp24_] = '\0';
	_tmp25_ = _tmp23_[_tmp24_];
	_tmp26_ = buffer;
	_tmp26__length1 = buffer_length1;
	_tmp27_ = string_strip ((const gchar*) _tmp26_);
	response = _tmp27_;
	_tmp28_ = response;
	if (g_strcmp0 (_tmp28_, "OK") != 0) {
		FsoFrameworkLogger* _tmp29_;
		const gchar* _tmp30_;
		const gchar* _tmp31_ = NULL;
		gchar* _tmp32_ = NULL;
		gchar* _tmp33_;
		_tmp29_ = ((FsoFrameworkTransport*) self)->logger;
		_tmp30_ = response;
		_tmp31_ = string_to_string (_tmp30_);
		_tmp32_ = g_strconcat ("Can't enter MUX mode: Modem answered '", _tmp31_, "'", NULL);
		_tmp33_ = _tmp32_;
		fso_framework_logger_error (_tmp29_, _tmp33_);
		_g_free0 (_tmp33_);
		result = FALSE;
		_g_free0 (response);
		_g_free0 (_tmp10_);
		_g_free0 (command);
		buffer = (g_free (buffer), NULL);
		return result;
	}
	_tmp34_ = ((FsoFrameworkTransport*) self)->logger;
	_tmp35_ = fso_framework_logger_debug (_tmp34_, "Setting line discipline...");
	g_assert (_tmp35_);
	fso_framework_transport_freeze ((FsoFrameworkTransport*) self);
	ldisc = LINE_DISCIPLINE_N_GSM;
	_tmp36_ = ((FsoFrameworkBaseTransport*) self)->fd;
	_tmp37_ = ioctl (_tmp36_, TIOCGETD, &self->priv->oldisc);
	if (_tmp37_ == (-1)) {
		FsoFrameworkLogger* _tmp38_;
		gint _tmp39_;
		const gchar* _tmp40_ = NULL;
		const gchar* _tmp41_ = NULL;
		gchar* _tmp42_ = NULL;
		gchar* _tmp43_;
		_tmp38_ = ((FsoFrameworkTransport*) self)->logger;
		_tmp39_ = errno;
		_tmp40_ = g_strerror (_tmp39_);
		_tmp41_ = string_to_string (_tmp40_);
		_tmp42_ = g_strconcat ("Can't get old line discipline: ", _tmp41_, NULL);
		_tmp43_ = _tmp42_;
		fso_framework_logger_error (_tmp38_, _tmp43_);
		_g_free0 (_tmp43_);
		result = FALSE;
		_g_free0 (response);
		_g_free0 (_tmp10_);
		_g_free0 (command);
		buffer = (g_free (buffer), NULL);
		return result;
	}
	_tmp44_ = ((FsoFrameworkBaseTransport*) self)->fd;
	_tmp45_ = ioctl (_tmp44_, TIOCSETD, &ldisc);
	if (_tmp45_ == (-1)) {
		FsoFrameworkLogger* _tmp46_;
		gint _tmp47_;
		const gchar* _tmp48_ = NULL;
		const gchar* _tmp49_ = NULL;
		gchar* _tmp50_ = NULL;
		gchar* _tmp51_;
		_tmp46_ = ((FsoFrameworkTransport*) self)->logger;
		_tmp47_ = errno;
		_tmp48_ = g_strerror (_tmp47_);
		_tmp49_ = string_to_string (_tmp48_);
		_tmp50_ = g_strconcat ("Can't set N_GSM line discipline: ", _tmp49_, NULL);
		_tmp51_ = _tmp50_;
		fso_framework_logger_error (_tmp46_, _tmp51_);
		_g_free0 (_tmp51_);
		result = FALSE;
		_g_free0 (response);
		_g_free0 (_tmp10_);
		_g_free0 (command);
		buffer = (g_free (buffer), NULL);
		return result;
	}
	memset (&muxconfig, 0, sizeof (struct gsm_config));
	_tmp52_ = ((FsoFrameworkBaseTransport*) self)->fd;
	_tmp53_ = ioctl (_tmp52_, GSMIOC_GETCONF, &muxconfig);
	if (_tmp53_ == (-1)) {
		FsoFrameworkLogger* _tmp54_;
		gint _tmp55_;
		const gchar* _tmp56_ = NULL;
		const gchar* _tmp57_ = NULL;
		gchar* _tmp58_ = NULL;
		gchar* _tmp59_;
		gint _tmp60_;
		_tmp54_ = ((FsoFrameworkTransport*) self)->logger;
		_tmp55_ = errno;
		_tmp56_ = g_strerror (_tmp55_);
		_tmp57_ = string_to_string (_tmp56_);
		_tmp58_ = g_strconcat ("Can't get N_GSM configuration: ", _tmp57_, NULL);
		_tmp59_ = _tmp58_;
		fso_framework_logger_error (_tmp54_, _tmp59_);
		_g_free0 (_tmp59_);
		_tmp60_ = ((FsoFrameworkBaseTransport*) self)->fd;
		ioctl (_tmp60_, TIOCSETD, &self->priv->oldisc);
		result = FALSE;
		_g_free0 (response);
		_g_free0 (_tmp10_);
		_g_free0 (command);
		buffer = (g_free (buffer), NULL);
		return result;
	}
	muxconfig.initiator = (guint) 1;
	_tmp61_ = self->priv->mode;
	muxconfig.encapsulation = _tmp61_;
	muxconfig.mru = (guint) 127;
	muxconfig.mtu = (guint) 127;
	_tmp62_ = ((FsoFrameworkBaseTransport*) self)->fd;
	_tmp63_ = ioctl (_tmp62_, GSMIOC_SETCONF, &muxconfig);
	if (_tmp63_ == (-1)) {
		FsoFrameworkLogger* _tmp64_;
		gint _tmp65_;
		const gchar* _tmp66_ = NULL;
		const gchar* _tmp67_ = NULL;
		gchar* _tmp68_ = NULL;
		gchar* _tmp69_;
		gint _tmp70_;
		_tmp64_ = ((FsoFrameworkTransport*) self)->logger;
		_tmp65_ = errno;
		_tmp66_ = g_strerror (_tmp65_);
		_tmp67_ = string_to_string (_tmp66_);
		_tmp68_ = g_strconcat ("Can't set N_GSM configuration: ", _tmp67_, NULL);
		_tmp69_ = _tmp68_;
		fso_framework_logger_error (_tmp64_, _tmp69_);
		_g_free0 (_tmp69_);
		_tmp70_ = ((FsoFrameworkBaseTransport*) self)->fd;
		ioctl (_tmp70_, TIOCSETD, &self->priv->oldisc);
		result = FALSE;
		_g_free0 (response);
		_g_free0 (_tmp10_);
		_g_free0 (command);
		buffer = (g_free (buffer), NULL);
		return result;
	}
	_tmp71_ = ((FsoFrameworkTransport*) self)->logger;
	_tmp72_ = fso_framework_logger_debug (_tmp71_, "Creating device nodes... (needs root privileges)");
	g_assert (_tmp72_);
	{
		gint i;
		i = 1;
		{
			gboolean _tmp73_;
			_tmp73_ = TRUE;
			while (TRUE) {
				gboolean _tmp74_;
				gint _tmp76_;
				gint _tmp77_;
				gchar* _tmp78_ = NULL;
				gchar* _tmp79_;
				gchar* _tmp80_ = NULL;
				gchar* _tmp81_;
				gint _tmp82_;
				dev_t _tmp83_ = {0};
				_tmp74_ = _tmp73_;
				if (!_tmp74_) {
					gint _tmp75_;
					_tmp75_ = i;
					i = _tmp75_ + 1;
				}
				_tmp73_ = FALSE;
				_tmp76_ = i;
				if (!(_tmp76_ < 8)) {
					break;
				}
				_tmp77_ = i;
				_tmp78_ = g_strdup_printf ("%i", _tmp77_);
				_tmp79_ = _tmp78_;
				_tmp80_ = g_strconcat ("/dev/ttygsm", _tmp79_, NULL);
				_tmp81_ = _tmp80_;
				_tmp82_ = i;
				_tmp83_ = makedev ((gint) MKNOD_TTYGSM_MAJOR, _tmp82_);
				mknod (_tmp81_, S_IFCHR | 0666, _tmp83_);
				_g_free0 (_tmp81_);
				_g_free0 (_tmp79_);
			}
		}
	}
	_tmp84_ = ((FsoFrameworkTransport*) self)->logger;
	_tmp85_ = fso_framework_logger_debug (_tmp84_, "MUX mode established, you can now use /dev/ttygsm[1-n]");
	g_assert (_tmp85_);
	result = TRUE;
	_g_free0 (response);
	_g_free0 (_tmp10_);
	_g_free0 (command);
	buffer = (g_free (buffer), NULL);
	return result;
}


static void fso_framework_ngsm_transport_real_close (FsoFrameworkTransport* base) {
	FsoFrameworkNgsmTransport * self;
	gint _tmp0_;
	self = (FsoFrameworkNgsmTransport*) base;
	fso_framework_transport_freeze ((FsoFrameworkTransport*) self);
	_tmp0_ = ((FsoFrameworkBaseTransport*) self)->fd;
	ioctl (_tmp0_, TIOCSETD, &self->priv->oldisc);
	fso_framework_transport_thaw ((FsoFrameworkTransport*) self);
	FSO_FRAMEWORK_TRANSPORT_CLASS (fso_framework_ngsm_transport_parent_class)->close ((FsoFrameworkTransport*) FSO_FRAMEWORK_BASE_TRANSPORT (self));
}


static gchar* fso_framework_ngsm_transport_real_repr (FsoFrameworkBaseTransport* base) {
	FsoFrameworkNgsmTransport * self;
	gchar* result = NULL;
	const gchar* _tmp0_;
	guint _tmp1_;
	gint _tmp2_;
	gchar* _tmp3_ = NULL;
	self = (FsoFrameworkNgsmTransport*) base;
	_tmp0_ = ((FsoFrameworkBaseTransport*) self)->name;
	_tmp1_ = ((FsoFrameworkBaseTransport*) self)->speed;
	_tmp2_ = ((FsoFrameworkBaseTransport*) self)->fd;
	_tmp3_ = g_strdup_printf ("<N_GSM %s@%u (fd %d)>", _tmp0_, _tmp1_, _tmp2_);
	result = _tmp3_;
	return result;
}


static void fso_framework_ngsm_transport_class_init (FsoFrameworkNgsmTransportClass * klass) {
	fso_framework_ngsm_transport_parent_class = g_type_class_peek_parent (klass);
	g_type_class_add_private (klass, sizeof (FsoFrameworkNgsmTransportPrivate));
	FSO_FRAMEWORK_TRANSPORT_CLASS (klass)->open = fso_framework_ngsm_transport_real_open;
	FSO_FRAMEWORK_TRANSPORT_CLASS (klass)->close = fso_framework_ngsm_transport_real_close;
	FSO_FRAMEWORK_BASE_TRANSPORT_CLASS (klass)->repr = fso_framework_ngsm_transport_real_repr;
	G_OBJECT_CLASS (klass)->finalize = fso_framework_ngsm_transport_finalize;
}


static void fso_framework_ngsm_transport_instance_init (FsoFrameworkNgsmTransport * self) {
	self->priv = FSO_FRAMEWORK_NGSM_TRANSPORT_GET_PRIVATE (self);
}


static void fso_framework_ngsm_transport_finalize (GObject* obj) {
	FsoFrameworkNgsmTransport * self;
	self = FSO_FRAMEWORK_NGSM_TRANSPORT (obj);
	G_OBJECT_CLASS (fso_framework_ngsm_transport_parent_class)->finalize (obj);
}


GType fso_framework_ngsm_transport_get_type (void) {
	static volatile gsize fso_framework_ngsm_transport_type_id__volatile = 0;
	if (g_once_init_enter (&fso_framework_ngsm_transport_type_id__volatile)) {
		static const GTypeInfo g_define_type_info = { sizeof (FsoFrameworkNgsmTransportClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) fso_framework_ngsm_transport_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (FsoFrameworkNgsmTransport), 0, (GInstanceInitFunc) fso_framework_ngsm_transport_instance_init, NULL };
		GType fso_framework_ngsm_transport_type_id;
		fso_framework_ngsm_transport_type_id = g_type_register_static (FSO_FRAMEWORK_TYPE_BASE_TRANSPORT, "FsoFrameworkNgsmTransport", &g_define_type_info, 0);
		g_once_init_leave (&fso_framework_ngsm_transport_type_id__volatile, fso_framework_ngsm_transport_type_id);
	}
	return fso_framework_ngsm_transport_type_id__volatile;
}


FsoFrameworkNgsmBasicMuxTransport* fso_framework_ngsm_basic_mux_transport_construct (GType object_type, const gchar* portname, guint portspeed, guint framesize) {
	FsoFrameworkNgsmBasicMuxTransport * self = NULL;
	const gchar* _tmp0_;
	guint _tmp1_;
	guint _tmp2_;
	g_return_val_if_fail (portname != NULL, NULL);
	_tmp0_ = portname;
	_tmp1_ = portspeed;
	_tmp2_ = framesize;
	self = (FsoFrameworkNgsmBasicMuxTransport*) fso_framework_ngsm_transport_construct (object_type, _tmp0_, _tmp1_, FALSE, _tmp2_);
	return self;
}


FsoFrameworkNgsmBasicMuxTransport* fso_framework_ngsm_basic_mux_transport_new (const gchar* portname, guint portspeed, guint framesize) {
	return fso_framework_ngsm_basic_mux_transport_construct (FSO_FRAMEWORK_TYPE_NGSM_BASIC_MUX_TRANSPORT, portname, portspeed, framesize);
}


static void fso_framework_ngsm_basic_mux_transport_class_init (FsoFrameworkNgsmBasicMuxTransportClass * klass) {
	fso_framework_ngsm_basic_mux_transport_parent_class = g_type_class_peek_parent (klass);
}


static void fso_framework_ngsm_basic_mux_transport_instance_init (FsoFrameworkNgsmBasicMuxTransport * self) {
}


GType fso_framework_ngsm_basic_mux_transport_get_type (void) {
	static volatile gsize fso_framework_ngsm_basic_mux_transport_type_id__volatile = 0;
	if (g_once_init_enter (&fso_framework_ngsm_basic_mux_transport_type_id__volatile)) {
		static const GTypeInfo g_define_type_info = { sizeof (FsoFrameworkNgsmBasicMuxTransportClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) fso_framework_ngsm_basic_mux_transport_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (FsoFrameworkNgsmBasicMuxTransport), 0, (GInstanceInitFunc) fso_framework_ngsm_basic_mux_transport_instance_init, NULL };
		GType fso_framework_ngsm_basic_mux_transport_type_id;
		fso_framework_ngsm_basic_mux_transport_type_id = g_type_register_static (FSO_FRAMEWORK_TYPE_NGSM_TRANSPORT, "FsoFrameworkNgsmBasicMuxTransport", &g_define_type_info, 0);
		g_once_init_leave (&fso_framework_ngsm_basic_mux_transport_type_id__volatile, fso_framework_ngsm_basic_mux_transport_type_id);
	}
	return fso_framework_ngsm_basic_mux_transport_type_id__volatile;
}


FsoFrameworkNgsmAdvancedMuxTransport* fso_framework_ngsm_advanced_mux_transport_construct (GType object_type, const gchar* portname, guint portspeed, guint framesize) {
	FsoFrameworkNgsmAdvancedMuxTransport * self = NULL;
	const gchar* _tmp0_;
	guint _tmp1_;
	guint _tmp2_;
	g_return_val_if_fail (portname != NULL, NULL);
	_tmp0_ = portname;
	_tmp1_ = portspeed;
	_tmp2_ = framesize;
	self = (FsoFrameworkNgsmAdvancedMuxTransport*) fso_framework_ngsm_transport_construct (object_type, _tmp0_, _tmp1_, TRUE, _tmp2_);
	return self;
}


FsoFrameworkNgsmAdvancedMuxTransport* fso_framework_ngsm_advanced_mux_transport_new (const gchar* portname, guint portspeed, guint framesize) {
	return fso_framework_ngsm_advanced_mux_transport_construct (FSO_FRAMEWORK_TYPE_NGSM_ADVANCED_MUX_TRANSPORT, portname, portspeed, framesize);
}


static void fso_framework_ngsm_advanced_mux_transport_class_init (FsoFrameworkNgsmAdvancedMuxTransportClass * klass) {
	fso_framework_ngsm_advanced_mux_transport_parent_class = g_type_class_peek_parent (klass);
}


static void fso_framework_ngsm_advanced_mux_transport_instance_init (FsoFrameworkNgsmAdvancedMuxTransport * self) {
}


GType fso_framework_ngsm_advanced_mux_transport_get_type (void) {
	static volatile gsize fso_framework_ngsm_advanced_mux_transport_type_id__volatile = 0;
	if (g_once_init_enter (&fso_framework_ngsm_advanced_mux_transport_type_id__volatile)) {
		static const GTypeInfo g_define_type_info = { sizeof (FsoFrameworkNgsmAdvancedMuxTransportClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) fso_framework_ngsm_advanced_mux_transport_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (FsoFrameworkNgsmAdvancedMuxTransport), 0, (GInstanceInitFunc) fso_framework_ngsm_advanced_mux_transport_instance_init, NULL };
		GType fso_framework_ngsm_advanced_mux_transport_type_id;
		fso_framework_ngsm_advanced_mux_transport_type_id = g_type_register_static (FSO_FRAMEWORK_TYPE_NGSM_TRANSPORT, "FsoFrameworkNgsmAdvancedMuxTransport", &g_define_type_info, 0);
		g_once_init_leave (&fso_framework_ngsm_advanced_mux_transport_type_id__volatile, fso_framework_ngsm_advanced_mux_transport_type_id);
	}
	return fso_framework_ngsm_advanced_mux_transport_type_id__volatile;
}



