Saturday, July 19, 2008

The key to zaptel

We need to have a deep understanding of the following structure to work with zaptel. This is the structure passed by individual driver to zaptel at the time of registration.

struct zt_span {
spinlock_t lock;
void *pvt; /* Private stuff */
char name[40]; /* Span name */
char desc[80]; /* Span description */
const char *spantype; /* span type in text form */
const char *manufacturer; /* span's device manufacturer */
char devicetype[80]; /* span's device type */
char location[40]; /* span device's location in system */
int deflaw; /* Default law (ZT_MULAW or ZT_ALAW) */
int alarms; /* Pending alarms on span */
int flags;
int irq; /* IRQ for this span's hardware */
int lbo; /* Span Line-Buildout */
int lineconfig; /* Span line configuration */
int linecompat; /* Span line compatibility */
int channels; /* Number of channels in span */
int txlevel; /* Tx level */
int rxlevel; /* Rx level */
int syncsrc; /* current sync src (gets copied here) */
unsigned int bpvcount; /* BPV counter */
unsigned int crc4count; /* CRC4 error counter */
unsigned int ebitcount; /* current E-bit error count */
unsigned int fascount; /* current FAS error count */

int maintstat; /* Maintenance state */
wait_queue_head_t maintq; /* Maintenance queue */
int mainttimer; /* Maintenance timer */

int irqmisses; /* Interrupt misses */

int timingslips; /* Clock slips */

struct zt_chan *chans; /* Member channel structures */

/* ==== Span Callback Operations ==== */
/* Req: Set the requested chunk size. This is the unit in which you must
report results for conferencing, etc */
int (*setchunksize)(struct zt_span *span, int chunksize);

/* Opt: Configure the span (if appropriate) */
int (*spanconfig)(struct zt_span *span, struct zt_lineconfig *lc);

/* Opt: Start the span */
int (*startup)(struct zt_span *span);

/* Opt: Shutdown the span */
int (*shutdown)(struct zt_span *span);

/* Opt: Enable maintenance modes */
int (*maint)(struct zt_span *span, int mode);

#ifdef ZAPTEL_SYNC_TICK
/* Opt: send sync to spans */
int (*sync_tick)(struct zt_span *span, int is_master);
#endif

/* ==== Channel Callback Operations ==== */
/* Opt: Set signalling type (if appropriate) */
int (*chanconfig)(struct zt_chan *chan, int sigtype);

/* Opt: Prepare a channel for I/O */
int (*open)(struct zt_chan *chan);

/* Opt: Close channel for I/O */
int (*close)(struct zt_chan *chan);

/* Opt: IOCTL */
int (*ioctl)(struct zt_chan *chan, unsigned int cmd, unsigned long data);

/* Opt: Native echo cancellation (simple) */
int (*echocan)(struct zt_chan *chan, int ecval);

int (*echocan_with_params)(struct zt_chan *chan, struct zt_echocanparams *ecp, struct zt_echocanparam *p);

/* Okay, now we get to the signalling. You have several options: */

/* Option 1: If you're a T1 like interface, you can just provide a
rbsbits function and we'll assert robbed bits for you. Be sure to
set the ZT_FLAG_RBS in this case. */

/* Opt: If the span uses A/B bits, set them here */
int (*rbsbits)(struct zt_chan *chan, int bits);

/* Option 2: If you don't know about sig bits, but do have their
equivalents (i.e. you can disconnect battery, detect off hook,
generate ring, etc directly) then you can just specify a
sethook function, and we'll call you with appropriate hook states
to set. Still set the ZT_FLAG_RBS in this case as well */
int (*hooksig)(struct zt_chan *chan, zt_txsig_t hookstate);

/* Option 3: If you can't use sig bits, you can write a function
which handles the individual hook states */
int (*sethook)(struct zt_chan *chan, int hookstate);

/* Opt: Dacs the contents of chan2 into chan1 if possible */
int (*dacs)(struct zt_chan *chan1, struct zt_chan *chan2);

/* Opt: Used to tell an onboard HDLC controller that there is data ready to transmit */
void (*hdlc_hard_xmit)(struct zt_chan *chan);

/* Used by zaptel only -- no user servicable parts inside */
int spanno; /* Span number for zaptel */
int offset; /* Offset within a given card */
int lastalarms; /* Previous alarms */

#ifdef CONFIG_DEVFS_FS
devfs_handle_t dhandle; /* Directory name */
#endif
/* If the watchdog detects no received data, it will call the
watchdog routine */
int (*watchdog)(struct zt_span *span, int cause);
#ifdef CONFIG_ZAPTEL_WATCHDOG
int watchcounter;
int watchstate;
#endif
};

No comments: