Refactor: Enable multiplexer drivers for GAtMux

This commit is contained in:
Denis Kenzior 2009-10-12 15:31:44 -05:00
parent 1575f2dcd1
commit a4a54f6625
2 changed files with 78 additions and 60 deletions

View File

@ -76,7 +76,8 @@ struct _GAtMux {
gpointer debug_data; /* Data to pass to debug func */ gpointer debug_data; /* Data to pass to debug func */
GAtMuxChannel *dlcs[MAX_CHANNELS]; /* DLCs opened by the MUX */ GAtMuxChannel *dlcs[MAX_CHANNELS]; /* DLCs opened by the MUX */
guint8 newdata[BITMAP_SIZE]; /* Channels that got new data */ guint8 newdata[BITMAP_SIZE]; /* Channels that got new data */
struct gsm0710_context ctx; const GAtMuxDriver *driver; /* Driver functions */
void *driver_data; /* Driver data */
}; };
struct mux_setup_data { struct mux_setup_data {
@ -164,7 +165,9 @@ static gboolean received_data(GIOChannel *channel, GIOCondition cond,
DBG("received data"); DBG("received data");
memset(mux->newdata, 0, BITMAP_SIZE); memset(mux->newdata, 0, BITMAP_SIZE);
gsm0710_ready_read(&mux->ctx);
if (mux->driver->ready_read)
mux->driver->ready_read(mux);
for (i = 1; i <= MAX_CHANNELS; i++) { for (i = 1; i <= MAX_CHANNELS; i++) {
int offset = i / 8; int offset = i / 8;
@ -249,25 +252,23 @@ static void wakeup_writer(GAtMux *mux)
(GDestroyNotify)write_watcher_destroy_notify); (GDestroyNotify)write_watcher_destroy_notify);
} }
static int do_read(struct gsm0710_context *ctx, void *data, int len) int g_at_mux_raw_read(GAtMux *mux, void *data, int toread)
{ {
GAtMux *mux = ctx->user_data;
GError *error = NULL; GError *error = NULL;
GIOStatus status; GIOStatus status;
gsize bytes_read; gsize bytes_read;
status = g_io_channel_read_chars(mux->channel, data, len, status = g_io_channel_read_chars(mux->channel, data, toread,
&bytes_read, &error); &bytes_read, &error);
return bytes_read; return bytes_read;
} }
static int do_write(struct gsm0710_context *ctx, const void *data, int len) int g_at_mux_raw_write(GAtMux *mux, const void *data, int towrite)
{ {
GAtMux *mux = ctx->user_data;
GError *error = NULL; GError *error = NULL;
GIOStatus status; GIOStatus status;
gssize count = len; gssize count = towrite;
gsize bytes_written; gsize bytes_written;
status = g_io_channel_write_chars(mux->channel, (gchar *) data, status = g_io_channel_write_chars(mux->channel, (gchar *) data,
@ -276,10 +277,9 @@ static int do_write(struct gsm0710_context *ctx, const void *data, int len)
return bytes_written; return bytes_written;
} }
static void deliver_data(struct gsm0710_context *ctx, int dlc, void g_at_mux_feed_dlc_data(GAtMux *mux, guint8 dlc,
const void *data, int len) const void *data, int tofeed)
{ {
GAtMux *mux = ctx->user_data;
GAtMuxChannel *channel = mux->dlcs[dlc-1]; GAtMuxChannel *channel = mux->dlcs[dlc-1];
int written; int written;
int offset; int offset;
@ -290,7 +290,7 @@ static void deliver_data(struct gsm0710_context *ctx, int dlc,
if (channel == NULL) if (channel == NULL)
return; return;
written = ring_buffer_write(channel->buffer, data, len); written = ring_buffer_write(channel->buffer, data, tofeed);
if (written < 0) if (written < 0)
return; return;
@ -302,20 +302,20 @@ static void deliver_data(struct gsm0710_context *ctx, int dlc,
channel->condition |= G_IO_IN; channel->condition |= G_IO_IN;
} }
static void deliver_status(struct gsm0710_context *ctx, void g_at_mux_set_dlc_status(GAtMux *mux, guint8 dlc, int status)
int channel, int status)
{ {
GAtMux *mux = ctx->user_data;
DBG("Got status %d, for channel %d", status, channel); DBG("Got status %d, for channel %d", status, channel);
if (status & GSM0710_RTS) { if (dlc < 1 || dlc > MAX_CHANNELS)
return;
if (status & G_AT_MUX_DLC_STATUS_RTR) {
GSList *l; GSList *l;
mux->dlcs[channel-1]->throttled = FALSE; mux->dlcs[dlc-1]->throttled = FALSE;
DBG("setting throttled to FALSE"); DBG("setting throttled to FALSE");
for (l = mux->dlcs[channel-1]->sources; l; l = l->next) { for (l = mux->dlcs[dlc-1]->sources; l; l = l->next) {
GAtMuxWatch *source = l->data; GAtMuxWatch *source = l->data;
if (source->condition & G_IO_OUT) { if (source->condition & G_IO_OUT) {
@ -324,11 +324,7 @@ static void deliver_status(struct gsm0710_context *ctx,
} }
} }
} else } else
mux->dlcs[channel-1]->throttled = TRUE; mux->dlcs[dlc-1]->throttled = TRUE;
}
static void debug_message(struct gsm0710_context *ctx, const char *msg)
{
} }
static gboolean watch_check(GSource *source) static gboolean watch_check(GSource *source)
@ -390,7 +386,8 @@ static GIOStatus channel_write(GIOChannel *channel, const gchar *buf,
GAtMuxChannel *mux_channel = (GAtMuxChannel *) channel; GAtMuxChannel *mux_channel = (GAtMuxChannel *) channel;
GAtMux *mux = mux_channel->mux; GAtMux *mux = mux_channel->mux;
gsm0710_write_data(&mux->ctx, mux_channel->dlc, buf, count); if (mux->driver->write)
mux->driver->write(mux, mux_channel->dlc, buf, count);
*bytes_written = count; *bytes_written = count;
return G_IO_STATUS_NORMAL; return G_IO_STATUS_NORMAL;
@ -411,7 +408,9 @@ static GIOStatus channel_close(GIOChannel *channel, GError **err)
dispatch_sources(mux_channel, G_IO_NVAL); dispatch_sources(mux_channel, G_IO_NVAL);
gsm0710_close_channel(&mux->ctx, mux_channel->dlc); if (mux->driver->close_dlc)
mux->driver->close_dlc(mux, mux_channel->dlc);
mux->dlcs[mux_channel->dlc - 1] = NULL; mux->dlcs[mux_channel->dlc - 1] = NULL;
return G_IO_STATUS_NORMAL; return G_IO_STATUS_NORMAL;
@ -479,51 +478,28 @@ static GIOFuncs channel_funcs = {
channel_get_flags, channel_get_flags,
}; };
static GAtMux *mux_new_gsm0710_common(GIOChannel *channel, GAtMux *g_at_mux_new(GIOChannel *channel, const GAtMuxDriver *driver)
int mode, int frame_size)
{ {
GAtMux *mux; GAtMux *mux;
if (!channel) if (!channel)
return NULL; return NULL;
mux = g_try_new0(GAtMux, 1); mux = g_new0(GAtMux, 1);
if (!mux) if (!mux)
return NULL; return NULL;
mux->ref_count = 1; mux->ref_count = 1;
mux->driver = driver;
mux->channel = channel; mux->channel = channel;
g_io_channel_ref(channel); g_io_channel_ref(channel);
g_io_channel_set_close_on_unref(channel, TRUE); g_io_channel_set_close_on_unref(channel, TRUE);
gsm0710_initialize(&mux->ctx);
mux->ctx.user_data = mux;
mux->ctx.read = do_read;
mux->ctx.write = do_write;
mux->ctx.deliver_data = deliver_data;
mux->ctx.deliver_status = deliver_status;
mux->ctx.debug_message = debug_message;
mux->ctx.mode = mode;
mux->ctx.frame_size = frame_size;
return mux; return mux;
} }
GAtMux *g_at_mux_new_gsm0710_basic(GIOChannel *channel, int frame_size)
{
return mux_new_gsm0710_common(channel, GSM0710_MODE_BASIC, frame_size);
}
GAtMux *g_at_mux_new_gsm0710_advanced(GIOChannel *channel, int frame_size)
{
return mux_new_gsm0710_common(channel, GSM0710_MODE_ADVANCED,
frame_size);
}
GAtMux *g_at_mux_ref(GAtMux *mux) GAtMux *g_at_mux_ref(GAtMux *mux)
{ {
if (mux == NULL) if (mux == NULL)
@ -544,6 +520,9 @@ void g_at_mux_unref(GAtMux *mux)
g_io_channel_unref(mux->channel); g_io_channel_unref(mux->channel);
if (mux->driver->remove)
mux->driver->remove(mux);
g_free(mux); g_free(mux);
} }
} }
@ -553,12 +532,16 @@ gboolean g_at_mux_start(GAtMux *mux)
if (mux->channel == NULL) if (mux->channel == NULL)
return FALSE; return FALSE;
if (mux->driver->startup == NULL)
return FALSE;
if (mux->driver->startup(mux) == FALSE)
return FALSE;
mux->read_watch = g_io_add_watch_full(mux->channel, G_PRIORITY_DEFAULT, mux->read_watch = g_io_add_watch_full(mux->channel, G_PRIORITY_DEFAULT,
G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
received_data, mux, NULL); received_data, mux, NULL);
gsm0710_startup(&mux->ctx);
return TRUE; return TRUE;
} }
@ -566,6 +549,9 @@ gboolean g_at_mux_shutdown(GAtMux *mux)
{ {
int i; int i;
if (mux->channel == NULL)
return FALSE;
if (mux->read_watch > 0) if (mux->read_watch > 0)
g_source_remove(mux->read_watch); g_source_remove(mux->read_watch);
@ -576,10 +562,8 @@ gboolean g_at_mux_shutdown(GAtMux *mux)
channel_close((GIOChannel *) mux->dlcs[i], NULL); channel_close((GIOChannel *) mux->dlcs[i], NULL);
} }
if (mux->channel == NULL) if (mux->driver->shutdown)
return FALSE; mux->driver->shutdown(mux);
gsm0710_shutdown(&mux->ctx);
return TRUE; return TRUE;
} }
@ -625,7 +609,8 @@ GIOChannel *g_at_mux_create_channel(GAtMux *mux)
if (mux_channel == NULL) if (mux_channel == NULL)
return NULL; return NULL;
gsm0710_open_channel(&mux->ctx, i+1); if (mux->driver->open_dlc)
mux->driver->open_dlc(mux, i+1);
channel = (GIOChannel *) mux_channel; channel = (GIOChannel *) mux_channel;

View File

@ -31,9 +31,29 @@ extern "C" {
struct _GAtMux; struct _GAtMux;
typedef struct _GAtMux GAtMux; typedef struct _GAtMux GAtMux;
typedef struct _GAtMuxDriver GAtMuxDriver;
typedef enum _GAtMuxChannelStatus GAtMuxChannelStatus;
typedef void (*GAtMuxSetupFunc)(GAtMux *mux, gpointer user_data); typedef void (*GAtMuxSetupFunc)(GAtMux *mux, gpointer user_data);
enum _GAtMuxDlcStatus {
G_AT_MUX_DLC_STATUS_RTC = 0x02,
G_AT_MUX_DLC_STATUS_RTR = 0x04,
G_AT_MUX_DLC_STATUS_IC = 0x08,
G_AT_MUX_DLC_STATUS_DV = 0x80,
};
struct _GAtMuxDriver {
void (*remove)(GAtMux *mux);
gboolean (*startup)(GAtMux *mux);
gboolean (*shutdown)(GAtMux *mux);
gboolean (*open_dlc)(GAtMux *mux, guint8 dlc);
gboolean (*close_dlc)(GAtMux *mux, guint8 dlc);
void (*ready_read)(GAtMux *mux);
void (*set_status)(GAtMux *mux, guint8 dlc, int status);
void (*write)(GAtMux *mux, guint8 dlc, const void *data, int towrite);
};
GAtMux *g_at_mux_new(GIOChannel *channel, const GAtMuxDriver *driver);
GAtMux *g_at_mux_new_gsm0710_basic(GIOChannel *channel, int framesize); GAtMux *g_at_mux_new_gsm0710_basic(GIOChannel *channel, int framesize);
GAtMux *g_at_mux_new_gsm0710_advanced(GIOChannel *channel, int framesize); GAtMux *g_at_mux_new_gsm0710_advanced(GIOChannel *channel, int framesize);
@ -50,6 +70,19 @@ gboolean g_at_mux_set_debug(GAtMux *mux, GAtDebugFunc func, gpointer user);
GIOChannel *g_at_mux_create_channel(GAtMux *mux); GIOChannel *g_at_mux_create_channel(GAtMux *mux);
/*!
* Multiplexer driver integration functions
*/
void g_at_mux_set_dlc_status(GAtMux *mux, guint8 dlc, int status);
void g_at_mux_feed_dlc_data(GAtMux *mux, guint8 dlc,
const void *data, int tofeed);
int g_at_mux_raw_read(GAtMux *mux, void *data, int toread);
int g_at_mux_raw_write(GAtMux *mux, const void *data, int towrite);
void g_at_mux_set_data(GAtMux *mux, void *data);
void g_at_mux_get_data(GAtMux *mux);
/*! /*!
* Uses the passed in GAtChat to setup a GSM 07.10 style multiplexer on the * Uses the passed in GAtChat to setup a GSM 07.10 style multiplexer on the
* channel used by GAtChat. This function queries the multiplexer capability, * channel used by GAtChat. This function queries the multiplexer capability,