Separating the "hayes" plug-in into more parts
This commit is contained in:
parent
d530a48e13
commit
48c4ac170f
1
Makefile
1
Makefile
@ -103,6 +103,7 @@ dist:
|
||||
$(PACKAGE)-$(VERSION)/src/phone.h \
|
||||
$(PACKAGE)-$(VERSION)/src/project.conf \
|
||||
$(PACKAGE)-$(VERSION)/src/modems/debug.c \
|
||||
$(PACKAGE)-$(VERSION)/src/modems/hayes/command.c \
|
||||
$(PACKAGE)-$(VERSION)/src/modems/hayes.c \
|
||||
$(PACKAGE)-$(VERSION)/src/modems/purple.c \
|
||||
$(PACKAGE)-$(VERSION)/src/modems/sofia.c \
|
||||
|
@ -27,7 +27,7 @@ debug_LDFLAGS = $(LDFLAGSF) $(LDFLAGS) `pkg-config --libs gtk+-2.0 libSystem`
|
||||
debug.so: $(debug_OBJS)
|
||||
$(CCSHARED) -o debug.so $(debug_OBJS) $(debug_LDFLAGS)
|
||||
|
||||
hayes_OBJS = hayes.o
|
||||
hayes_OBJS = hayes/command.o hayes.o
|
||||
hayes_CFLAGS = $(CPPFLAGSF) $(CPPFLAGS) $(CFLAGSF) $(CFLAGS) `pkg-config --cflags libSystem`
|
||||
hayes_LDFLAGS = $(LDFLAGSF) $(LDFLAGS) `pkg-config --libs libSystem`
|
||||
|
||||
@ -58,7 +58,10 @@ template.so: $(template_OBJS)
|
||||
debug.o: debug.c
|
||||
$(CC) $(debug_CFLAGS) -c debug.c
|
||||
|
||||
hayes.o: hayes.c hayes.h
|
||||
hayes/command.o: hayes/command.c hayes/command.h
|
||||
$(CC) $(hayes_CFLAGS) -o hayes/command.o -c hayes/command.c
|
||||
|
||||
hayes.o: hayes.c hayes/command.h hayes.h
|
||||
$(CC) $(hayes_CFLAGS) -c hayes.c
|
||||
|
||||
purple.o: purple.c ../../config.h
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include <glib.h>
|
||||
#include <System.h>
|
||||
#include <Phone/modem.h>
|
||||
#include "hayes/command.h"
|
||||
#include "hayes.h"
|
||||
|
||||
#define max(a, b) ((a) > (b) ? (a) : (b))
|
||||
@ -106,57 +107,14 @@ typedef struct _ModemPlugin
|
||||
HayesChannel channel;
|
||||
} Hayes;
|
||||
|
||||
typedef enum _HayesCommandPriority
|
||||
{
|
||||
HCP_LOWER = 0,
|
||||
HCP_NORMAL,
|
||||
HCP_HIGHER,
|
||||
HCP_IMMEDIATE
|
||||
} HayesCommandPriority;
|
||||
|
||||
typedef enum _HayesCommandStatus
|
||||
{
|
||||
HCS_PENDING = 0,
|
||||
HCS_QUEUED,
|
||||
HCS_ACTIVE,
|
||||
HCS_TIMEOUT,
|
||||
HCS_ERROR,
|
||||
HCS_SUCCESS
|
||||
} HayesCommandStatus;
|
||||
#define HCS_LAST HCS_SUCCESS
|
||||
#define HCS_COUNT (HCS_LAST + 1)
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char * _hayes_command_status[HCS_COUNT] =
|
||||
static const char * hayes_command_status[HCS_COUNT] =
|
||||
{
|
||||
"HCS_PENDING", "HCS_QUEUED", "HCS_ACTIVE", "HCS_TIMEOUT", "HCS_ERROR",
|
||||
"HCS_SUCCESS"
|
||||
};
|
||||
#endif
|
||||
|
||||
typedef struct _HayesCommand HayesCommand;
|
||||
|
||||
typedef HayesCommandStatus (*HayesCommandCallback)(HayesCommand * command,
|
||||
HayesCommandStatus status, void * priv);
|
||||
|
||||
struct _HayesCommand
|
||||
{
|
||||
HayesCommandPriority priority;
|
||||
HayesCommandStatus status;
|
||||
|
||||
/* request */
|
||||
char * attention;
|
||||
unsigned int timeout;
|
||||
HayesCommandCallback callback;
|
||||
void * priv;
|
||||
|
||||
/* answer */
|
||||
char * answer;
|
||||
|
||||
/* XXX should be handled a better way */
|
||||
void * data;
|
||||
};
|
||||
|
||||
typedef struct _HayesRequestContactList
|
||||
{
|
||||
unsigned int from;
|
||||
@ -286,32 +244,6 @@ static int _hayes_queue_push(Hayes * hayes, HayesChannel * channel);
|
||||
|
||||
static void _hayes_reset(Hayes * hayes);
|
||||
|
||||
/* commands */
|
||||
static HayesCommand * _hayes_command_new(char const * attention);
|
||||
static void _hayes_command_delete(HayesCommand * command);
|
||||
static char const * _hayes_command_get_answer(HayesCommand * command);
|
||||
static char const * _hayes_command_get_attention(HayesCommand * command);
|
||||
static void * _hayes_command_get_data(HayesCommand * command);
|
||||
#if 0 /* XXX no longer being used */
|
||||
static char * _hayes_command_get_line(HayesCommand * command,
|
||||
char const * prefix);
|
||||
#endif
|
||||
static HayesCommandPriority _hayes_command_get_priority(HayesCommand * command);
|
||||
static HayesCommandStatus _hayes_command_get_status(HayesCommand * command);
|
||||
static unsigned int _hayes_command_get_timeout(HayesCommand * command);
|
||||
static void _hayes_command_set_callback(HayesCommand * command,
|
||||
HayesCommandCallback callback, void * priv);
|
||||
static void _hayes_command_set_data(HayesCommand * command, void * data);
|
||||
static void _hayes_command_set_priority(HayesCommand * command,
|
||||
HayesCommandPriority priority);
|
||||
static void _hayes_command_set_status(HayesCommand * command,
|
||||
HayesCommandStatus status);
|
||||
static void _hayes_command_set_timeout(HayesCommand * command,
|
||||
unsigned int timeout);
|
||||
static int _hayes_command_answer_append(HayesCommand * command,
|
||||
char const * answer);
|
||||
static HayesCommandStatus _hayes_command_callback(HayesCommand * command);
|
||||
|
||||
/* callbacks */
|
||||
static gboolean _on_queue_timeout(gpointer data);
|
||||
static gboolean _on_reset(gpointer data);
|
||||
@ -1109,16 +1041,16 @@ static int _parse_do(Hayes * hayes, HayesChannel * channel)
|
||||
: NULL;
|
||||
HayesCommandStatus status;
|
||||
|
||||
if(command == NULL || _hayes_command_get_status(command) != HCS_ACTIVE)
|
||||
if(command == NULL || hayes_command_get_status(command) != HCS_ACTIVE)
|
||||
/* this was most likely unsollicited */
|
||||
return _hayes_parse_trigger(hayes, channel, line, NULL);
|
||||
_hayes_parse_trigger(hayes, channel, line, command);
|
||||
if(_hayes_command_answer_append(command, line) != 0)
|
||||
if(hayes_command_answer_append(command, line) != 0)
|
||||
return -1;
|
||||
if((status = _hayes_command_get_status(command)) == HCS_ACTIVE)
|
||||
_hayes_command_callback(command);
|
||||
if((status = hayes_command_get_status(command)) == HCS_ACTIVE)
|
||||
hayes_command_callback(command);
|
||||
/* unqueue if complete */
|
||||
if((status = _hayes_command_get_status(command)) == HCS_SUCCESS
|
||||
if((status = hayes_command_get_status(command)) == HCS_SUCCESS
|
||||
|| status == HCS_ERROR || status == HCS_TIMEOUT)
|
||||
{
|
||||
_hayes_queue_pop(hayes, channel);
|
||||
@ -1163,7 +1095,7 @@ static int _hayes_parse_trigger(Hayes * hayes, HayesChannel * channel,
|
||||
}
|
||||
/* if the answer has no prefix choose it from the command issued */
|
||||
if(command == NULL
|
||||
|| (p = _hayes_command_get_attention(command)) == NULL
|
||||
|| (p = hayes_command_get_attention(command)) == NULL
|
||||
|| strncmp(p, "AT", 2) != 0)
|
||||
return 0;
|
||||
for(i = 0; i < count; i++)
|
||||
@ -1191,13 +1123,13 @@ static int _hayes_queue_command(Hayes * hayes, HayesChannel * channel,
|
||||
{
|
||||
case HAYES_MODE_INIT:
|
||||
/* ignore commands besides initialization */
|
||||
if(_hayes_command_get_priority(command)
|
||||
if(hayes_command_get_priority(command)
|
||||
!= HCP_IMMEDIATE)
|
||||
return -1;
|
||||
case HAYES_MODE_COMMAND:
|
||||
case HAYES_MODE_DATA:
|
||||
_hayes_command_set_status(command, HCS_QUEUED);
|
||||
if(_hayes_command_get_status(command) != HCS_QUEUED)
|
||||
hayes_command_set_status(command, HCS_QUEUED);
|
||||
if(hayes_command_get_status(command) != HCS_QUEUED)
|
||||
return -1;
|
||||
queue = channel->queue;
|
||||
channel->queue = g_slist_append(channel->queue,
|
||||
@ -1220,13 +1152,13 @@ static int _hayes_queue_command_full(Hayes * hayes,
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "DEBUG: %s(\"%s\")\n", __func__, attention);
|
||||
#endif
|
||||
if((command = _hayes_command_new(attention)) == NULL)
|
||||
if((command = hayes_command_new(attention)) == NULL)
|
||||
return -hayes->helper->error(hayes->helper->modem, error_get(),
|
||||
1);
|
||||
_hayes_command_set_callback(command, callback, hayes);
|
||||
hayes_command_set_callback(command, callback, hayes);
|
||||
if(_hayes_queue_command(hayes, command) != 0)
|
||||
{
|
||||
_hayes_command_delete(command);
|
||||
hayes_command_delete(command);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
@ -1237,11 +1169,11 @@ static int _hayes_queue_command_full(Hayes * hayes,
|
||||
/* hayes_queue_flush */
|
||||
static void _hayes_queue_flush(Hayes * hayes, HayesChannel * channel)
|
||||
{
|
||||
g_slist_foreach(channel->queue_timeout, (GFunc)_hayes_command_delete,
|
||||
g_slist_foreach(channel->queue_timeout, (GFunc)hayes_command_delete,
|
||||
NULL);
|
||||
g_slist_free(channel->queue_timeout);
|
||||
channel->queue_timeout = NULL;
|
||||
g_slist_foreach(channel->queue, (GFunc)_hayes_command_delete, NULL);
|
||||
g_slist_foreach(channel->queue, (GFunc)hayes_command_delete, NULL);
|
||||
g_slist_free(channel->queue);
|
||||
channel->queue = NULL;
|
||||
free(channel->rd_buf);
|
||||
@ -1282,7 +1214,7 @@ static int _hayes_queue_pop(Hayes * hayes, HayesChannel * channel)
|
||||
if(channel->queue == NULL) /* nothing to send */
|
||||
return 0;
|
||||
command = channel->queue->data; /* XXX assumes it's valid */
|
||||
_hayes_command_delete(command);
|
||||
hayes_command_delete(command);
|
||||
channel->queue = g_slist_remove(channel->queue, command);
|
||||
return 0;
|
||||
}
|
||||
@ -1308,11 +1240,11 @@ static int _hayes_queue_push(Hayes * hayes, HayesChannel * channel)
|
||||
#else
|
||||
return 0; /* XXX keep commands in the queue in DATA mode */
|
||||
#endif
|
||||
_hayes_command_set_status(command, HCS_ACTIVE);
|
||||
if(_hayes_command_get_status(command) != HCS_ACTIVE)
|
||||
hayes_command_set_status(command, HCS_ACTIVE);
|
||||
if(hayes_command_get_status(command) != HCS_ACTIVE)
|
||||
/* no longer push the command */
|
||||
return 0;
|
||||
attention = _hayes_command_get_attention(command);
|
||||
attention = hayes_command_get_attention(command);
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "DEBUG: %s() pushing \"%s\"\n", __func__, attention);
|
||||
#endif
|
||||
@ -1330,7 +1262,7 @@ static int _hayes_queue_push(Hayes * hayes, HayesChannel * channel)
|
||||
if(channel->timeout != 0)
|
||||
g_source_remove(channel->timeout);
|
||||
channel->timeout = 0;
|
||||
if((timeout = _hayes_command_get_timeout(command)) != 0)
|
||||
if((timeout = hayes_command_get_timeout(command)) != 0)
|
||||
channel->timeout = g_timeout_add(timeout, _on_timeout, channel);
|
||||
return 0;
|
||||
}
|
||||
@ -1411,19 +1343,19 @@ static int _hayes_request_channel(Hayes * hayes, HayesChannel * channel,
|
||||
attention = p;
|
||||
}
|
||||
/* XXX using _hayes_queue_command_full() was more elegant */
|
||||
command = _hayes_command_new(attention);
|
||||
command = hayes_command_new(attention);
|
||||
free(p);
|
||||
if(command == NULL)
|
||||
return -1;
|
||||
_hayes_command_set_callback(command,
|
||||
hayes_command_set_callback(command,
|
||||
_hayes_request_handlers[i].callback, channel);
|
||||
if(_hayes_queue_command(hayes, channel, command) != 0)
|
||||
{
|
||||
_hayes_command_delete(command);
|
||||
hayes_command_delete(command);
|
||||
return -1;
|
||||
}
|
||||
if(data != NULL)
|
||||
_hayes_command_set_data(command, data);
|
||||
hayes_command_set_data(command, data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1906,183 +1838,6 @@ static void _hayes_reset(Hayes * hayes)
|
||||
}
|
||||
|
||||
|
||||
/* commands */
|
||||
/* hayes_command_new */
|
||||
static HayesCommand * _hayes_command_new(char const * attention)
|
||||
{
|
||||
HayesCommand * command;
|
||||
|
||||
if((command = object_new(sizeof(*command))) == NULL)
|
||||
return NULL;
|
||||
command->priority = HCP_NORMAL;
|
||||
command->status = HCS_PENDING;
|
||||
command->attention = string_new(attention);
|
||||
command->timeout = 30000;
|
||||
command->callback = NULL;
|
||||
command->priv = NULL;
|
||||
command->answer = NULL;
|
||||
command->data = NULL;
|
||||
if(command->attention == NULL)
|
||||
{
|
||||
_hayes_command_delete(command);
|
||||
return NULL;
|
||||
}
|
||||
return command;
|
||||
}
|
||||
|
||||
|
||||
/* hayes_command_delete */
|
||||
static void _hayes_command_delete(HayesCommand * command)
|
||||
{
|
||||
string_delete(command->attention);
|
||||
string_delete(command->answer);
|
||||
object_delete(command);
|
||||
}
|
||||
|
||||
|
||||
/* hayes_command_get_answer */
|
||||
static char const * _hayes_command_get_answer(HayesCommand * command)
|
||||
{
|
||||
return command->answer;
|
||||
}
|
||||
|
||||
|
||||
/* hayes_command_get_attention */
|
||||
static char const * _hayes_command_get_attention(HayesCommand * command)
|
||||
{
|
||||
return command->attention;
|
||||
}
|
||||
|
||||
|
||||
/* hayes_command_get_data */
|
||||
static void * _hayes_command_get_data(HayesCommand * command)
|
||||
{
|
||||
return command->data;
|
||||
}
|
||||
|
||||
|
||||
#if 0 /* XXX no longer being used */
|
||||
/* hayes_command_get_line */
|
||||
static char * _hayes_command_get_line(HayesCommand * command,
|
||||
char const * prefix)
|
||||
{
|
||||
/* FIXME also return the other lines matching */
|
||||
char * ret;
|
||||
char const * answer = command->answer;
|
||||
size_t len;
|
||||
char * p;
|
||||
|
||||
if(prefix == NULL)
|
||||
return NULL;
|
||||
len = strlen(prefix);
|
||||
while(answer != NULL)
|
||||
if(strncmp(answer, prefix, len) == 0 && strncmp(&answer[len],
|
||||
": ", 2) == 0)
|
||||
{
|
||||
if((ret = string_new(&answer[len + 2])) != NULL
|
||||
&& (p = strchr(ret, '\n')) != NULL)
|
||||
*p = '\0';
|
||||
return ret;
|
||||
}
|
||||
else if((answer = strchr(answer, '\n')) != NULL)
|
||||
answer++;
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* hayes_command_get_priority */
|
||||
static HayesCommandPriority _hayes_command_get_priority(HayesCommand * command)
|
||||
{
|
||||
return command->priority;
|
||||
}
|
||||
|
||||
|
||||
/* hayes_command_get_status */
|
||||
static HayesCommandStatus _hayes_command_get_status(HayesCommand * command)
|
||||
{
|
||||
return command->status;
|
||||
}
|
||||
|
||||
|
||||
/* hayes_command_get_timeout */
|
||||
static unsigned int _hayes_command_get_timeout(HayesCommand * command)
|
||||
{
|
||||
return command->timeout;
|
||||
}
|
||||
|
||||
|
||||
/* hayes_command_set_callback */
|
||||
static void _hayes_command_set_callback(HayesCommand * command,
|
||||
HayesCommandCallback callback, void * priv)
|
||||
{
|
||||
command->callback = callback;
|
||||
command->priv = priv;
|
||||
}
|
||||
|
||||
|
||||
/* hayes_command_set_id */
|
||||
static void _hayes_command_set_data(HayesCommand * command, void * data)
|
||||
{
|
||||
command->data = data;
|
||||
}
|
||||
|
||||
|
||||
/* hayes_command_set_priority */
|
||||
static void _hayes_command_set_priority(HayesCommand * command,
|
||||
HayesCommandPriority priority)
|
||||
{
|
||||
command->priority = priority;
|
||||
}
|
||||
|
||||
|
||||
/* hayes_command_set_status */
|
||||
static void _hayes_command_set_status(HayesCommand * command,
|
||||
HayesCommandStatus status)
|
||||
{
|
||||
command->status = status;
|
||||
_hayes_command_callback(command);
|
||||
}
|
||||
|
||||
|
||||
/* hayes_command_set_timeout */
|
||||
static void _hayes_command_set_timeout(HayesCommand * command,
|
||||
unsigned int timeout)
|
||||
{
|
||||
command->timeout = timeout;
|
||||
}
|
||||
|
||||
|
||||
/* hayes_command_answer_append */
|
||||
static int _hayes_command_answer_append(HayesCommand * command,
|
||||
char const * answer)
|
||||
{
|
||||
char * p;
|
||||
|
||||
if(answer == NULL)
|
||||
return 0;
|
||||
if(command->answer == NULL)
|
||||
p = string_new(answer);
|
||||
else
|
||||
p = string_new_append(command->answer, "\n", answer, NULL);
|
||||
if(p == NULL)
|
||||
return -1;
|
||||
free(command->answer);
|
||||
command->answer = p;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* hayes_command_callback */
|
||||
static HayesCommandStatus _hayes_command_callback(HayesCommand * command)
|
||||
{
|
||||
if(command->callback != NULL)
|
||||
command->status = command->callback(command, command->status,
|
||||
command->priv);
|
||||
return command->status;
|
||||
}
|
||||
|
||||
|
||||
/* callbacks */
|
||||
/* on_queue_timeout */
|
||||
static gboolean _on_queue_timeout(gpointer data)
|
||||
@ -2295,18 +2050,18 @@ static gboolean _reset_settle(gpointer data)
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "DEBUG: %s()\n", __func__);
|
||||
#endif
|
||||
if((command = _hayes_command_new("ATZE0V1")) == NULL)
|
||||
if((command = hayes_command_new("ATZE0V1")) == NULL)
|
||||
{
|
||||
hayes->helper->error(hayes->helper->modem, error_get(), 1);
|
||||
return FALSE;
|
||||
}
|
||||
_hayes_command_set_callback(command, _on_reset_callback, channel);
|
||||
_hayes_command_set_priority(command, HCP_IMMEDIATE);
|
||||
_hayes_command_set_timeout(command, 500);
|
||||
hayes_command_set_callback(command, _on_reset_callback, channel);
|
||||
hayes_command_set_priority(command, HCP_IMMEDIATE);
|
||||
hayes_command_set_timeout(command, 500);
|
||||
if(_hayes_queue_command(hayes, channel, command) != 0)
|
||||
{
|
||||
hayes->helper->error(hayes->helper->modem, error_get(), 1);
|
||||
_hayes_command_delete(command);
|
||||
hayes_command_delete(command);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
@ -2319,7 +2074,7 @@ static HayesCommandStatus _on_reset_callback(HayesCommand * command,
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "DEBUG: %s(%s (%u))\n", __func__,
|
||||
_hayes_command_status[status], status);
|
||||
hayes_command_status[status], status);
|
||||
#endif
|
||||
status = _on_request_generic(command, status, hayes);
|
||||
switch(status)
|
||||
@ -2364,7 +2119,7 @@ static gboolean _on_timeout(gpointer data)
|
||||
channel->timeout = 0;
|
||||
if(channel->queue == NULL || (command = channel->queue->data) == NULL)
|
||||
return FALSE;
|
||||
_hayes_command_set_status(command, HCS_TIMEOUT);
|
||||
hayes_command_set_status(command, HCS_TIMEOUT);
|
||||
_hayes_queue_pop(hayes, channel);
|
||||
_hayes_queue_push(hayes, channel);
|
||||
return FALSE;
|
||||
@ -2808,7 +2563,7 @@ static HayesCommandStatus _on_request_generic(HayesCommand * command,
|
||||
|
||||
if(status != HCS_ACTIVE)
|
||||
return status;
|
||||
if((answer = _hayes_command_get_answer(command)) == NULL)
|
||||
if((answer = hayes_command_get_answer(command)) == NULL)
|
||||
return status;
|
||||
/* look for the last line */
|
||||
while((p = strchr(answer, '\n')) != NULL)
|
||||
@ -2829,10 +2584,10 @@ static HayesCommandStatus _on_request_message(HayesCommand * command,
|
||||
|
||||
if((status = _on_request_generic(command, status, priv)) == HCS_SUCCESS
|
||||
|| status == HCS_ERROR || status == HCS_TIMEOUT)
|
||||
if((data = _hayes_command_get_data(command)) != NULL)
|
||||
if((data = hayes_command_get_data(command)) != NULL)
|
||||
{
|
||||
free(data);
|
||||
_hayes_command_set_data(command, NULL);
|
||||
hayes_command_set_data(command, NULL);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
@ -2861,10 +2616,10 @@ static HayesCommandStatus _on_request_message_list(HayesCommand * command,
|
||||
|
||||
if((status = _on_request_generic(command, status, priv)) == HCS_SUCCESS
|
||||
|| status == HCS_ERROR || status == HCS_TIMEOUT)
|
||||
if((data = _hayes_command_get_data(command)) != NULL)
|
||||
if((data = hayes_command_get_data(command)) != NULL)
|
||||
{
|
||||
free(data);
|
||||
_hayes_command_set_data(command, NULL);
|
||||
hayes_command_set_data(command, NULL);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
@ -3030,7 +2785,7 @@ static void _on_code_call_error(HayesChannel * channel, char const * answer)
|
||||
? channel->queue->data : NULL;
|
||||
|
||||
if(command != NULL)
|
||||
_hayes_command_set_status(command, HCS_ERROR);
|
||||
hayes_command_set_status(command, HCS_ERROR);
|
||||
_hayes_request_type(hayes, channel, HAYES_REQUEST_PHONE_ACTIVE);
|
||||
}
|
||||
|
||||
@ -3224,7 +2979,7 @@ static void _on_code_cme_error(HayesChannel * channel, char const * answer)
|
||||
ModemEvent * event;
|
||||
|
||||
if(command != NULL)
|
||||
_hayes_command_set_status(command, HCS_ERROR);
|
||||
hayes_command_set_status(command, HCS_ERROR);
|
||||
if(sscanf(answer, "%u", &u) != 1)
|
||||
return;
|
||||
switch(u)
|
||||
@ -3244,12 +2999,11 @@ static void _on_code_cme_error(HayesChannel * channel, char const * answer)
|
||||
/* repeat the command */
|
||||
if(command == NULL)
|
||||
break;
|
||||
if((p = _hayes_command_new(command->attention)) == NULL)
|
||||
if((p = hayes_command_new_copy(command)) == NULL)
|
||||
break;
|
||||
_hayes_command_set_callback(p, command->callback,
|
||||
command->priv);
|
||||
_hayes_command_set_data(p, command->data);
|
||||
_hayes_command_set_data(command, NULL);
|
||||
hayes_command_set_data(p,
|
||||
hayes_command_get_data(command));
|
||||
hayes_command_set_data(command, NULL);
|
||||
channel->queue_timeout = g_slist_append(
|
||||
channel->queue_timeout, p);
|
||||
if(hayes->source == 0)
|
||||
@ -3303,7 +3057,7 @@ static void _on_code_cmgl(HayesChannel * channel, char const * answer)
|
||||
return;
|
||||
request.type = MODEM_REQUEST_MESSAGE;
|
||||
request.message.id = id;
|
||||
if(command != NULL && (data = _hayes_command_get_data(command)) != NULL)
|
||||
if(command != NULL && (data = hayes_command_get_data(command)) != NULL)
|
||||
{
|
||||
folder = data->folder;
|
||||
status = data->status;
|
||||
@ -3374,7 +3128,7 @@ static void _on_code_cmgr(HayesChannel * channel, char const * answer)
|
||||
if(event->message.length == 0) /* XXX assumes this is text mode */
|
||||
{
|
||||
/* FIXME guarantee this would not happen */
|
||||
if(command == NULL || (data = _hayes_command_get_data(command))
|
||||
if(command == NULL || (data = hayes_command_get_data(command))
|
||||
== NULL)
|
||||
return;
|
||||
event->message.id = data->id;
|
||||
@ -3391,7 +3145,7 @@ static void _on_code_cmgr(HayesChannel * channel, char const * answer)
|
||||
&event->message.length)) == NULL)
|
||||
return;
|
||||
/* FIXME guarantee this would not happen */
|
||||
if(command == NULL || (data = _hayes_command_get_data(command)) == NULL)
|
||||
if(command == NULL || (data = hayes_command_get_data(command)) == NULL)
|
||||
return;
|
||||
event->message.id = data->id;
|
||||
event->message.folder = data->folder;
|
||||
@ -3656,7 +3410,7 @@ static void _on_code_cms_error(HayesChannel * channel, char const * answer)
|
||||
HayesCommand * p;
|
||||
|
||||
if(command != NULL)
|
||||
_hayes_command_set_status(command, HCS_ERROR);
|
||||
hayes_command_set_status(command, HCS_ERROR);
|
||||
if(sscanf(answer, "%u", &u) != 1)
|
||||
return;
|
||||
switch(u)
|
||||
@ -3677,12 +3431,11 @@ static void _on_code_cms_error(HayesChannel * channel, char const * answer)
|
||||
/* FIXME duplicated from _on_code_cme_error() */
|
||||
if(command == NULL)
|
||||
break;
|
||||
if((p = _hayes_command_new(command->attention)) == NULL)
|
||||
if((p = hayes_command_new_copy(command)) == NULL)
|
||||
break;
|
||||
_hayes_command_set_callback(p, command->callback,
|
||||
command->priv);
|
||||
_hayes_command_set_data(p, command->data);
|
||||
_hayes_command_set_data(command, NULL);
|
||||
hayes_command_set_data(p,
|
||||
hayes_command_get_data(command));
|
||||
hayes_command_set_data(command, NULL);
|
||||
channel->queue_timeout = g_slist_append(
|
||||
channel->queue_timeout, p);
|
||||
if(hayes->source == 0)
|
||||
@ -3730,7 +3483,7 @@ static void _on_code_connect(HayesChannel * channel, char const * answer)
|
||||
GError * error = NULL;
|
||||
|
||||
if(command != NULL) /* XXX else report error? */
|
||||
_hayes_command_set_status(command, HCS_SUCCESS);
|
||||
hayes_command_set_status(command, HCS_SUCCESS);
|
||||
_hayes_set_mode(hayes, channel, HAYES_MODE_DATA);
|
||||
if(channel->gprs_username != NULL)
|
||||
argv[5] = channel->gprs_username;
|
||||
@ -4112,7 +3865,7 @@ static void _on_code_ext_error(HayesChannel * channel, char const * answer)
|
||||
unsigned int u;
|
||||
|
||||
if(command != NULL)
|
||||
_hayes_command_set_status(command, HCS_ERROR);
|
||||
hayes_command_set_status(command, HCS_ERROR);
|
||||
if(sscanf(answer, "%u", &u) != 1)
|
||||
return;
|
||||
switch(u)
|
||||
|
237
src/modems/hayes/command.c
Normal file
237
src/modems/hayes/command.c
Normal file
@ -0,0 +1,237 @@
|
||||
/* $Id$ */
|
||||
/* Copyright (c) 2014 Pierre Pronchery <khorben@defora.org> */
|
||||
/* This file is part of DeforaOS Desktop Phone */
|
||||
/* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 3 of the License.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
|
||||
|
||||
#if 0
|
||||
# include <string.h>
|
||||
#endif
|
||||
#include <System.h>
|
||||
#include "hayes/command.h"
|
||||
|
||||
|
||||
/* HayesCommand */
|
||||
/* private */
|
||||
/* types */
|
||||
struct _HayesCommand
|
||||
{
|
||||
HayesCommandPriority priority;
|
||||
HayesCommandStatus status;
|
||||
|
||||
/* request */
|
||||
String * attention;
|
||||
unsigned int timeout;
|
||||
HayesCommandCallback callback;
|
||||
void * priv;
|
||||
|
||||
/* answer */
|
||||
String * answer;
|
||||
|
||||
/* XXX should be handled a better way */
|
||||
void * data;
|
||||
};
|
||||
|
||||
|
||||
/* public */
|
||||
/* functions */
|
||||
/* hayes_command_new */
|
||||
HayesCommand * hayes_command_new(char const * attention)
|
||||
{
|
||||
HayesCommand * command;
|
||||
|
||||
if((command = object_new(sizeof(*command))) == NULL)
|
||||
return NULL;
|
||||
command->priority = HCP_NORMAL;
|
||||
command->status = HCS_PENDING;
|
||||
command->attention = string_new(attention);
|
||||
command->timeout = 30000;
|
||||
command->callback = NULL;
|
||||
command->priv = NULL;
|
||||
command->answer = NULL;
|
||||
command->data = NULL;
|
||||
if(command->attention == NULL)
|
||||
{
|
||||
hayes_command_delete(command);
|
||||
return NULL;
|
||||
}
|
||||
return command;
|
||||
}
|
||||
|
||||
|
||||
/* hayes_command_new_copy */
|
||||
HayesCommand * hayes_command_new_copy(HayesCommand const * command)
|
||||
{
|
||||
HayesCommand * ret;
|
||||
|
||||
if((ret = hayes_command_new(command->attention)) == NULL)
|
||||
return NULL;
|
||||
ret->priority = command->priority;
|
||||
ret->timeout = command->timeout;
|
||||
ret->callback = command->callback;
|
||||
ret->priv = command->priv;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* hayes_command_delete */
|
||||
void hayes_command_delete(HayesCommand * command)
|
||||
{
|
||||
string_delete(command->attention);
|
||||
string_delete(command->answer);
|
||||
object_delete(command);
|
||||
}
|
||||
|
||||
|
||||
/* hayes_command_get_answer */
|
||||
char const * hayes_command_get_answer(HayesCommand * command)
|
||||
{
|
||||
return command->answer;
|
||||
}
|
||||
|
||||
|
||||
/* hayes_command_get_attention */
|
||||
char const * hayes_command_get_attention(HayesCommand * command)
|
||||
{
|
||||
return command->attention;
|
||||
}
|
||||
|
||||
|
||||
/* hayes_command_get_data */
|
||||
void * hayes_command_get_data(HayesCommand * command)
|
||||
{
|
||||
return command->data;
|
||||
}
|
||||
|
||||
|
||||
#if 0 /* XXX no longer being used */
|
||||
/* hayes_command_get_line */
|
||||
char * hayes_command_get_line(HayesCommand * command,
|
||||
char const * prefix)
|
||||
{
|
||||
/* FIXME also return the other lines matching */
|
||||
char * ret;
|
||||
char const * answer = command->answer;
|
||||
size_t len;
|
||||
char * p;
|
||||
|
||||
if(prefix == NULL)
|
||||
return NULL;
|
||||
len = strlen(prefix);
|
||||
while(answer != NULL)
|
||||
if(strncmp(answer, prefix, len) == 0 && strncmp(&answer[len],
|
||||
": ", 2) == 0)
|
||||
{
|
||||
if((ret = string_new(&answer[len + 2])) != NULL
|
||||
&& (p = strchr(ret, '\n')) != NULL)
|
||||
*p = '\0';
|
||||
return ret;
|
||||
}
|
||||
else if((answer = strchr(answer, '\n')) != NULL)
|
||||
answer++;
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* hayes_command_get_priority */
|
||||
HayesCommandPriority hayes_command_get_priority(HayesCommand * command)
|
||||
{
|
||||
return command->priority;
|
||||
}
|
||||
|
||||
|
||||
/* hayes_command_get_status */
|
||||
HayesCommandStatus hayes_command_get_status(HayesCommand * command)
|
||||
{
|
||||
return command->status;
|
||||
}
|
||||
|
||||
|
||||
/* hayes_command_get_timeout */
|
||||
unsigned int hayes_command_get_timeout(HayesCommand * command)
|
||||
{
|
||||
return command->timeout;
|
||||
}
|
||||
|
||||
|
||||
/* hayes_command_set_callback */
|
||||
void hayes_command_set_callback(HayesCommand * command,
|
||||
HayesCommandCallback callback, void * priv)
|
||||
{
|
||||
command->callback = callback;
|
||||
command->priv = priv;
|
||||
}
|
||||
|
||||
|
||||
/* hayes_command_set_id */
|
||||
void hayes_command_set_data(HayesCommand * command, void * data)
|
||||
{
|
||||
command->data = data;
|
||||
}
|
||||
|
||||
|
||||
/* hayes_command_set_priority */
|
||||
void hayes_command_set_priority(HayesCommand * command,
|
||||
HayesCommandPriority priority)
|
||||
{
|
||||
command->priority = priority;
|
||||
}
|
||||
|
||||
|
||||
/* hayes_command_set_status */
|
||||
void hayes_command_set_status(HayesCommand * command,
|
||||
HayesCommandStatus status)
|
||||
{
|
||||
command->status = status;
|
||||
hayes_command_callback(command);
|
||||
}
|
||||
|
||||
|
||||
/* hayes_command_set_timeout */
|
||||
void hayes_command_set_timeout(HayesCommand * command,
|
||||
unsigned int timeout)
|
||||
{
|
||||
command->timeout = timeout;
|
||||
}
|
||||
|
||||
|
||||
/* hayes_command_answer_append */
|
||||
int hayes_command_answer_append(HayesCommand * command,
|
||||
char const * answer)
|
||||
{
|
||||
String * p;
|
||||
|
||||
if(answer == NULL)
|
||||
return 0;
|
||||
if(command->answer == NULL)
|
||||
p = string_new(answer);
|
||||
else
|
||||
p = string_new_append(command->answer, "\n", answer, NULL);
|
||||
if(p == NULL)
|
||||
return -1;
|
||||
string_delete(command->answer);
|
||||
command->answer = p;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* hayes_command_callback */
|
||||
HayesCommandStatus hayes_command_callback(HayesCommand * command)
|
||||
{
|
||||
if(command->callback != NULL)
|
||||
command->status = command->callback(command, command->status,
|
||||
command->priv);
|
||||
return command->status;
|
||||
}
|
80
src/modems/hayes/command.h
Normal file
80
src/modems/hayes/command.h
Normal file
@ -0,0 +1,80 @@
|
||||
/* $Id$ */
|
||||
/* Copyright (c) 2014 Pierre Pronchery <khorben@defora.org> */
|
||||
/* This file is part of DeforaOS Desktop Phone */
|
||||
/* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 3 of the License.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
|
||||
|
||||
#ifndef PHONE_MODEM_HAYES_COMMAND_H
|
||||
# define PHONE_MODEM_HAYES_COMMAND_H
|
||||
|
||||
|
||||
/* HayesCommand */
|
||||
/* public */
|
||||
/* types */
|
||||
typedef enum _HayesCommandPriority
|
||||
{
|
||||
HCP_LOWER = 0,
|
||||
HCP_NORMAL,
|
||||
HCP_HIGHER,
|
||||
HCP_IMMEDIATE
|
||||
} HayesCommandPriority;
|
||||
|
||||
typedef enum _HayesCommandStatus
|
||||
{
|
||||
HCS_PENDING = 0,
|
||||
HCS_QUEUED,
|
||||
HCS_ACTIVE,
|
||||
HCS_TIMEOUT,
|
||||
HCS_ERROR,
|
||||
HCS_SUCCESS
|
||||
} HayesCommandStatus;
|
||||
#define HCS_LAST HCS_SUCCESS
|
||||
#define HCS_COUNT (HCS_LAST + 1)
|
||||
|
||||
typedef struct _HayesCommand HayesCommand;
|
||||
|
||||
typedef HayesCommandStatus (*HayesCommandCallback)(HayesCommand * command,
|
||||
HayesCommandStatus status, void * priv);
|
||||
|
||||
|
||||
/* prototypes */
|
||||
HayesCommand * hayes_command_new(char const * attention);
|
||||
HayesCommand * hayes_command_new_copy(HayesCommand const * command);
|
||||
void hayes_command_delete(HayesCommand * command);
|
||||
|
||||
/* accessors */
|
||||
char const * hayes_command_get_answer(HayesCommand * command);
|
||||
char const * hayes_command_get_attention(HayesCommand * command);
|
||||
void * hayes_command_get_data(HayesCommand * command);
|
||||
#if 0 /* XXX no longer being used */
|
||||
char * hayes_command_get_line(HayesCommand * command,
|
||||
char const * prefix);
|
||||
#endif
|
||||
HayesCommandPriority hayes_command_get_priority(HayesCommand * command);
|
||||
HayesCommandStatus hayes_command_get_status(HayesCommand * command);
|
||||
unsigned int hayes_command_get_timeout(HayesCommand * command);
|
||||
void hayes_command_set_callback(HayesCommand * command,
|
||||
HayesCommandCallback callback, void * priv);
|
||||
void hayes_command_set_data(HayesCommand * command, void * data);
|
||||
void hayes_command_set_priority(HayesCommand * command,
|
||||
HayesCommandPriority priority);
|
||||
void hayes_command_set_status(HayesCommand * command,
|
||||
HayesCommandStatus status);
|
||||
void hayes_command_set_timeout(HayesCommand * command,
|
||||
unsigned int timeout);
|
||||
int hayes_command_answer_append(HayesCommand * command,
|
||||
char const * answer);
|
||||
HayesCommandStatus hayes_command_callback(HayesCommand * command);
|
||||
|
||||
#endif /* PHONE_MODEM_HAYES_COMMAND_H */
|
@ -16,13 +16,16 @@ install=$(LIBDIR)/Phone/modem
|
||||
|
||||
[hayes]
|
||||
type=plugin
|
||||
sources=hayes.c
|
||||
sources=hayes/command.c,hayes.c
|
||||
cflags=`pkg-config --cflags libSystem`
|
||||
ldflags=`pkg-config --libs libSystem`
|
||||
install=$(LIBDIR)/Phone/modem
|
||||
|
||||
[hayes.c]
|
||||
depends=hayes.h
|
||||
depends=hayes/command.h,hayes.h
|
||||
|
||||
[hayes/command.c]
|
||||
depends=hayes/command.h
|
||||
|
||||
[hayes.h]
|
||||
install=$(INCLUDEDIR)/Desktop/Phone/modems
|
||||
|
@ -47,8 +47,8 @@ modems.o: modems.c
|
||||
plugins.o: plugins.c
|
||||
$(CC) $(plugins_CFLAGS) -c plugins.c
|
||||
|
||||
ussd.o: ussd.c ../src/modems/hayes.c
|
||||
$(CC) $(ussd_CFLAGS) -c ussd.c
|
||||
ussd.o: ussd.c ../src/modems/hayes.c ../src/modems/hayes/command.c ../src/modems/hayes/command.h
|
||||
$(CC) -I ../src/modems $(ussd_CFLAGS) -c ussd.c
|
||||
|
||||
clean:
|
||||
$(RM) -- $(modems_OBJS) $(plugins_OBJS) $(ussd_OBJS) $(tests.log_OBJS)
|
||||
|
@ -23,4 +23,5 @@ type=binary
|
||||
sources=ussd.c
|
||||
|
||||
[ussd.c]
|
||||
depends=../src/modems/hayes.c
|
||||
cppflags=-I ../src/modems
|
||||
depends=../src/modems/hayes.c,../src/modems/hayes/command.c,../src/modems/hayes/command.h
|
||||
|
@ -15,6 +15,7 @@
|
||||
|
||||
|
||||
|
||||
#include "../src/modems/hayes/command.c"
|
||||
#include "../src/modems/hayes.c"
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user