/* #define WRITE_SCHEDULER_DEBUG 1 */
-static void chat_wakeup_writer(GAtChat *chat);
+struct at_chat;
+static void chat_wakeup_writer(struct at_chat *chat);
static const char *none_prefix[] = { NULL };
char **prefixes;
gboolean expect_pdu;
guint id;
+ guint gid;
GAtResultFunc callback;
GAtNotifyFunc listing;
gpointer user_data;
struct at_notify_node {
guint id;
+ guint gid;
GAtNotifyFunc callback;
gpointer user_data;
GDestroyNotify notify;
gboolean pdu;
};
-struct _GAtChat {
+struct at_chat {
gint ref_count; /* Ref count */
guint next_cmd_id; /* Next command id */
guint next_notify_id; /* Next notify id */
+ guint next_gid; /* Next group id */
GAtIO *io; /* AT IO */
GQueue *command_queue; /* Command queue */
guint cmd_bytes_written; /* bytes written from cmd */
GSList *terminator_list; /* Non-standard terminator */
};
+struct _GAtChat {
+ gint ref_count;
+ struct at_chat *parent;
+ guint group;
+};
+
struct terminator_info {
char *terminator;
int len;
return 0;
}
-static struct at_command *at_command_create(const char *cmd,
+static struct at_command *at_command_create(guint gid, const char *cmd,
const char **prefix_list,
gboolean expect_pdu,
GAtNotifyFunc listing,
c->cmd[len] = '\0';
+ c->gid = gid;
c->expect_pdu = expect_pdu;
c->prefixes = prefixes;
c->callback = func;
info = NULL;
}
-static void chat_cleanup(GAtChat *chat)
+static void chat_cleanup(struct at_chat *chat)
{
struct at_command *c;
static void io_disconnect(gpointer user_data)
{
- GAtChat *chat = user_data;
+ struct at_chat *chat = user_data;
chat_cleanup(chat);
g_at_io_unref(chat->io);
node->callback(result, node->user_data);
}
-static gboolean g_at_chat_match_notify(GAtChat *chat, char *line)
+static gboolean at_chat_match_notify(struct at_chat *chat, char *line)
{
GHashTableIter iter;
struct at_notify *notify;
return ret;
}
-static void g_at_chat_finish_command(GAtChat *p, gboolean ok, char *final)
+static void at_chat_finish_command(struct at_chat *p, gboolean ok, char *final)
{
struct at_command *cmd = g_queue_pop_head(p->command_queue);
GSList *response_lines;
{ "+EXT ERROR:", 11, FALSE }
};
-void g_at_chat_add_terminator(GAtChat *chat, char *terminator,
+static void at_chat_add_terminator(struct at_chat *chat, char *terminator,
int len, gboolean success)
{
struct terminator_info *info = g_new0(struct terminator_info, 1);
return FALSE;
}
-static gboolean g_at_chat_handle_command_response(GAtChat *p,
+static gboolean at_chat_handle_command_response(struct at_chat *p,
struct at_command *cmd,
char *line)
{
for (i = 0; i < size; i++) {
struct terminator_info *info = &terminator_table[i];
if (check_terminator(info, line)) {
- g_at_chat_finish_command(p, info->success, line);
+ at_chat_finish_command(p, info->success, line);
return TRUE;
}
}
for (l = p->terminator_list; l; l = l->next) {
struct terminator_info *info = l->data;
if (check_terminator(info, line)) {
- g_at_chat_finish_command(p, info->success, line);
+ at_chat_finish_command(p, info->success, line);
return TRUE;
}
}
return TRUE;
}
-static void have_line(GAtChat *p, char *str)
+static void have_line(struct at_chat *p, char *str)
{
/* We're not going to copy terminal <CR><LF> */
struct at_command *cmd;
* final response from the modem, so we check this as well.
*/
if ((c == '\r' || c == 26) &&
- g_at_chat_handle_command_response(p, cmd, str))
+ at_chat_handle_command_response(p, cmd, str))
return;
}
- if (g_at_chat_match_notify(p, str) == TRUE)
+ if (at_chat_match_notify(p, str) == TRUE)
return;
done:
g_free(str);
}
-static void have_notify_pdu(GAtChat *p, char *pdu, GAtResult *result)
+static void have_notify_pdu(struct at_chat *p, char *pdu, GAtResult *result)
{
GHashTableIter iter;
struct at_notify *notify;
}
}
-static void have_pdu(GAtChat *p, char *pdu)
+static void have_pdu(struct at_chat *p, char *pdu)
{
struct at_command *cmd;
GAtResult result;
g_free(pdu);
}
-static char *extract_line(GAtChat *p, struct ring_buffer *rbuf)
+static char *extract_line(struct at_chat *p, struct ring_buffer *rbuf)
{
unsigned int wrap = ring_buffer_len_no_wrap(rbuf);
unsigned int pos = 0;
static void new_bytes(struct ring_buffer *rbuf, gpointer user_data)
{
- GAtChat *p = user_data;
+ struct at_chat *p = user_data;
unsigned int len = ring_buffer_len(rbuf);
unsigned int wrap = ring_buffer_len_no_wrap(rbuf);
unsigned char *buf = ring_buffer_read_ptr(rbuf, p->read_so_far);
static void wakeup_cb(gboolean ok, GAtResult *result, gpointer user_data)
{
- GAtChat *chat = user_data;
+ struct at_chat *chat = user_data;
if (ok == FALSE)
return;
static gboolean wakeup_no_response(gpointer user_data)
{
- GAtChat *chat = user_data;
+ struct at_chat *chat = user_data;
struct at_command *cmd = g_queue_peek_head(chat->command_queue);
if (chat->debugf)
if (cmd == NULL)
return FALSE;
- g_at_chat_finish_command(chat, FALSE, NULL);
- cmd = at_command_create(chat->wakeup, none_prefix, FALSE,
+ at_chat_finish_command(chat, FALSE, NULL);
+ cmd = at_command_create(0, chat->wakeup, none_prefix, FALSE,
NULL, wakeup_cb, chat, NULL, TRUE);
if (!cmd) {
static gboolean can_write_data(gpointer data)
{
- GAtChat *chat = data;
+ struct at_chat *chat = data;
struct at_command *cmd;
gsize bytes_written;
gsize towrite;
}
if (chat->cmd_bytes_written == 0 && wakeup_first == TRUE) {
- cmd = at_command_create(chat->wakeup, none_prefix, FALSE,
+ cmd = at_command_create(0, chat->wakeup, none_prefix, FALSE,
NULL, wakeup_cb, chat, NULL, TRUE);
if (!cmd)
return FALSE;
}
-static void chat_wakeup_writer(GAtChat *chat)
+static void chat_wakeup_writer(struct at_chat *chat)
{
g_at_io_set_write_handler(chat->io, can_write_data, chat);
}
-static GAtChat *create_chat(GIOChannel *channel, GIOFlags flags,
- GAtSyntax *syntax)
+static void at_chat_suspend(struct at_chat *chat)
{
- GAtChat *chat;
-
- if (!channel)
- return NULL;
-
- if (!syntax)
- return NULL;
-
- chat = g_try_new0(GAtChat, 1);
- if (!chat)
- return chat;
-
- chat->ref_count = 1;
- chat->next_cmd_id = 1;
- chat->next_notify_id = 1;
- chat->debugf = NULL;
-
- if (flags & G_IO_FLAG_NONBLOCK)
- chat->io = g_at_io_new(channel);
- else
- chat->io = g_at_io_new_blocking(channel);
-
- if (!chat->io)
- goto error;
-
- g_at_io_set_disconnect_function(chat->io, io_disconnect, chat);
-
- chat->command_queue = g_queue_new();
-
- if (!chat->command_queue)
- goto error;
-
- chat->notify_list = g_hash_table_new_full(g_str_hash, g_str_equal,
- g_free, at_notify_destroy);
-
- g_at_io_set_read_handler(chat->io, new_bytes, chat);
-
- chat->syntax = g_at_syntax_ref(syntax);
-
- return chat;
-
-error:
- g_at_io_unref(chat->io);
-
- if (chat->command_queue)
- g_queue_free(chat->command_queue);
-
- if (chat->notify_list)
- g_hash_table_destroy(chat->notify_list);
-
- g_free(chat);
- return NULL;
-}
-
-GAtChat *g_at_chat_new(GIOChannel *channel, GAtSyntax *syntax)
-{
- return create_chat(channel, G_IO_FLAG_NONBLOCK, syntax);
-}
-
-GAtChat *g_at_chat_new_blocking(GIOChannel *channel, GAtSyntax *syntax)
-{
- return create_chat(channel, 0, syntax);
-}
-
-GIOChannel *g_at_chat_get_channel(GAtChat *chat)
-{
- if (chat == NULL || chat->io == NULL)
- return NULL;
-
- return g_at_io_get_channel(chat->io);
-}
-
-GAtIO *g_at_chat_get_io(GAtChat *chat)
-{
- if (chat == NULL)
- return NULL;
-
- return chat->io;
-}
-
-GAtChat *g_at_chat_ref(GAtChat *chat)
-{
- if (chat == NULL)
- return NULL;
-
- g_atomic_int_inc(&chat->ref_count);
-
- return chat;
-}
-
-void g_at_chat_suspend(GAtChat *chat)
-{
- if (chat == NULL)
- return;
-
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_debug(chat->io, NULL, NULL);
+
}
-void g_at_chat_resume(GAtChat *chat)
+static void at_chat_resume(struct at_chat *chat)
{
- if (chat == NULL)
- return;
-
chat->suspended = FALSE;
if (g_at_io_get_channel(chat->io) == NULL) {
chat_wakeup_writer(chat);
}
-void g_at_chat_unref(GAtChat *chat)
+static void at_chat_unref(struct at_chat *chat)
{
gboolean is_zero;
- if (chat == NULL)
- return;
-
is_zero = g_atomic_int_dec_and_test(&chat->ref_count);
if (is_zero == FALSE)
return;
if (chat->io) {
- g_at_chat_suspend(chat);
+ at_chat_suspend(chat);
g_at_io_unref(chat->io);
chat->io = NULL;
chat_cleanup(chat);
g_free(chat);
}
-gboolean g_at_chat_set_disconnect_function(GAtChat *chat,
+static gboolean at_chat_set_disconnect_function(struct at_chat *chat,
GAtDisconnectFunc disconnect, gpointer user_data)
{
- if (chat == NULL)
- return FALSE;
-
chat->user_disconnect = disconnect;
chat->user_disconnect_data = user_data;
return TRUE;
}
-gboolean g_at_chat_set_debug(GAtChat *chat,
+static gboolean at_chat_set_debug(struct at_chat *chat,
GAtDebugFunc func, gpointer user_data)
{
- if (chat == NULL)
- return FALSE;
chat->debugf = func;
chat->debug_data = user_data;
return TRUE;
}
-static guint send_common(GAtChat *chat, const char *cmd,
- const char **prefix_list,
- gboolean expect_pdu,
- GAtNotifyFunc listing, GAtResultFunc func,
- gpointer user_data, GDestroyNotify notify)
+static gboolean at_chat_set_wakeup_command(struct at_chat *chat,
+ const char *cmd,
+ unsigned int timeout,
+ unsigned int msec)
+{
+ if (chat->wakeup)
+ g_free(chat->wakeup);
+
+ chat->wakeup = g_strdup(cmd);
+ chat->inactivity_time = (gdouble)msec / 1000;
+ chat->wakeup_timeout = timeout;
+
+ return TRUE;
+}
+
+static guint at_chat_send_common(struct at_chat *chat, guint gid,
+ const char *cmd,
+ const char **prefix_list,
+ gboolean expect_pdu,
+ GAtNotifyFunc listing,
+ GAtResultFunc func,
+ gpointer user_data,
+ GDestroyNotify notify)
{
struct at_command *c;
if (chat == NULL || chat->command_queue == NULL)
return 0;
- c = at_command_create(cmd, prefix_list, expect_pdu, listing, func,
+ c = at_command_create(gid, cmd, prefix_list, expect_pdu, listing, func,
user_data, notify, FALSE);
if (!c)
return c->id;
}
-guint g_at_chat_send(GAtChat *chat, const char *cmd,
- const char **prefix_list, GAtResultFunc func,
- gpointer user_data, GDestroyNotify notify)
+static struct at_notify *at_notify_create(struct at_chat *chat,
+ const char *prefix,
+ gboolean pdu)
{
- return send_common(chat, cmd, prefix_list, FALSE, NULL, func,
- user_data, notify);
-}
+ struct at_notify *notify;
+ char *key;
-guint g_at_chat_send_listing(GAtChat *chat, const char *cmd,
- const char **prefix_list,
- GAtNotifyFunc listing, GAtResultFunc func,
- gpointer user_data, GDestroyNotify notify)
-{
- if (listing == NULL)
- return 0;
+ key = g_strdup(prefix);
- return send_common(chat, cmd, prefix_list, FALSE, listing, func,
- user_data, notify);
-}
+ if (!key)
+ return 0;
-guint g_at_chat_send_pdu_listing(GAtChat *chat, const char *cmd,
- const char **prefix_list,
- GAtNotifyFunc listing, GAtResultFunc func,
- gpointer user_data, GDestroyNotify notify)
-{
- if (listing == NULL)
+ notify = g_try_new0(struct at_notify, 1);
+ if (!notify) {
+ g_free(key);
return 0;
+ }
+
+ notify->pdu = pdu;
- return send_common(chat, cmd, prefix_list, TRUE, listing, func,
- user_data, notify);
+ g_hash_table_insert(chat->notify_list, key, notify);
+
+ return notify;
}
-gboolean g_at_chat_cancel(GAtChat *chat, guint id)
+static gboolean at_chat_cancel(struct at_chat *chat, guint group, guint id)
{
GList *l;
+ struct at_command *c;
- if (chat == NULL || chat->command_queue == NULL)
- return FALSE;
-
- /* We use id 0 for wakeup commands */
- if (id == 0)
+ if (chat->command_queue == NULL)
return FALSE;
l = g_queue_find_custom(chat->command_queue, GUINT_TO_POINTER(id),
if (!l)
return FALSE;
+ c = l->data;
+
+ if (c->gid != group)
+ return FALSE;
+
if (l == g_queue_peek_head(chat->command_queue) &&
chat->cmd_bytes_written > 0) {
- struct at_command *c = l->data;
-
/* We can't actually remove it since it is most likely
* already in progress, just null out the callback
* so it won't be called
*/
c->callback = NULL;
} else {
- at_command_destroy(l->data);
- g_queue_remove(chat->command_queue, l->data);
+ at_command_destroy(c);
+ g_queue_remove(chat->command_queue, c);
}
return TRUE;
}
-gboolean g_at_chat_cancel_all(GAtChat *chat)
+static gboolean at_chat_cancel_group(struct at_chat *chat, guint group)
{
int n = 0;
struct at_command *c;
- if (chat == NULL || chat->command_queue == NULL)
+ if (chat->command_queue == NULL)
return FALSE;
while ((c = g_queue_peek_nth(chat->command_queue, n)) != NULL) {
- if (c->id == 0) {
+ if (c->id == 0 || c->gid != group) {
n += 1;
continue;
}
return TRUE;
}
-static struct at_notify *at_notify_create(GAtChat *chat, const char *prefix,
- gboolean pdu)
-{
- struct at_notify *notify;
- char *key;
-
- key = g_strdup(prefix);
-
- if (!key)
- return 0;
-
- notify = g_try_new0(struct at_notify, 1);
- if (!notify) {
- g_free(key);
- return 0;
- }
-
- notify->pdu = pdu;
-
- g_hash_table_insert(chat->notify_list, key, notify);
-
- return notify;
-}
-
-guint g_at_chat_register(GAtChat *chat, const char *prefix,
- GAtNotifyFunc func, gboolean expect_pdu,
- gpointer user_data,
+static guint at_chat_register(struct at_chat *chat, guint group,
+ const char *prefix, GAtNotifyFunc func,
+ gboolean expect_pdu, gpointer user_data,
GDestroyNotify destroy_notify)
{
struct at_notify *notify;
struct at_notify_node *node;
- if (chat == NULL || chat->notify_list == NULL)
+ if (chat->notify_list == NULL)
return 0;
if (func == NULL)
return 0;
node->id = chat->next_notify_id++;
+ node->gid = group;
node->callback = func;
node->user_data = user_data;
node->notify = destroy_notify;
return node->id;
}
-gboolean g_at_chat_unregister(GAtChat *chat, guint id)
+static gboolean at_chat_unregister(struct at_chat *chat, guint group, guint id)
{
GHashTableIter iter;
struct at_notify *notify;
+ struct at_notify_node *node;
gpointer key, value;
GSList *l;
- if (chat == NULL || chat->notify_list == NULL)
+ if (chat->notify_list == NULL)
return FALSE;
g_hash_table_iter_init(&iter, chat->notify_list);
if (!l)
continue;
- at_notify_node_destroy(l->data, NULL);
- notify->nodes = g_slist_remove(notify->nodes, l->data);
+ node = l->data;
+
+ if (node->gid != group)
+ continue;
+
+ at_notify_node_destroy(node, NULL);
+ notify->nodes = g_slist_remove(notify->nodes, node);
if (notify->nodes == NULL)
g_hash_table_iter_remove(&iter);
return TRUE;
}
- return TRUE;
+ return FALSE;
}
-gboolean g_at_chat_unregister_all(GAtChat *chat)
+static gboolean at_chat_unregister_group(struct at_chat *chat, guint group)
{
GHashTableIter iter;
struct at_notify *notify;
+ struct at_notify_node *node;
gpointer key, value;
- GSList *l;
+ GSList *p;
+ GSList *c;
+ GSList *t;
- if (chat == NULL || chat->notify_list == NULL)
+ if (chat->notify_list == NULL)
return FALSE;
g_hash_table_iter_init(&iter, chat->notify_list);
while (g_hash_table_iter_next(&iter, &key, &value)) {
notify = value;
- for (l = notify->nodes; l; l = l->next)
- at_notify_node_destroy(l->data, NULL);
+ p = NULL;
+ c = notify->nodes;
+
+ while (c) {
+ node = c->data;
+
+ if (node->gid != group) {
+ p = c;
+ c = c->next;
+ continue;
+ }
+
+ if (p)
+ p->next = c->next;
+ else
+ notify->nodes = c->next;
+
+ at_notify_node_destroy(node, NULL);
- g_slist_free(notify->nodes);
- notify->nodes = NULL;
- g_hash_table_iter_remove(&iter);
+ t = c;
+ c = c->next;
+ g_slist_free_1(t);
+ }
+
+ if (notify->nodes == NULL)
+ g_hash_table_iter_remove(&iter);
}
return TRUE;
}
+static struct at_chat *create_chat(GIOChannel *channel, GIOFlags flags,
+ GAtSyntax *syntax)
+{
+ struct at_chat *chat;
+
+ if (!channel)
+ return NULL;
+
+ if (!syntax)
+ return NULL;
+
+ chat = g_try_new0(struct at_chat, 1);
+ if (!chat)
+ return chat;
+
+ chat->ref_count = 1;
+ chat->next_cmd_id = 1;
+ chat->next_notify_id = 1;
+ chat->debugf = NULL;
+
+ if (flags & G_IO_FLAG_NONBLOCK)
+ chat->io = g_at_io_new(channel);
+ else
+ chat->io = g_at_io_new_blocking(channel);
+
+ if (!chat->io)
+ goto error;
+
+ g_at_io_set_disconnect_function(chat->io, io_disconnect, chat);
+
+ chat->command_queue = g_queue_new();
+
+ if (!chat->command_queue)
+ goto error;
+
+ chat->notify_list = g_hash_table_new_full(g_str_hash, g_str_equal,
+ g_free, at_notify_destroy);
+
+ g_at_io_set_read_handler(chat->io, new_bytes, chat);
+
+ chat->syntax = g_at_syntax_ref(syntax);
+
+ return chat;
+
+error:
+ g_at_io_unref(chat->io);
+
+ if (chat->command_queue)
+ g_queue_free(chat->command_queue);
+
+ if (chat->notify_list)
+ g_hash_table_destroy(chat->notify_list);
+
+ g_free(chat);
+ return NULL;
+}
+
+static GAtChat *g_at_chat_new_common(GIOChannel *channel, GIOFlags flags,
+ GAtSyntax *syntax)
+{
+ GAtChat *chat;
+
+ chat = g_try_new0(GAtChat, 1);
+ if (chat == NULL)
+ return NULL;
+
+ chat->parent = create_chat(channel, flags, syntax);
+ if (chat->parent == NULL) {
+ g_free(chat);
+ return NULL;
+ }
+
+ chat->group = chat->parent->next_gid++;
+ chat->ref_count = 1;
+
+ return chat;
+}
+
+GAtChat *g_at_chat_new(GIOChannel *channel, GAtSyntax *syntax)
+{
+ return g_at_chat_new_common(channel, G_IO_FLAG_NONBLOCK, syntax);
+}
+
+GAtChat *g_at_chat_new_blocking(GIOChannel *channel, GAtSyntax *syntax)
+{
+ return g_at_chat_new_common(channel, 0, syntax);
+}
+
+GIOChannel *g_at_chat_get_channel(GAtChat *chat)
+{
+ if (chat == NULL || chat->parent->io == NULL)
+ return NULL;
+
+ return g_at_io_get_channel(chat->parent->io);
+}
+
+GAtIO *g_at_chat_get_io(GAtChat *chat)
+{
+ if (chat == NULL)
+ return NULL;
+
+ return chat->parent->io;
+}
+
+GAtChat *g_at_chat_ref(GAtChat *chat)
+{
+ if (chat == NULL)
+ return NULL;
+
+ g_atomic_int_inc(&chat->ref_count);
+
+ return chat;
+}
+
+void g_at_chat_suspend(GAtChat *chat)
+{
+ if (chat == NULL)
+ return;
+
+ at_chat_suspend(chat->parent);
+}
+
+void g_at_chat_resume(GAtChat *chat)
+{
+ if (chat == NULL)
+ return;
+
+ at_chat_resume(chat->parent);
+}
+
+void g_at_chat_unref(GAtChat *chat)
+{
+ gboolean is_zero;
+
+ if (chat == NULL)
+ return;
+
+ is_zero = g_atomic_int_dec_and_test(&chat->ref_count);
+
+ if (is_zero == FALSE)
+ return;
+
+ at_chat_cancel_group(chat->parent, chat->group);
+ at_chat_unregister_group(chat->parent, chat->group);
+ at_chat_unref(chat->parent);
+
+ g_free(chat);
+}
+
+gboolean g_at_chat_set_disconnect_function(GAtChat *chat,
+ GAtDisconnectFunc disconnect, gpointer user_data)
+{
+ if (chat == NULL || chat->group != 0)
+ return FALSE;
+
+ return at_chat_set_disconnect_function(chat->parent, disconnect,
+ user_data);
+}
+
+gboolean g_at_chat_set_debug(GAtChat *chat,
+ GAtDebugFunc func, gpointer user_data)
+{
+
+ if (chat == NULL || chat->group != 0)
+ return FALSE;
+
+ return at_chat_set_debug(chat->parent, func, user_data);
+}
+
+void g_at_chat_add_terminator(GAtChat *chat, char *terminator,
+ int len, gboolean success)
+{
+ if (chat == NULL || chat->group != 0)
+ return;
+
+ at_chat_add_terminator(chat->parent, terminator, len, success);
+}
+
gboolean g_at_chat_set_wakeup_command(GAtChat *chat, const char *cmd,
unsigned int timeout, unsigned int msec)
{
+ if (chat == NULL || chat->group != 0)
+ return FALSE;
+
+ return at_chat_set_wakeup_command(chat->parent, cmd, timeout, msec);
+}
+
+guint g_at_chat_send(GAtChat *chat, const char *cmd,
+ const char **prefix_list, GAtResultFunc func,
+ gpointer user_data, GDestroyNotify notify)
+{
+ return at_chat_send_common(chat->parent, chat->group,
+ cmd, prefix_list, FALSE, NULL,
+ func, user_data, notify);
+}
+
+guint g_at_chat_send_listing(GAtChat *chat, const char *cmd,
+ const char **prefix_list,
+ GAtNotifyFunc listing, GAtResultFunc func,
+ gpointer user_data, GDestroyNotify notify)
+{
+ if (listing == NULL)
+ return 0;
+
+ return at_chat_send_common(chat->parent, chat->group,
+ cmd, prefix_list, FALSE,
+ listing, func, user_data, notify);
+}
+
+guint g_at_chat_send_pdu_listing(GAtChat *chat, const char *cmd,
+ const char **prefix_list,
+ GAtNotifyFunc listing, GAtResultFunc func,
+ gpointer user_data, GDestroyNotify notify)
+{
+ if (listing == NULL)
+ return 0;
+
+ return at_chat_send_common(chat->parent, chat->group,
+ cmd, prefix_list, TRUE,
+ listing, func, user_data, notify);
+}
+
+gboolean g_at_chat_cancel(GAtChat *chat, guint id)
+{
+ /* We use id 0 for wakeup commands */
+ if (chat == NULL || id == 0)
+ return FALSE;
+
+ return at_chat_cancel(chat->parent, chat->group, id);
+}
+
+gboolean g_at_chat_cancel_all(GAtChat *chat)
+{
if (chat == NULL)
return FALSE;
- if (chat->wakeup)
- g_free(chat->wakeup);
+ return at_chat_cancel_group(chat->parent, chat->group);
+}
- chat->wakeup = g_strdup(cmd);
- chat->inactivity_time = (gdouble)msec / 1000;
- chat->wakeup_timeout = timeout;
+guint g_at_chat_register(GAtChat *chat, const char *prefix,
+ GAtNotifyFunc func, gboolean expect_pdu,
+ gpointer user_data,
+ GDestroyNotify destroy_notify)
+{
+ if (chat == NULL)
+ return 0;
- return TRUE;
+ return at_chat_register(chat->parent, chat->group, prefix,
+ func, expect_pdu, user_data, destroy_notify);
+}
+
+gboolean g_at_chat_unregister(GAtChat *chat, guint id)
+{
+ if (chat == NULL)
+ return FALSE;
+
+ return at_chat_unregister(chat->parent, chat->group, id);
+}
+
+gboolean g_at_chat_unregister_all(GAtChat *chat)
+{
+ if (chat == NULL)
+ return FALSE;
+
+ return at_chat_unregister_group(chat->parent, chat->group);
}