mirror of git://git.sysmocom.de/ofono
Refactor: Enable multiplexer drivers for GAtMux
This commit is contained in:
parent
1575f2dcd1
commit
a4a54f6625
103
gatchat/gatmux.c
103
gatchat/gatmux.c
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Reference in New Issue