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:
12
libpri.h
12
libpri.h
@@ -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
62
pri.c
@@ -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 */
|
||||
|
||||
@@ -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
2
q921.c
@@ -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
2
q931.c
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user