Allow PRI to support callback functions (Diana's patch, placed in public domain)

git-svn-id: https://origsvn.digium.com/svn/libpri/trunk@202 2fbb986a-6c06-0410-b554-c9c1f0a7f128
This commit is contained in:
Mark Spencer
2005-03-17 15:46:23 +00:00
parent d7b60b28e0
commit 23a638cf66
5 changed files with 68 additions and 13 deletions

View File

@@ -376,6 +376,9 @@ typedef union {
struct pri;
struct pri_sr;
#define PRI_IO_FUNCS
/* Type declaration for callbacks to read or write a HDLC frame as below */
typedef int (*pri_io_cb)(struct pri *pri, void *buf, int buflen);
/* Create a D-channel on a given file descriptor. The file descriptor must be a
channel operating in HDLC mode with FCS computed by the fd's driver. Also it
@@ -383,6 +386,15 @@ struct pri_sr;
must be one of PRI_NETWORK or PRI_CPE. switchtype should be PRI_SWITCH_* */
extern struct pri *pri_new(int fd, int nodetype, int switchtype);
/* Create D-channel just as above with user defined I/O callbacks and data */
extern struct pri *pri_new_cb(int fd, int nodetype, int switchtype, pri_io_cb io_read, pri_io_cb io_write, void *userdata);
/* Retrieve the user data associated with the D channel */
extern void *pri_get_userdata(struct pri *pri);
/* Set the user data associated with the D channel */
extern void pri_set_userdata(struct pri *pri, void *userdata);
/* Set Network Specific Facility for PRI */
extern void pri_set_nsf(struct pri *pri, int nsf);

62
pri.c
View File

@@ -153,13 +153,38 @@ int pri_timer2idx(char *timer)
return -1;
}
static struct pri *__pri_new(int fd, int node, int switchtype, struct pri *master)
static int __pri_read(struct pri *pri, void *buf, int buflen)
{
int res = read(pri->fd, buf, buflen);
if (res < 0) {
if (errno != EAGAIN)
pri_error("Read on %d failed: %s\n", pri->fd, strerror(errno));
return 0;
}
return res;
}
static int __pri_write(struct pri *pri, void *buf, int buflen)
{
int res = write(pri->fd, buf, buflen);
if (res < 0) {
if (errno != EAGAIN)
pri_error("Write to %d failed: %s\n", pri->fd, strerror(errno));
return 0;
}
return res;
}
static struct pri *__pri_new(int fd, int node, int switchtype, struct pri *master, pri_io_cb rd, pri_io_cb wr, void *userdata)
{
struct pri *p;
p = malloc(sizeof(struct pri));
if (p) {
memset(p, 0, sizeof(struct pri));
p->fd = fd;
p->read_func = rd;
p->write_func = wr;
p->userdata = userdata;
p->localtype = node;
p->switchtype = switchtype;
p->cref = 1;
@@ -180,7 +205,7 @@ static struct pri *__pri_new(int fd, int node, int switchtype, struct pri *maste
p->protodisc = GR303_PROTOCOL_DISCRIMINATOR;
p->sapi = Q921_SAPI_GR303_EOC;
p->tei = Q921_TEI_GR303_EOC_OPS;
p->subchannel = __pri_new(-1, node, PRI_SWITCH_GR303_EOC_PATH, p);
p->subchannel = __pri_new(-1, node, PRI_SWITCH_GR303_EOC_PATH, p, NULL, NULL, NULL);
if (!p->subchannel) {
free(p);
p = NULL;
@@ -189,7 +214,7 @@ static struct pri *__pri_new(int fd, int node, int switchtype, struct pri *maste
p->protodisc = GR303_PROTOCOL_DISCRIMINATOR;
p->sapi = Q921_SAPI_GR303_TMC_CALLPROC;
p->tei = Q921_TEI_GR303_TMC_CALLPROC;
p->subchannel = __pri_new(-1, node, PRI_SWITCH_GR303_TMC_SWITCHING, p);
p->subchannel = __pri_new(-1, node, PRI_SWITCH_GR303_TMC_SWITCHING, p, NULL, NULL, NULL);
if (!p->subchannel) {
free(p);
p = NULL;
@@ -210,9 +235,29 @@ static struct pri *__pri_new(int fd, int node, int switchtype, struct pri *maste
return p;
}
struct pri *pri_new(int fd, int node, int switchtype)
struct pri *pri_new(int fd, int nodetype, int switchtype)
{
return __pri_new(fd, node, switchtype, NULL);
return __pri_new(fd, nodetype, switchtype, NULL, __pri_read, __pri_write, NULL);
}
struct pri *pri_new_cb(int fd, int nodetype, int switchtype, pri_io_cb io_read, pri_io_cb io_write, void *userdata)
{
if (!io_read)
io_read = __pri_read;
if (!io_write)
io_write = __pri_write;
return __pri_new(fd, nodetype, switchtype, NULL, io_read, io_write, userdata);
}
void *pri_get_userdata(struct pri *pri)
{
return pri ? pri->userdata : NULL;
}
void pri_set_userdata(struct pri *pri, void *userdata)
{
if (pri)
pri->userdata = userdata;
}
void pri_set_nsf(struct pri *pri, int nsf)
@@ -268,12 +313,7 @@ pri_event *pri_check_event(struct pri *pri)
char buf[1024];
int res;
pri_event *e;
res = read(pri->fd, buf, sizeof(buf));
if (res < 0) {
if (errno != EAGAIN)
pri_error("Read on %d failed: %s\n", pri->fd, strerror(errno));
return NULL;
}
res = pri->read_func ? pri->read_func(pri, buf, sizeof(buf)) : 0;
if (!res)
return NULL;
/* Receive the q921 packet */

View File

@@ -44,6 +44,9 @@ enum q931_mode;
struct pri {
int fd; /* File descriptor for D-Channel */
pri_io_cb read_func; /* Read data callback */
pri_io_cb write_func; /* Write data callback */
void *userdata;
struct pri *subchannel; /* Sub-channel if appropriate */
struct pri *master; /* Master channel if appropriate */
struct pri_sched pri_sched[MAX_SCHED]; /* Scheduled events */

2
q921.c
View File

@@ -83,7 +83,7 @@ static int q921_transmit(struct pri *pri, q921_h *h, int len)
if (pri->debug & PRI_DEBUG_Q921_DUMP)
q921_dump(h, len, pri->debug & PRI_DEBUG_Q921_RAW, 1);
/* Write an extra two bytes for the FCS */
res = write(pri->fd, h, len + 2);
res = pri->write_func ? pri->write_func(pri, h, len + 2) : 0;
if (res != (len + 2)) {
pri_error("Short write: %d/%d (%s)\n", res, len + 2, strerror(errno));
return -1;

2
q931.c
View File

@@ -1929,10 +1929,10 @@ static FUNC_RECV(receive_generic_digits)
}
if (len == 3) /* No number information */
return 0;
value = 0;
switch(type) {
/* Integer value handling */
case 4: /* Info Digits */
value = 0;
for(idx = 3; idx < len; ++idx) {
switch(encoding) {
case 0: /* BCD even */