gisi: Add message tracing and debugging support

This commit is contained in:
Aki Niemi 2010-12-03 09:55:04 +02:00
parent 7d6e163184
commit a1b20ae1da
2 changed files with 89 additions and 20 deletions

View File

@ -39,6 +39,10 @@
#include "modem.h" #include "modem.h"
#include "socket.h" #include "socket.h"
#define ISIDBG(m, fmt, ...) \
if ((m) != NULL && (m)->debug != NULL) \
m->debug("gisi: "fmt, ##__VA_ARGS__);
struct _GIsiServiceMux { struct _GIsiServiceMux {
GIsiModem *modem; GIsiModem *modem;
GSList *pending; GSList *pending;
@ -61,8 +65,8 @@ struct _GIsiModem {
int ind_fd; int ind_fd;
guint req_watch; guint req_watch;
guint ind_watch; guint ind_watch;
GIsiNotifyFunc debug; GIsiDebugFunc debug;
void *ddata; GIsiNotifyFunc trace;
void *opaque; void *opaque;
}; };
@ -120,11 +124,36 @@ static gint utid_equal(gconstpointer a, gconstpointer b)
return pa->utid - pb->utid; return pa->utid - pb->utid;
} }
static const char *pend_type_to_str(enum GIsiMessageType type)
{
switch (type) {
case GISI_MESSAGE_TYPE_REQ:
return "REQ";
case GISI_MESSAGE_TYPE_IND:
return "IND";
case GISI_MESSAGE_TYPE_NTF:
return "NTF";
case GISI_MESSAGE_TYPE_RESP:
return "RESP";
case GISI_MESSAGE_TYPE_COMMON:
return "COMMON";
}
return "UNKNOWN";
}
static void pending_dispatch(GIsiPending *pend, GIsiMessage *msg) static void pending_dispatch(GIsiPending *pend, GIsiMessage *msg)
{ {
if (!pend->notify) GIsiModem *modem;
if (pend->notify == NULL)
return; return;
modem = pend->service->modem;
ISIDBG(modem, "%s %s to %p [res=0x%02X, id=0x%02X, utid=0x%02X]",
g_isi_msg_strerror(msg), pend_type_to_str(pend->type), pend,
g_isi_msg_resource(msg), g_isi_msg_id(msg), g_isi_msg_utid(msg));
pend->notify(msg, pend->data); pend->notify(msg, pend->data);
} }
@ -221,6 +250,16 @@ static void common_message_decode(GIsiServiceMux *mux, GIsiMessage *msg)
msg->version = &mux->version; msg->version = &mux->version;
} }
static void firewall_notify_handle(GIsiModem *modem, GIsiMessage *msg)
{
uint8_t id;
if (!g_isi_msg_data_get_byte(msg, 0, &id))
return;
ISIDBG(modem, "firewall blocked message 0x%02X", id);
}
static gboolean isi_callback(GIOChannel *channel, GIOCondition cond, static gboolean isi_callback(GIOChannel *channel, GIOCondition cond,
gpointer data) gpointer data)
{ {
@ -229,7 +268,7 @@ static gboolean isi_callback(GIOChannel *channel, GIOCondition cond,
int fd; int fd;
if (cond & (G_IO_NVAL|G_IO_HUP)) { if (cond & (G_IO_NVAL|G_IO_HUP)) {
g_warning("Unexpected event on PhoNet channel %p", channel); ISIDBG(modem, "Unexpected event on PhoNet channel %p", channel);
return FALSE; return FALSE;
} }
@ -254,13 +293,21 @@ static gboolean isi_callback(GIOChannel *channel, GIOCondition cond,
msg.len = len; msg.len = len;
msg.version = &mux->version; msg.version = &mux->version;
if (modem->debug) if (modem->trace != NULL)
modem->debug(&msg, modem->ddata); modem->trace(&msg, NULL);
key = addr.spn_resource; key = addr.spn_resource;
mux = g_hash_table_lookup(modem->services, GINT_TO_POINTER(key)); mux = g_hash_table_lookup(modem->services, GINT_TO_POINTER(key));
if (!mux) if (mux == NULL) {
/*
* Unfortunately, the FW report has the wrong
* resource ID in the N900 modem.
*/
if (key == PN_FIREWALL)
firewall_notify_handle(modem, &msg);
return TRUE; return TRUE;
}
if (g_isi_msg_id(&msg) == COMMON_MESSAGE) if (g_isi_msg_id(&msg) == COMMON_MESSAGE)
common_message_decode(mux, &msg); common_message_decode(mux, &msg);
@ -321,7 +368,8 @@ static void service_name_register(GIsiServiceMux *mux)
uint16_t object = 0; uint16_t object = 0;
if (ioctl(mux->modem->req_fd, SIOCPNGETOBJECT, &object) < 0) { if (ioctl(mux->modem->req_fd, SIOCPNGETOBJECT, &object) < 0) {
g_warning("ioctl(SIOCPNGETOBJECT): %s", strerror(errno)); ISIDBG(mux->modem, "ioctl(SIOCPNGETOBJECT): %s",
strerror(errno));
return; return;
} }
@ -559,9 +607,9 @@ GIsiPending *g_isi_request_sendto(GIsiModem *modem, struct sockaddr_pn *dst,
destroy); destroy);
} }
static void vdebug(struct sockaddr_pn *dst, static void vtrace(struct sockaddr_pn *dst,
const struct iovec *__restrict iov, size_t iovlen, const struct iovec *__restrict iov, size_t iovlen,
size_t total_len, GIsiNotifyFunc debug, void *data) size_t total_len, GIsiNotifyFunc trace)
{ {
uint8_t buffer[total_len]; uint8_t buffer[total_len];
uint8_t *ptr = buffer; uint8_t *ptr = buffer;
@ -577,7 +625,7 @@ static void vdebug(struct sockaddr_pn *dst,
ptr += iov[i].iov_len; ptr += iov[i].iov_len;
} }
debug(&msg, data); trace(&msg, NULL);
} }
static gboolean resp_timeout(gpointer data) static gboolean resp_timeout(gpointer data)
@ -649,6 +697,7 @@ GIsiPending *g_isi_request_vsendto(GIsiModem *modem, struct sockaddr_pn *dst,
* transaction ID wraps, it's likely there is * transaction ID wraps, it's likely there is
* something wrong and we might as well fail here. * something wrong and we might as well fail here.
*/ */
ISIDBG(modem, "ERROR: UTID wrapped, modem busy");
errno = EBUSY; errno = EBUSY;
goto error; goto error;
} }
@ -661,8 +710,8 @@ GIsiPending *g_isi_request_vsendto(GIsiModem *modem, struct sockaddr_pn *dst,
len += iov[i].iov_len; len += iov[i].iov_len;
} }
if (modem->debug) if (modem->trace != NULL)
vdebug(dst, _iov, 1 + iovlen, len, modem->debug, modem->ddata); vtrace(dst, _iov, 1 + iovlen, len, modem->trace);
ret = sendmsg(modem->req_fd, &msg, MSG_NOSIGNAL); ret = sendmsg(modem->req_fd, &msg, MSG_NOSIGNAL);
if (ret == -1) if (ret == -1)
@ -749,6 +798,9 @@ GIsiPending *g_isi_ntf_subscribe(GIsiModem *modem, uint8_t resource,
mux->pending = g_slist_append(mux->pending, ntf); mux->pending = g_slist_append(mux->pending, ntf);
ISIDBG(modem, "Subscribed to %s (%p) [res=0x%02X, id=0x%02X]",
pend_type_to_str(ntf->type), ntf, resource, msgid);
return ntf; return ntf;
} }
@ -780,6 +832,9 @@ GIsiPending *g_isi_service_bind(GIsiModem *modem, uint8_t resource,
mux->pending = g_slist_append(mux->pending, srv); mux->pending = g_slist_append(mux->pending, srv);
ISIDBG(modem, "Bound service for %s (%p) [res=0x%02X, id=0x%02X]",
pend_type_to_str(srv->type), srv, resource, msgid);
service_regs_incr(mux); service_regs_incr(mux);
return srv; return srv;
@ -813,6 +868,9 @@ GIsiPending *g_isi_ind_subscribe(GIsiModem *modem, uint8_t resource,
mux->pending = g_slist_append(mux->pending, ind); mux->pending = g_slist_append(mux->pending, ind);
ISIDBG(modem, "Subscribed for %s (%p) [res=0x%02X, id=0x%02X]",
pend_type_to_str(ind->type), ind, resource, msgid);
service_subs_incr(mux); service_subs_incr(mux);
return ind; return ind;
@ -886,8 +944,8 @@ int g_isi_modem_vsendto(GIsiModem *modem, struct sockaddr_pn *dst,
for (i = 0, len = 0; i < iovlen; i++) for (i = 0, len = 0; i < iovlen; i++)
len += iov[i].iov_len; len += iov[i].iov_len;
if (modem->debug) if (modem->trace != NULL)
vdebug(dst, iov, iovlen, len, modem->debug, modem->ddata); vtrace(dst, iov, iovlen, len, modem->trace);
ret = sendmsg(modem->req_fd, &msg, MSG_NOSIGNAL); ret = sendmsg(modem->req_fd, &msg, MSG_NOSIGNAL);
if (ret == -1) if (ret == -1)
@ -899,13 +957,20 @@ int g_isi_modem_vsendto(GIsiModem *modem, struct sockaddr_pn *dst,
return 0; return 0;
} }
void g_isi_modem_set_debug(GIsiModem *modem, GIsiNotifyFunc debug, void *data) void g_isi_modem_set_trace(GIsiModem *modem, GIsiNotifyFunc trace)
{ {
if (!modem) if (modem == NULL)
return;
modem->trace = trace;
}
void g_isi_modem_set_debug(GIsiModem *modem, GIsiDebugFunc debug)
{
if (modem == NULL)
return; return;
modem->debug = debug; modem->debug = debug;
modem->ddata = data;
} }
static int version_get_send(GIsiModem *modem, GIsiPending *ping) static int version_get_send(GIsiModem *modem, GIsiPending *ping)
@ -1011,5 +1076,8 @@ GIsiPending *g_isi_resource_ping(GIsiModem *modem, uint8_t resource,
mux->pending = g_slist_prepend(mux->pending, ping); mux->pending = g_slist_prepend(mux->pending, ping);
mux->version_pending = TRUE; mux->version_pending = TRUE;
ISIDBG(modem, "Ping sent %s (%p) [res=0x%02X]",
pend_type_to_str(ping->type), ping, resource);
return ping; return ping;
} }

View File

@ -39,13 +39,14 @@ struct _GIsiPending;
typedef struct _GIsiPending GIsiPending; typedef struct _GIsiPending GIsiPending;
typedef void (*GIsiNotifyFunc)(const GIsiMessage *msg, void *opaque); typedef void (*GIsiNotifyFunc)(const GIsiMessage *msg, void *opaque);
typedef void (*GIsiDebugFunc)(const char *fmt, ...);
GIsiModem *g_isi_modem_create(unsigned index); GIsiModem *g_isi_modem_create(unsigned index);
GIsiModem *g_isi_modem_create_by_name(const char *name); GIsiModem *g_isi_modem_create_by_name(const char *name);
void g_isi_modem_destroy(GIsiModem *modem); void g_isi_modem_destroy(GIsiModem *modem);
unsigned g_isi_modem_index(GIsiModem *modem); unsigned g_isi_modem_index(GIsiModem *modem);
void g_isi_modem_set_debug(GIsiModem *modem, GIsiNotifyFunc notify, void g_isi_modem_set_trace(GIsiModem *modem, GIsiNotifyFunc notify);
void *opaque); void g_isi_modem_set_debug(GIsiModem *modem, GIsiDebugFunc debug);
void *g_isi_modem_set_userdata(GIsiModem *modem, void *data); void *g_isi_modem_set_userdata(GIsiModem *modem, void *data);
void *g_isi_modem_get_userdata(GIsiModem *modem); void *g_isi_modem_get_userdata(GIsiModem *modem);