gisi: Add ISI version and reachability check API

This patch adds an API for querying the ISI version of the resource
with which the client is associated. This information is only
available after g_isi_verify() has been called on the client. This is
because we use the version query message as a vehicle for reachability
checking.
This commit is contained in:
Aki Niemi 2009-09-15 15:35:47 +03:00
parent bee4bf4d7d
commit 8bbd9a8560
4 changed files with 159 additions and 1 deletions

View File

@ -42,7 +42,7 @@ gdbus_sources = gdbus/gdbus.h gdbus/mainloop.c gdbus/object.c gdbus/watch.c
gisi_sources = gisi/phonet.h gisi/modem.h gisi/netlink.h gisi/netlink.c \
gisi/socket.h gisi/socket.c gisi/client.h gisi/client.c \
gisi/pep.h gisi/pep.c gisi/pipe.h gisi/pipe.c gisi/iter.h \
gisi/iter.c
gisi/iter.c gisi/verify.c
gatchat_sources = gatchat/gatchat.h gatchat/gatchat.c \
gatchat/gatresult.h gatchat/gatresult.c \

View File

@ -41,6 +41,10 @@
struct _GIsiClient {
uint8_t resource;
struct {
int major;
int minor;
} version;
GIsiModem *modem;
/* Requests */
@ -100,6 +104,8 @@ GIsiClient *g_isi_client_create(GIsiModem *modem, uint8_t resource)
abort();
cl = ptr;
cl->resource = resource;
cl->version.major = -1;
cl->version.minor = -1;
cl->modem = modem;
cl->debug_func = NULL;
memset(cl->timeout, 0, sizeof(cl->timeout));
@ -132,6 +138,43 @@ GIsiClient *g_isi_client_create(GIsiModem *modem, uint8_t resource)
return cl;
}
/**
* Set the ISI resource version of @a client.
* @param client client for the resource
* @param major ISI major version
* @param minor ISI minor version
*/
void g_isi_version_set(GIsiClient *client, int major, int minor)
{
if (!client)
return;
client->version.major = major;
client->version.minor = minor;
}
/**
* Returns the ISI major version of the resource associated with @a
* client.
* @param client client for the resource
* @return major version, -1 if not available
*/
int g_isi_version_major(GIsiClient *client)
{
return client->version.major;
}
/**
* Returns the ISI minor version of the resource associated with @a
* client.
* @param client client for the resource
* @return minor version, -1 if not available
*/
int g_isi_version_minor(GIsiClient *client)
{
return client->version.minor;
}
/**
* Returns the resource associated with @a client
* @param client client for the resource

View File

@ -38,6 +38,8 @@ typedef struct _GIsiClient GIsiClient;
struct _GIsiRequest;
typedef struct _GIsiRequest GIsiRequest;
typedef void (*GIsiVerifyFunc)(GIsiClient *client, bool alive, void *opaque);
typedef bool (*GIsiResponseFunc)(GIsiClient *client,
const void *restrict data, size_t len,
uint16_t object, void *opaque);
@ -51,8 +53,15 @@ typedef void (*GIsiDebugFunc) (const void *restrict data, size_t len,
GIsiClient *g_isi_client_create(GIsiModem *modem, uint8_t resource);
GIsiRequest *g_isi_verify(GIsiClient *client, GIsiVerifyFunc func,
void *opaque);
uint8_t g_isi_client_resource(GIsiClient *client);
void g_isi_version_set(GIsiClient *client, int major, int minor);
int g_isi_version_major(GIsiClient *client);
int g_isi_version_minor(GIsiClient *client);
void g_isi_client_set_debug(GIsiClient *client, GIsiDebugFunc func,
void *opaque);

106
gisi/verify.c Normal file
View File

@ -0,0 +1,106 @@
/*
* This file is part of oFono - Open Source Telephony
*
* Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
*
* Contact: Rémi Denis-Courmont <remi.denis-courmont@nokia.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
* 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, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdint.h>
#include <stdbool.h>
#include <glib.h>
#include "client.h"
#define VERSION_TIMEOUT 5
#define COMMON_MESSAGE 0xF0
#define COMM_ISI_VERSION_GET_REQ 0x12
#define COMM_ISI_VERSION_GET_RESP 0x13
#define COMM_ISA_ENTITY_NOT_REACHABLE_RESP 0x14
struct verify_data {
void *func;
void *data;
};
static bool verify_cb(GIsiClient *client, const void *restrict data,
size_t len, uint16_t object, void *opaque)
{
const uint8_t *msg = data;
struct verify_data *vd = opaque;
GIsiVerifyFunc func = vd->func;
bool alive = false;
if(!msg)
goto out;
if (len < 4 || msg[0] != COMMON_MESSAGE)
goto out;
if (msg[1] == COMM_ISI_VERSION_GET_RESP) {
g_isi_version_set(client, msg[2], msg[3]);
alive = true;
goto out;
}
if (msg[1] != COMM_ISA_ENTITY_NOT_REACHABLE_RESP)
alive = true;
out:
if (func)
func(client, alive, vd->data);
g_free(vd);
return true;
}
/**
* Verifies reachability of @a client with its resource. As a side
* effect of this liveliness check, the ISI version of the client
* resource will be made available via g_isi_client_version().
* @param client client to verify
* @param func callback to process outcome
* @param opaque user data
* @return NULL on error (see errno), GIsiRequest pointer on success.
*/
GIsiRequest *g_isi_verify(GIsiClient *client, GIsiVerifyFunc func,
void *opaque)
{
struct verify_data *data = g_try_new0(struct verify_data, 1);
GIsiRequest *req = NULL;
uint8_t msg[] = {
COMMON_MESSAGE,
COMM_ISI_VERSION_GET_REQ,
0x00 /* Filler */
};
data->func = func;
data->data = opaque;
req = g_isi_request_make(client, msg, sizeof(msg), VERSION_TIMEOUT,
verify_cb, data);
if (!req)
g_free(data);
return req;
}