mirror of git://git.sysmocom.de/ofono
gatchat: Use GAtIO for write watchers
This commit is contained in:
parent
6a66505e46
commit
0845dc3b5d
|
@ -38,9 +38,9 @@
|
||||||
|
|
||||||
/* #define WRITE_SCHEDULER_DEBUG 1 */
|
/* #define WRITE_SCHEDULER_DEBUG 1 */
|
||||||
|
|
||||||
static const char *none_prefix[] = { NULL };
|
static void chat_wakeup_writer(GAtChat *chat);
|
||||||
|
|
||||||
static void g_at_chat_wakeup_writer(GAtChat *chat);
|
static const char *none_prefix[] = { NULL };
|
||||||
|
|
||||||
struct at_command {
|
struct at_command {
|
||||||
char *cmd;
|
char *cmd;
|
||||||
|
@ -69,9 +69,6 @@ struct _GAtChat {
|
||||||
gint ref_count; /* Ref count */
|
gint ref_count; /* Ref count */
|
||||||
guint next_cmd_id; /* Next command id */
|
guint next_cmd_id; /* Next command id */
|
||||||
guint next_notify_id; /* Next notify id */
|
guint next_notify_id; /* Next notify id */
|
||||||
guint write_watch; /* GSource write id, 0 if none */
|
|
||||||
gboolean use_write_watch; /* watch usage for non blocking */
|
|
||||||
GIOChannel *channel; /* channel */
|
|
||||||
GAtIO *io; /* AT IO */
|
GAtIO *io; /* AT IO */
|
||||||
GQueue *command_queue; /* Command queue */
|
GQueue *command_queue; /* Command queue */
|
||||||
guint cmd_bytes_written; /* bytes written from cmd */
|
guint cmd_bytes_written; /* bytes written from cmd */
|
||||||
|
@ -273,7 +270,6 @@ static void chat_cleanup(GAtChat *chat)
|
||||||
g_at_syntax_unref(chat->syntax);
|
g_at_syntax_unref(chat->syntax);
|
||||||
chat->syntax = NULL;
|
chat->syntax = NULL;
|
||||||
|
|
||||||
chat->channel = NULL;
|
|
||||||
chat->io = NULL;
|
chat->io = NULL;
|
||||||
|
|
||||||
if (chat->terminator_list) {
|
if (chat->terminator_list) {
|
||||||
|
@ -296,13 +292,6 @@ static void io_disconnect(gpointer user_data)
|
||||||
chat->user_disconnect(chat->user_disconnect_data);
|
chat->user_disconnect(chat->user_disconnect_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void write_watcher_destroy_notify(gpointer user_data)
|
|
||||||
{
|
|
||||||
GAtChat *chat = user_data;
|
|
||||||
|
|
||||||
chat->write_watch = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void at_notify_call_callback(gpointer data, gpointer user_data)
|
static void at_notify_call_callback(gpointer data, gpointer user_data)
|
||||||
{
|
{
|
||||||
struct at_notify_node *node = data;
|
struct at_notify_node *node = data;
|
||||||
|
@ -366,7 +355,7 @@ static void g_at_chat_finish_command(GAtChat *p, gboolean ok, char *final)
|
||||||
p->cmd_bytes_written = 0;
|
p->cmd_bytes_written = 0;
|
||||||
|
|
||||||
if (g_queue_peek_head(p->command_queue))
|
if (g_queue_peek_head(p->command_queue))
|
||||||
g_at_chat_wakeup_writer(p);
|
chat_wakeup_writer(p);
|
||||||
|
|
||||||
response_lines = p->response_lines;
|
response_lines = p->response_lines;
|
||||||
p->response_lines = NULL;
|
p->response_lines = NULL;
|
||||||
|
@ -666,7 +655,7 @@ static void new_bytes(struct ring_buffer *rbuf, gpointer user_data)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case G_AT_SYNTAX_RESULT_PROMPT:
|
case G_AT_SYNTAX_RESULT_PROMPT:
|
||||||
g_at_chat_wakeup_writer(p);
|
chat_wakeup_writer(p);
|
||||||
ring_buffer_drain(rbuf, p->read_so_far);
|
ring_buffer_drain(rbuf, p->read_so_far);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -725,23 +714,15 @@ static gboolean wakeup_no_response(gpointer user_data)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean can_write_data(GIOChannel *channel, GIOCondition cond,
|
static gboolean can_write_data(gpointer data)
|
||||||
gpointer data)
|
|
||||||
{
|
{
|
||||||
GAtChat *chat = data;
|
GAtChat *chat = data;
|
||||||
struct at_command *cmd;
|
struct at_command *cmd;
|
||||||
GIOError err;
|
|
||||||
gsize bytes_written;
|
gsize bytes_written;
|
||||||
gsize towrite;
|
gsize towrite;
|
||||||
gsize len;
|
gsize len;
|
||||||
char *cr;
|
char *cr;
|
||||||
gboolean wakeup_first = FALSE;
|
gboolean wakeup_first = FALSE;
|
||||||
#ifdef WRITE_SCHEDULER_DEBUG
|
|
||||||
int limiter;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
/* Grab the first command off the queue and write as
|
/* Grab the first command off the queue and write as
|
||||||
* much of it as we can
|
* much of it as we can
|
||||||
|
@ -794,28 +775,17 @@ static gboolean can_write_data(GIOChannel *channel, GIOCondition cond,
|
||||||
towrite = cr - (cmd->cmd + chat->cmd_bytes_written) + 1;
|
towrite = cr - (cmd->cmd + chat->cmd_bytes_written) + 1;
|
||||||
|
|
||||||
#ifdef WRITE_SCHEDULER_DEBUG
|
#ifdef WRITE_SCHEDULER_DEBUG
|
||||||
limiter = towrite;
|
if (towrite > 5)
|
||||||
|
towrite = 5;
|
||||||
if (limiter > 5)
|
|
||||||
limiter = 5;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
err = g_io_channel_write(chat->channel,
|
bytes_written = g_at_io_write(chat->io,
|
||||||
cmd->cmd + chat->cmd_bytes_written,
|
cmd->cmd + chat->cmd_bytes_written,
|
||||||
#ifdef WRITE_SCHEDULER_DEBUG
|
towrite);
|
||||||
limiter,
|
|
||||||
#else
|
|
||||||
towrite,
|
|
||||||
#endif
|
|
||||||
&bytes_written);
|
|
||||||
|
|
||||||
if (err != G_IO_ERROR_NONE) {
|
if (bytes_written == 0)
|
||||||
io_disconnect(chat);
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
|
||||||
|
|
||||||
g_at_util_debug_chat(FALSE, cmd->cmd + chat->cmd_bytes_written,
|
|
||||||
bytes_written, chat->debugf, chat->debug_data);
|
|
||||||
chat->cmd_bytes_written += bytes_written;
|
chat->cmd_bytes_written += bytes_written;
|
||||||
|
|
||||||
if (bytes_written < towrite)
|
if (bytes_written < towrite)
|
||||||
|
@ -828,21 +798,9 @@ static gboolean can_write_data(GIOChannel *channel, GIOCondition cond,
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void g_at_chat_wakeup_writer(GAtChat *chat)
|
static void chat_wakeup_writer(GAtChat *chat)
|
||||||
{
|
{
|
||||||
if (chat->write_watch != 0)
|
g_at_io_set_write_handler(chat->io, can_write_data, chat);
|
||||||
return;
|
|
||||||
|
|
||||||
if (chat->use_write_watch == TRUE) {
|
|
||||||
chat->write_watch = g_io_add_watch_full(chat->channel,
|
|
||||||
G_PRIORITY_DEFAULT,
|
|
||||||
G_IO_OUT | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
|
|
||||||
can_write_data, chat,
|
|
||||||
write_watcher_destroy_notify);
|
|
||||||
} else {
|
|
||||||
while (can_write_data(chat->channel, G_IO_OUT, chat) == TRUE);
|
|
||||||
write_watcher_destroy_notify(chat);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static GAtChat *create_chat(GIOChannel *channel, GIOFlags flags,
|
static GAtChat *create_chat(GIOChannel *channel, GIOFlags flags,
|
||||||
|
@ -865,13 +823,10 @@ static GAtChat *create_chat(GIOChannel *channel, GIOFlags flags,
|
||||||
chat->next_notify_id = 1;
|
chat->next_notify_id = 1;
|
||||||
chat->debugf = NULL;
|
chat->debugf = NULL;
|
||||||
|
|
||||||
if (flags & G_IO_FLAG_NONBLOCK) {
|
if (flags & G_IO_FLAG_NONBLOCK)
|
||||||
chat->use_write_watch = TRUE;
|
|
||||||
chat->io = g_at_io_new(channel);
|
chat->io = g_at_io_new(channel);
|
||||||
} else {
|
else
|
||||||
chat->use_write_watch = FALSE;
|
|
||||||
chat->io = g_at_io_new_blocking(channel);
|
chat->io = g_at_io_new_blocking(channel);
|
||||||
}
|
|
||||||
|
|
||||||
if (!chat->io)
|
if (!chat->io)
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -886,9 +841,6 @@ static GAtChat *create_chat(GIOChannel *channel, GIOFlags flags,
|
||||||
chat->notify_list = g_hash_table_new_full(g_str_hash, g_str_equal,
|
chat->notify_list = g_hash_table_new_full(g_str_hash, g_str_equal,
|
||||||
g_free, at_notify_destroy);
|
g_free, at_notify_destroy);
|
||||||
|
|
||||||
|
|
||||||
chat->channel = channel;
|
|
||||||
|
|
||||||
g_at_io_set_read_handler(chat->io, new_bytes, chat);
|
g_at_io_set_read_handler(chat->io, new_bytes, chat);
|
||||||
|
|
||||||
chat->syntax = g_at_syntax_ref(syntax);
|
chat->syntax = g_at_syntax_ref(syntax);
|
||||||
|
@ -943,6 +895,7 @@ void g_at_chat_suspend(GAtChat *chat)
|
||||||
|
|
||||||
chat->suspended = TRUE;
|
chat->suspended = TRUE;
|
||||||
|
|
||||||
|
g_at_io_set_write_handler(chat->io, NULL, NULL);
|
||||||
g_at_io_set_read_handler(chat->io, NULL, NULL);
|
g_at_io_set_read_handler(chat->io, NULL, NULL);
|
||||||
g_at_io_set_debug(chat->io, NULL, NULL);
|
g_at_io_set_debug(chat->io, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
@ -954,8 +907,11 @@ void g_at_chat_resume(GAtChat *chat)
|
||||||
|
|
||||||
chat->suspended = FALSE;
|
chat->suspended = FALSE;
|
||||||
|
|
||||||
g_at_io_set_read_handler(chat->io, new_bytes, chat);
|
|
||||||
g_at_io_set_debug(chat->io, chat->debugf, chat->debug_data);
|
g_at_io_set_debug(chat->io, chat->debugf, chat->debug_data);
|
||||||
|
g_at_io_set_read_handler(chat->io, new_bytes, chat);
|
||||||
|
|
||||||
|
if (g_queue_get_length(chat->command_queue) > 0)
|
||||||
|
chat_wakeup_writer(chat);
|
||||||
}
|
}
|
||||||
|
|
||||||
void g_at_chat_unref(GAtChat *chat)
|
void g_at_chat_unref(GAtChat *chat)
|
||||||
|
@ -1033,7 +989,7 @@ static guint send_common(GAtChat *chat, const char *cmd,
|
||||||
g_queue_push_tail(chat->command_queue, c);
|
g_queue_push_tail(chat->command_queue, c);
|
||||||
|
|
||||||
if (g_queue_get_length(chat->command_queue) == 1)
|
if (g_queue_get_length(chat->command_queue) == 1)
|
||||||
g_at_chat_wakeup_writer(chat);
|
chat_wakeup_writer(chat);
|
||||||
|
|
||||||
return c->id;
|
return c->id;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue