Wednesday, July 23, 2008

data flow

In a program, data flow diagrams are as important as the function call trees. As we now have some idea of the working how zaptel calls hardware specific functions, let us briefly see how the data is moving across zaptel and hardware drivers.

Responsible functions: ZAP_IRQ_HANDLER, tor2_run

data -> interrupt -> ZAP_IRQ_HANDLER -> tor2_run -> zt_receive / zt_transmit

Details soon...

Tuesday, July 22, 2008

open & close

Function: tor2_open
Argument: struct zt_chan *chan
Function: Do device specific open. In this case, just increments module usage count

Function: tor2_close
Argument: struct zt_chan *chan
Function: Do device specific open. In this case,just decrements module usage count

The call flow


Before we proceed further, let us have a look at the call flow. Asterisk calls the zaptel using system calls on the devices created by zaptel. A large chunk of such calls are ioctl calls.

To give an example, when a channel has to be configured, asterisk, through chan_zap.so, makes a ZT_CHANCONFIG ioctl. The user data is put into the form of zt_chanconfig structure and passed to the ioctl function.

zt_ctl_ioctl function is invoked as a result of this. This in turn does some generic operations such as error checking etc and then assigns the values from the user space structure to the kernel space structure.

When, there are device specific job to be done, zt_ctl_ioctl calls the device specific function that is already populated in the span structure that we used while registering our device with zaptel. In this particular case, they don't handle the clear function. For clear, they call the

res = chans[ch.chan]->span->chanconfig(chans[ch.chan], ch.sigtype);

In short, in this example we have seen
Asterisk <--> chan_zap.so <-> zaptel.ko (kernel) <-> device driver <-> Zaptel device <-> Phone/switch/PSTN

Monday, July 21, 2008

tor2_spanconfig

Arguments:
  1. struct zt_span *span - This is a pointer to current span structure on which the operation is taking place
  2. struct zt_lineconfig *lc - This is the user supplied data
Functionalities: This is used to set the parameters present in zaptel.conf to the driver. The parameters are present in the lc structure. These parameters are extracted and set in the span structure. In tor2.c, this function is responsible mainly for changing the sync source status of the span.

sync source status of the span: Is whether the current span is an input source, output source or a sink of a time pulse.

This function also takes care about restarting the card if it is currently running


static int tor2_spanconfig(struct zt_span *span, struct zt_lineconfig *lc)
{
int i;
struct tor2_span *p = span->pvt;

if (debug)
printk("Tor2: Configuring span %d\n", span->spanno);

span->syncsrc = p->tor->syncsrc;

/* remove this span number from the current sync sources, if there */
for (i = 0; i <>tor->syncs[i] == span->spanno) {
p->tor->syncs[i] = 0;
p->tor->psyncs[i] = 0;
}
}
p->tor->syncpos[p->span] = lc->sync;
/* if a sync src, put it in the proper place */
if (lc->sync) {
p->tor->syncs[lc->sync - 1] = span->spanno;
p->tor->psyncs[lc->sync - 1] = p->span + 1;
}
/* If we're already running, then go ahead and apply the changes */
if (span->flags & ZT_FLAG_RUNNING)
return tor2_startup(span);

return 0;
}

Moral of my asterisk story

Very simple...

If you have to make a PRI E1/T1 card driver compatible with asterisk...

1. The driver should define span structure
2. The driver should define functions such as ioctl, spanconfig, open, close, rbsbits etc
3. The span variables should be populated with corresponding functions and values
4. In the device init, call zt_register with the populated span.

Next: What are the functions of methods populated in span?