mISDNuser/include/isdn_net.h

297 lines
6.6 KiB
C

#ifndef ISDN_NET_H
#define ISDN_NET_H
#include <stdlib.h>
#include <errno.h>
#include <pthread.h>
#include <semaphore.h>
#include "mISDNlib.h"
#include "isdn_msg.h"
#include "isdn_debug.h"
#include "ibuffer.h"
#define MSN_LEN 32
#define SUBADR_LEN 24
#define UUS_LEN 256
#define FAC_LEN 132
#ifndef mISDN_FRAME_MIN
#define mISDN_FRAME_MIN 8
#endif
typedef struct _layer2 layer2_t;
typedef struct _layer3 layer3_t;
typedef struct _layer4 layer4_t;
typedef struct _bchannel bchannel_t;
typedef struct _mISDNif mISDNif_t;
typedef struct _mISDNinstance mISDNinstance_t;
typedef struct _net_stack net_stack_t;
typedef struct _manager manager_t;
typedef struct _nr_list nr_list_t;
typedef int (*ifunc_t)(net_stack_t *, msg_t *);
typedef int (*bfunc_t)(void *, void *);
typedef int (*afunc_t)(manager_t *, int, void *);
#define MAX_BDATA_SIZE 2048
struct _bchannel {
sem_t work;
msg_queue_t workq;
pthread_t tid;
manager_t *manager;
void *app;
int channel;
pthread_mutex_t lock;
int cstate;
int bstate;
int l3id;
int b_addr;
int Flags;
int ttime;
nr_list_t *usednr;
int l1_prot;
unsigned char bc[8];
unsigned char uu[UUS_LEN];
unsigned char fac[FAC_LEN];
unsigned char nr[MSN_LEN];
unsigned char msn[MSN_LEN];
unsigned char clisub[SUBADR_LEN];
unsigned char cldsub[SUBADR_LEN];
int cause_loc;
int cause_val;
unsigned char display[84];
msg_t *smsg;
ibuffer_t *rbuf;
ibuffer_t *sbuf;
int rrid;
int rsid;
};
struct _manager {
manager_t *prev;
manager_t *next;
bchannel_t bc[2];
nr_list_t *nrlist;
net_stack_t *nst;
bfunc_t man2stack;
afunc_t application;
afunc_t app_bc;
pthread_t tid;
sem_t work;
msg_queue_t workq;
};
#define PR_APP_CHECK_NR 1
#define PR_APP_ICALL 2
#define PR_APP_OCHANNEL 3
#define PR_APP_OCALL 4
#define PR_APP_ALERT 5
#define PR_APP_CONNECT 6
#define PR_APP_HANGUP 7
#define PR_APP_CLEAR 8
#define PR_APP_USERUSER 9
#define PR_APP_FACILITY 10
#define PR_APP_OPEN_RECFILES 11
#define PR_APP_CLOSE_RECFILES 12
#define FLG_NST_READER_ABORT 1
#define FLG_NST_TERMINATION 2
struct _net_stack {
int device;
int cardnr;
int d_stid;
int l0_id;
int l1_id;
int l2_id;
msg_t *phd_down_msg;
layer2_t *layer2;
layer3_t *layer3;
ifunc_t l1_l2;
ifunc_t l2_l3;
ifunc_t l3_l2;
ifunc_t manager_l3;
bfunc_t l3_manager;
manager_t *manager;
msg_queue_t down_queue;
msg_queue_t rqueue;
msg_queue_t wqueue;
sem_t work;
pthread_mutex_t lock;
pthread_t reader;
int b_stid[2];
int b_addr[2];
int bcid[2];
int flag;
struct _itimer *tlist;
};
struct _nr_list {
nr_list_t *prev;
nr_list_t *next;
unsigned char len;
unsigned char nr[MSN_LEN];
unsigned char name[64];
int typ;
int flags;
};
#define NR_TYPE_INTERN 1
#define NR_TYPE_AUDIO 2
#define NR_TYPE_VOIP 3
typedef struct _itimer {
struct _itimer *prev;
struct _itimer *next;
net_stack_t *nst;
int id;
int expires;
int Flags;
unsigned long data;
int (*function)(unsigned long);
} itimer_t;
#define FLG_TIMER_RUNING 1
#define FLG_BC_USE 0x00000001
#define FLG_BC_SENT_CID 0x00000002
#define FLG_BC_CALL_ORGINATE 0x00000004
#define FLG_BC_PROGRESS 0x00000008
#define FLG_BC_APPLICATION 0x00000010
#define FLG_BC_TONE_DIAL 0x00000100
#define FLG_BC_TONE_BUSY 0x00000200
#define FLG_BC_TONE_ALERT 0x00000400
#define FLG_BC_TONE_SILENCE 0x00000800
#define FLG_BC_TONE_NONE 0x00000000
#define FLG_BC_TONE 0x00000F00
#define FLG_BC_RECORD 0x00010000
#define FLG_BC_RECORDING 0x00020000
#define FLG_BC_RAWDEVICE 0x01000000
#define FLG_BC_KEEP_SEND 0x02000000
#define FLG_BC_TERMINATE 0x08000000
#define MSG_L1_PRIM 0x010000
#define MSG_L2_PRIM 0x020000
#define MSG_L3_PRIM 0x030000
extern int do_net_stack_setup(net_stack_t *);
extern int do_net_stack_cleanup(net_stack_t *nst);
extern void *do_netthread(void *);
extern int term_netstack(net_stack_t *nst);
extern int init_manager(manager_t **mlist, afunc_t application);
extern int cleanup_manager(manager_t *mgr);
extern int write_dmsg(net_stack_t *, msg_t *);
extern int phd_conf(net_stack_t *, iframe_t *, msg_t *);
extern int init_timer(itimer_t *, net_stack_t *);
extern int add_timer(itimer_t *);
extern int del_timer(itimer_t *);
extern int remove_timer(itimer_t *it);
extern int timer_pending(itimer_t *);
extern u_char *findie(u_char *, int, u_char, int);
extern u_char *find_and_copy_ie(u_char *, int, u_char, int, msg_t *);
extern void display_NR_IE(u_char *, char *);
extern int match_nr(manager_t *mgr, unsigned char *nx, nr_list_t **nrx);
typedef struct _mISDN_head {
u_int prim;
int dinfo;
} mISDN_head_t;
#define mISDN_HEAD_SIZE sizeof(mISDN_head_t)
/* interface msg help routines */
static inline void mISDN_newhead(u_int prim, int dinfo, msg_t *msg)
{
mISDN_head_t *hh = (mISDN_head_t *)msg->data;
hh->prim = prim;
hh->dinfo = dinfo;
}
static inline int if_newhead(void *arg, ifunc_t func, u_int prim, int dinfo,
msg_t *msg)
{
if (!msg)
return(-ENXIO);
mISDN_newhead(prim, dinfo, msg);
return(func(arg, msg));
}
static inline void mISDN_addhead(u_int prim, int dinfo, msg_t *msg)
{
mISDN_head_t *hh = (mISDN_head_t *)msg_push(msg, mISDN_HEAD_SIZE);
hh->prim = prim;
hh->dinfo = dinfo;
}
static inline int if_addhead(void *arg, ifunc_t func, u_int prim, int dinfo,
msg_t *msg)
{
if (!msg)
return(-ENXIO);
mISDN_addhead(prim, dinfo, msg);
return(func(arg, msg));
}
static inline msg_t *create_link_msg(u_int prim, int dinfo,
int len, void *arg, int reserve)
{
msg_t *msg;
if (!(msg = alloc_msg(len + mISDN_HEAD_SIZE + reserve))) {
wprint("%s: no msg size %d+%d+%d\n", __FUNCTION__,
len, mISDN_HEAD_SIZE, reserve);
return(NULL);
} else
msg_reserve(msg, reserve + mISDN_HEAD_SIZE);
if (len)
memcpy(msg_put(msg, len), arg, len);
mISDN_addhead(prim, dinfo, msg);
return(msg);
}
static inline int if_link(void *farg, ifunc_t func, u_int prim, int dinfo, int len,
void *arg, int reserve)
{
msg_t *msg;
int err;
if (!(msg = create_link_msg(prim, dinfo, len, arg, reserve)))
return(-ENOMEM);
err = func(farg, msg);
if (err)
free_msg(msg);
return(err);
}
static inline msg_t *prep_l3data_msg(u_int prim, int dinfo, int ssize, int dsize, msg_t *old)
{
if (!old) {
old = alloc_msg(ssize + dsize + mISDN_HEAD_SIZE + DEFAULT_HEADROOM);
if (!old) {
wprint("%s: no msg size %d+%d+%d\n", __FUNCTION__,
ssize, dsize, mISDN_HEAD_SIZE + DEFAULT_HEADROOM);
return(NULL);
}
} else {
old->data = old->head + DEFAULT_HEADROOM;
old->tail = old->data;
old->len = 0;
}
memset(msg_put(old, ssize + mISDN_HEAD_SIZE), 0,
ssize + mISDN_HEAD_SIZE);
mISDN_newhead(prim, dinfo, old);
return(old);
}
#endif