/* $Id: isdn_divert.c,v 1.6.6.3 2001/09/23 22:24:36 kai Exp $
 *
 * DSS1 main diversion supplementary handling for i4l.
 *
 * Copyright 1999       by Werner Cornelius (werner@isdn4linux.de)
 *
 * This software may be used and distributed according to the terms
 * of the GNU General Public License, incorporated herein by reference.
 *
 */

#include <linux/proc_fs.h>
#include <linux/slab.h>
#include <linux/timer.h>
#include <linux/jiffies.h>

#include "isdn_divert.h"

/**********************************/
/* structure keeping calling info */
/**********************************/
struct call_struc {
	isdn_ctrl ics; /* delivered setup + driver parameters */
	ulong divert_id; /* Id delivered to user */
	unsigned char akt_state; /* actual state */
	char deflect_dest[35]; /* deflection destination */
	struct timer_list timer; /* timer control structure */
	char info[90]; /* device info output */
	struct call_struc *next; /* pointer to next entry */
	struct call_struc *prev;
};


/********************************************/
/* structure keeping deflection table entry */
/********************************************/
struct deflect_struc {
	struct deflect_struc *next, *prev;
	divert_rule rule; /* used rule */
};


/*****************************************/
/* variables for main diversion services */
/*****************************************/
/* diversion/deflection processes */
static struct call_struc *divert_head = NULL; /* head of remembered entrys */
static ulong next_id = 1; /* next info id */
static struct deflect_struc *table_head = NULL;
static struct deflect_struc *table_tail = NULL;
static unsigned char extern_wait_max = 4; /* maximum wait in s for external process */

DEFINE_SPINLOCK(divert_lock);

/***************************/
/* timer callback function */
/***************************/
static void deflect_timer_expire(ulong arg)
{
	unsigned long flags;
	struct call_struc *cs = (struct call_struc *) arg;

	spin_lock_irqsave(&divert_lock, flags);
	del_timer(&cs->timer); /* delete active timer */
	spin_unlock_irqrestore(&divert_lock, flags);

	switch (cs->akt_state) {
	case DEFLECT_PROCEED:
		cs->ics.command = ISDN_CMD_HANGUP; /* cancel action */
		divert_if.ll_cmd(&cs->ics);
		spin_lock_irqsave(&divert_lock, flags);
		cs->akt_state = DEFLECT_AUTODEL; /* delete after timeout */
		cs->timer.expires = jiffies + (HZ * AUTODEL_TIME);
		add_timer(&cs->timer);
		spin_unlock_irqrestore(&divert_lock, flags);
		break;

	case DEFLECT_ALERT:
		cs->ics.command = ISDN_CMD_REDIR; /* protocol */
		strlcpy(cs->ics.parm.setup.phone, cs->deflect_dest, sizeof(cs->ics.parm.setup.phone));
		strcpy(cs->ics.parm.setup.eazmsn, "Testtext delayed");
		divert_if.ll_cmd(&cs->ics);
		spin_lock_irqsave(&divert_lock, flags);
		cs->akt_state = DEFLECT_AUTODEL; /* delete after timeout */
		cs->timer.expires = jiffies + (HZ * AUTODEL_TIME);
		add_timer(&cs->timer);
		spin_unlock_irqrestore(&divert_lock, flags);
		break;

	case DEFLECT_AUTODEL:
	default:
		spin_lock_irqsave(&divert_lock, flags);
		if (cs->prev)
			cs->prev->next = cs->next; /* forward link */
		else
			divert_head = cs->next;
		if (cs->next)
			cs->next->prev = cs->prev; /* back link */
		spin_unlock_irqrestore(&divert_lock, flags);
		kfree(cs);
		return;

	} /* switch */
} /* deflect_timer_func */


/*****************************************/
/* handle call forwarding de/activations */
/* 0 = deact, 1 = act, 2 = interrogate   */
/*****************************************/
int cf_command(int drvid, int mode,
	       u_char proc, char *msn,
	       u_char service, char *fwd_nr, ulong *procid)
{
	unsigned long flags;
	int retval, msnlen;
	int fwd_len;
	char *p, *ielenp, tmp[60];
	struct call_struc *cs;

	if (strchr(msn, '.')) return (-EINVAL); /* subaddress not allowed in msn */
	if ((proc & 0x7F) > 2) return (-EINVAL);
	proc &= 3;
	p = tmp;
	*p++ = 0x30; /* enumeration */
	ielenp = p++; /* remember total length position */
	*p++ = 0xa; /* proc tag */
	*p++ = 1;   /* length */
	*p++ = proc & 0x7F; /* procedure to de/activate/interrogate */
	*p++ = 0xa; /* service tag */
	*p++ = 1;   /* length */
	*p++ = service; /* service to handle */

	if (mode == 1) {
		if (!*fwd_nr) return (-EINVAL); /* destination missing */
		if (strchr(fwd_nr, '.')) return (-EINVAL); /* subaddress not allowed */
		fwd_len = strlen(fwd_nr);
		*p++ = 0x30; /* number enumeration */
		*p++ = fwd_len + 2; /* complete forward to len */
		*p++ = 0x80; /* fwd to nr */
		*p++ = fwd_len; /* length of number */
		strcpy(p, fwd_nr); /* copy number */
		p += fwd_len; /* pointer beyond fwd */
	} /* activate */

	msnlen = strlen(msn);
	*p++ = 0x80; /* msn number */
	if (msnlen > 1) {
		*p++ = msnlen; /* length */
		strcpy(p, msn);
		p += msnlen;
	} else
		*p++ = 0;

	*ielenp = p - ielenp - 1; /* set total IE length */

	/* allocate mem for information struct */
	if (!(cs = kmalloc(sizeof(struct call_struc), GFP_ATOMIC)))
		return (-ENOMEM); /* no memory */
	init_timer(&cs->timer);
	cs->info[0] = '\0';
	cs->timer.function = deflect_timer_expire;
	cs->timer.data = (ulong) cs; /* pointer to own structure */
	cs->ics.driver = drvid;
	cs->ics.command = ISDN_CMD_PROT_IO; /* protocol specific io */
	cs->ics.arg = DSS1_CMD_INVOKE; /* invoke supplementary service */
	cs->ics.parm.dss1_io.proc = (mode == 1) ? 7 : (mode == 2) ? 11 : 8; /* operation */
	cs->ics.parm.dss1_io.timeout = 4000; /* from ETS 300 207-1 */
	cs->ics.parm.dss1_io.datalen = p - tmp; /* total len */
	cs->ics.parm.dss1_io.data = tmp; /* start of buffer */

	spin_lock_irqsave(&divert_lock, flags);
	cs->ics.parm.dss1_io.ll_id = next_id++; /* id for callback */
	spin_unlock_irqrestore(&divert_lock, flags);
	*procid = cs->ics.parm.dss1_io.ll_id;

	sprintf(cs->info, "%d 0x%lx %s%s 0 %s %02x %d%s%s\n",
		(!mode) ? DIVERT_DEACTIVATE : (mode == 1) ? DIVERT_ACTIVATE : DIVERT_REPORT,
		cs->ics.parm.dss1_io.ll_id,
		(mode != 2) ? "" : "0 ",
		divert_if.drv_to_name(cs->ics.driver),
		msn,
		service & 0xFF,
		proc,
		(mode != 1) ? "" : " 0 ",
		(mode != 1) ? "" : fwd_nr);

	retval = divert_if.ll_cmd(&cs->ics); /* execute command */

	if (!retval) {
		cs->prev = NULL;
		spin_lock_irqsave(&divert_lock, flags);
		cs->next = divert_head;
		divert_head = cs;
		spin_unlock_irqrestore(&divert_lock, flags);
	} else
		kfree(cs);
	return (retval);
} /* cf_command */


/****************************************/
/* handle a external deflection command */
/****************************************/
int deflect_extern_action(u_char cmd, ulong callid, char *to_nr)
{
	struct call_struc *cs;
	isdn_ctrl ic;
	unsigned long flags;
	int i;

	if ((cmd & 0x7F) > 2) return (-EINVAL); /* invalid command */
	cs = divert_head; /* start of parameter list */
	while (cs) {
		if (cs->divert_id == callid) break; /* found */
		cs = cs->next;
	} /* search entry */
	if (!cs) return (-EINVAL); /* invalid callid */

	ic.driver = cs->ics.driver;
	ic.arg = cs->ics.arg;
	i = -EINVAL;
	if (cs->akt_state == DEFLECT_AUTODEL) return (i); /* no valid call */
	switch (cmd & 0x7F) {
	case 0: /* hangup */
		del_timer(&cs->timer);
		ic.command = ISDN_CMD_HANGUP;
		i = divert_if.ll_cmd(&ic);
		spin_lock_irqsave(&divert_lock, flags);
		cs->akt_state = DEFLECT_AUTODEL; /* delete after timeout */
		cs->timer.expires = jiffies + (HZ * AUTODEL_TIME);
		add_timer(&cs->timer);
		spin_unlock_irqrestore(&divert_lock, flags);
		break;

	case 1: /* alert */
		if (cs->akt_state == DEFLECT_ALERT) return (0);
		cmd &= 0x7F; /* never wait */
		del_timer(&cs->timer);
		ic.command = ISDN_CMD_ALERT;
		if ((i = divert_if.ll_cmd(&ic))) {
			spin_lock_irqsave(&divert_lock, flags);
			cs->akt_state = DEFLECT_AUTODEL; /* delete after timeout */
			cs->timer.expires = jiffies + (HZ * AUTODEL_TIME);
			add_timer(&cs->timer);
			spin_unlock_irqrestore(&divert_lock, flags);
		} else
			cs->akt_state = DEFLECT_ALERT;
		break;

	case 2: /* redir */
		del_timer(&cs->timer);
		strlcpy(cs->ics.parm.setup.phone, to_nr, sizeof(cs->ics.parm.setup.phone));
		strcpy(cs->ics.parm.setup.eazmsn, "Testtext manual");
		ic.command = ISDN_CMD_REDIR;
		if ((i = divert_if.ll_cmd(&ic))) {
			spin_lock_irqsave(&divert_lock, flags);
			cs->akt_state = DEFLECT_AUTODEL; /* delete after timeout */
			cs->timer.expires = jiffies + (HZ * AUTODEL_TIME);
			add_timer(&cs->timer);
			spin_unlock_irqrestore(&divert_lock, flags);
		} else
			cs->akt_state = DEFLECT_ALERT;
		break;

	} /* switch */
	return (i);
} /* deflect_extern_action */

/********************************/
/* insert a new rule before idx */
/********************************/
int insertrule(int idx, divert_rule *newrule)
{
	struct deflect_struc *ds, *ds1 = NULL;
	unsigned long flags;

	if (!(ds = kmalloc(sizeof(struct deflect_struc), GFP_KERNEL)))
		return (-ENOMEM); /* no memory */

	ds->rule = *newrule; /* set rule */

	spin_lock_irqsave(&divert_lock, flags);

	if (idx >= 0) {
		ds1 = table_head;
		while ((ds1) && (idx > 0))
		{ idx--;
			ds1 = ds1->next;
		}
		if (!ds1) idx = -1;
	}

	if (idx < 0) {
		ds->prev = table_tail; /* previous entry */
		ds->next = NULL; /* end of chain */
		if (ds->prev)
			ds->prev->next = ds; /* last forward */
		else
			table_head = ds; /* is first entry */
		table_tail = ds; /* end of queue */
	} else {
		ds->next = ds1; /* next entry */
		ds->prev = ds1->prev; /* prev entry */
		ds1->prev = ds; /* backward chain old element */
		if (!ds->prev)
			table_head = ds; /* first element */
	}

	spin_unlock_irqrestore(&divert_lock, flags);
	return (0);
} /* insertrule */

/***********************************/
/* delete the rule at position idx */
/***********************************/
int deleterule(int idx)
{
	struct deflect_struc *ds, *ds1;
	unsigned long flags;

	if (idx < 0) {
		spin_lock_irqsave(&divert_lock, flags);
		ds = table_head;
		table_head = NULL;
		table_tail = NULL;
		spin_unlock_irqrestore(&divert_lock, flags);
		while (ds) {
			ds1 = ds;
			ds = ds->next;
			kfree(ds1);
		}
		return (0);
	}

	spin_lock_irqsave(&divert_lock, flags);
	ds = table_head;

	while ((ds) && (idx > 0)) {
		idx--;
		ds = ds->next;
	}

	if (!ds) {
		spin_unlock_irqrestore(&divert_lock, flags);
		return (-EINVAL);
	}

	if (ds->next)
		ds->next->prev = ds->prev; /* backward chain */
	else
		table_tail = ds->prev; /* end of chain */

	if (ds->prev)
		ds->prev->next = ds->next; /* forward chain */
	else
		table_head = ds->next; /* start of chain */

	spin_unlock_irqrestore(&divert_lock, flags);
	kfree(ds);
	return (0);
} /* deleterule */

/*******************************************/
/* get a pointer to a specific rule number */
/*******************************************/
divert_rule *getruleptr(int idx)
{
	struct deflect_struc *ds = table_head;

	if (idx < 0) return (NULL);
	while ((ds) && (idx >= 0)) {
		if (!(idx--)) {
			return (&ds->rule);
			break;
		}
		ds = ds->next;
	}
	return (NULL);
} /* getruleptr */

/*************************************************/
/* called from common module on an incoming call */
/*************************************************/
static int isdn_divert_icall(isdn_ctrl *ic)
{
	int retval = 0;
	unsigned long flags;
	struct call_struc *cs = NULL;
	struct deflect_struc *dv;
	char *p, *p1;
	u_char accept;

	/* first check the internal deflection table */
	for (dv = table_head; dv; dv = dv->next) {
		/* scan table */
		if (((dv->rule.callopt == 1) && (ic->command == ISDN_STAT_ICALLW)) ||
		    ((dv->rule.callopt == 2) && (ic->command == ISDN_STAT_ICALL)))
			continue; /* call option check */
		if (!(dv->rule.drvid & (1L << ic->driver)))
			continue; /* driver not matching */
		if ((dv->rule.si1) && (dv->rule.si1 != ic->parm.setup.si1))
			continue; /* si1 not matching */
		if ((dv->rule.si2) && (dv->rule.si2 != ic->parm.setup.si2))
			continue; /* si2 not matching */

		p = dv->rule.my_msn;
		p1 = ic->parm.setup.eazmsn;
		accept = 0;
		while (*p) {
			/* complete compare */
			if (*p == '-') {
				accept = 1; /* call accepted */
				break;
			}
			if (*p++ != *p1++)
				break; /* not accepted */
			if ((!*p) && (!*p1))
				accept = 1;
		} /* complete compare */
		if (!accept) continue; /* not accepted */

		if ((strcmp(dv->rule.caller, "0")) ||
		    (ic->parm.setup.phone[0])) {
			p = dv->rule.caller;
			p1 = ic->parm.setup.phone;
			accept = 0;
			while (*p) {
				/* complete compare */
				if (*p == '-') {
					accept = 1; /* call accepted */
					break;
				}
				if (*p++ != *p1++)
					break; /* not accepted */
				if ((!*p) && (!*p1))
					accept = 1;
			} /* complete compare */
			if (!accept) continue; /* not accepted */
		}

		switch (dv->rule.action) {
		case DEFLECT_IGNORE:
			return (0);
			break;

		case DEFLECT_ALERT:
		case DEFLECT_PROCEED:
		case DEFLECT_REPORT:
		case DEFLECT_REJECT:
			if (dv->rule.action == DEFLECT_PROCEED)
				if ((!if_used) || ((!extern_wait_max) && (!dv->rule.waittime)))
					return (0); /* no external deflection needed */
			if (!(cs = kmalloc(sizeof(struct call_struc), GFP_ATOMIC)))
				return (0); /* no memory */
			init_timer(&cs->timer);
			cs->info[0] = '\0';
			cs->timer.function = deflect_timer_expire;
			cs->timer.data = (ulong) cs; /* pointer to own structure */

			cs->ics = *ic; /* copy incoming data */
			if (!cs->ics.parm.setup.phone[0]) strcpy(cs->ics.parm.setup.phone, "0");
			if (!cs->ics.parm.setup.eazmsn[0]) strcpy(cs->ics.parm.setup.eazmsn, "0");
			cs->ics.parm.setup.screen = dv->rule.screen;
			if (dv->rule.waittime)
				cs->timer.expires = jiffies + (HZ * dv->rule.waittime);
			else if (dv->rule.action == DEFLECT_PROCEED)
				cs->timer.expires = jiffies + (HZ * extern_wait_max);
			else
				cs->timer.expires = 0;
			cs->akt_state = dv->rule.action;
			spin_lock_irqsave(&divert_lock, flags);
			cs->divert_id = next_id++; /* new sequence number */
			spin_unlock_irqrestore(&divert_lock, flags);
			cs->prev = NULL;
			if (cs->akt_state == DEFLECT_ALERT) {
				strcpy(cs->deflect_dest, dv->rule.to_nr);
				if (!cs->timer.expires) {
					strcpy(ic->parm.setup.eazmsn,
					       "Testtext direct");
					ic->parm.setup.screen = dv->rule.screen;
					strlcpy(ic->parm.setup.phone, dv->rule.to_nr, sizeof(ic->parm.setup.phone));
					cs->akt_state = DEFLECT_AUTODEL; /* delete after timeout */
					cs->timer.expires = jiffies + (HZ * AUTODEL_TIME);
					retval = 5;
				} else
					retval = 1; /* alerting */
			} else {
				cs->deflect_dest[0] = '\0';
				retval = 4; /* only proceed */
			}
			sprintf(cs->info, "%d 0x%lx %s %s %s %s 0x%x 0x%x %d %d %s\n",
				cs->akt_state,
				cs->divert_id,
				divert_if.drv_to_name(cs->ics.driver),
				(ic->command == ISDN_STAT_ICALLW) ? "1" : "0",
				cs->ics.parm.setup.phone,
				cs->ics.parm.setup.eazmsn,
				cs->ics.parm.setup.si1,
				cs->ics.parm.setup.si2,
				cs->ics.parm.setup.screen,
				dv->rule.waittime,
				cs->deflect_dest);
			if ((dv->rule.action == DEFLECT_REPORT) ||
			    (dv->rule.action == DEFLECT_REJECT)) {
				put_info_buffer(cs->info);
				kfree(cs); /* remove */
				return ((dv->rule.action == DEFLECT_REPORT) ? 0 : 2); /* nothing to do */
			}
			break;

		default:
			return (0); /* ignore call */
			break;
		} /* switch action */
		break;
	} /* scan_table */

	if (cs) {
		cs->prev = NULL;
		spin_lock_irqsave(&divert_lock, flags);
		cs->next = divert_head;
		divert_head = cs;
		if (cs->timer.expires) add_timer(&cs->timer);
		spin_unlock_irqrestore(&divert_lock, flags);

		put_info_buffer(cs->info);
		return (retval);
	} else
		return (0);
} /* isdn_divert_icall */


void deleteprocs(void)
{
	struct call_struc *cs, *cs1;
	unsigned long flags;

	spin_lock_irqsave(&divert_lock, flags);
	cs = divert_head;
	divert_head = NULL;
	while (cs) {
		del_timer(&cs->timer);
		cs1 = cs;
		cs = cs->next;
		kfree(cs1);
	}
	spin_unlock_irqrestore(&divert_lock, flags);
} /* deleteprocs */

/****************************************************/
/* put a address including address type into buffer */
/****************************************************/
static int put_address(char *st, u_char *p, int len)
{
	u_char retval = 0;
	u_char adr_typ = 0; /* network standard */

	if (len < 2) return (retval);
	if (*p == 0xA1) {
		retval = *(++p) + 2; /* total length */
		if (retval > len) return (0); /* too short */
		len = retval - 2; /* remaining length */
		if (len < 3) return (0);
		if ((*(++p) != 0x0A) || (*(++p) != 1)) return (0);
		adr_typ = *(++p);
		len -= 3;
		p++;
		if (len < 2) return (0);
		if (*p++ != 0x12) return (0);
		if (*p > len) return (0); /* check number length */
		len = *p++;
	} else if (*p == 0x80) {
		retval = *(++p) + 2; /* total length */
		if (retval > len) return (0);
		len = retval - 2;
		p++;
	} else
		return (0); /* invalid address information */

	sprintf(st, "%d ", adr_typ);
	st += strlen(st);
	if (!len)
		*st++ = '-';
	else
		while (len--)
			*st++ = *p++;
	*st = '\0';
	return (retval);
} /* put_address */

/*************************************/
/* report a successful interrogation */
/*************************************/
static int interrogate_success(isdn_ctrl *ic, struct call_struc *cs)
{
	char *src = ic->parm.dss1_io.data;
	int restlen = ic->parm.dss1_io.datalen;
	int cnt = 1;
	u_char n, n1;
	char st[90], *p, *stp;

	if (restlen < 2) return (-100); /* frame too short */
	if (*src++ != 0x30) return (-101);
	if ((n = *src++) > 0x81) return (-102); /* invalid length field */
	restlen -= 2; /* remaining bytes */
	if (n == 0x80) {
		if (restlen < 2) return (-103);
		if ((*(src + restlen - 1)) || (*(src + restlen - 2))) return (-104);
		restlen -= 2;
	} else if (n == 0x81) {
		n = *src++;
		restlen--;
		if (n > restlen) return (-105);
		restlen = n;
	} else if (n > restlen)
		return (-106);
	else
		restlen = n; /* standard format */
	if (restlen < 3) return (-107); /* no procedure */
	if ((*src++ != 2) || (*src++ != 1) || (*src++ != 0x0B)) return (-108);
	restlen -= 3;
	if (restlen < 2) return (-109); /* list missing */
	if (*src == 0x31) {
		src++;
		if ((n = *src++) > 0x81) return (-110); /* invalid length field */
		restlen -= 2; /* remaining bytes */
		if (n == 0x80) {
			if (restlen < 2) return (-111);
			if ((*(src + restlen - 1)) || (*(src + restlen - 2))) return (-112);
			restlen -= 2;
		} else if (n == 0x81) {
			n = *src++;
			restlen--;
			if (n > restlen) return (-113);
			restlen = n;
		} else if (n > restlen)
			return (-114);
		else
			restlen = n; /* standard format */
	} /* result list header */

	while (restlen >= 2) {
		stp = st;
		sprintf(stp, "%d 0x%lx %d %s ", DIVERT_REPORT, ic->parm.dss1_io.ll_id,
			cnt++, divert_if.drv_to_name(ic->driver));
		stp += strlen(stp);
		if (*src++ != 0x30) return (-115); /* invalid enum */
		n = *src++;
		restlen -= 2;
		if (n > restlen) return (-116); /* enum length wrong */
		restlen -= n;
		p = src; /* one entry */
		src += n;
		if (!(n1 = put_address(stp, p, n & 0xFF))) continue;
		stp += strlen(stp);
		p += n1;
		n -= n1;
		if (n < 6) continue; /* no service and proc */
		if ((*p++ != 0x0A) || (*p++ != 1)) continue;
		sprintf(stp, " 0x%02x ", (*p++) & 0xFF);
		stp += strlen(stp);
		if ((*p++ != 0x0A) || (*p++ != 1)) continue;
		sprintf(stp, "%d ", (*p++) & 0xFF);
		stp += strlen(stp);
		n -= 6;
		if (n > 2) {
			if (*p++ != 0x30) continue;
			if (*p > (n - 2)) continue;
			n = *p++;
			if (!(n1 = put_address(stp, p, n & 0xFF))) continue;
			stp += strlen(stp);
		}
		sprintf(stp, "\n");
		put_info_buffer(st);
	} /* while restlen */
	if (restlen) return (-117);
	return (0);
} /* interrogate_success */

/*********************************************/
/* callback for protocol specific extensions */
/*********************************************/
static int prot_stat_callback(isdn_ctrl *ic)
{
	struct call_struc *cs, *cs1;
	int i;
	unsigned long flags;

	cs = divert_head; /* start of list */
	cs1 = NULL;
	while (cs) {
		if (ic->driver == cs->ics.driver) {
			switch (cs->ics.arg) {
			case DSS1_CMD_INVOKE:
				if ((cs->ics.parm.dss1_io.ll_id == ic->parm.dss1_io.ll_id) &&
				    (cs->ics.parm.dss1_io.hl_id == ic->parm.dss1_io.hl_id)) {
					switch (ic->arg) {
					case DSS1_STAT_INVOKE_ERR:
						sprintf(cs->info, "128 0x%lx 0x%x\n",
							ic->parm.dss1_io.ll_id,
							ic->parm.dss1_io.timeout);
						put_info_buffer(cs->info);
						break;

					case DSS1_STAT_INVOKE_RES:
						switch (cs->ics.parm.dss1_io.proc) {
						case  7:
						case  8:
							put_info_buffer(cs->info);
							break;

						case  11:
							i = interrogate_success(ic, cs);
							if (i)
								sprintf(cs->info, "%d 0x%lx %d\n", DIVERT_REPORT,
									ic->parm.dss1_io.ll_id, i);
							put_info_buffer(cs->info);
							break;

						default:
							printk(KERN_WARNING "dss1_divert: unknown proc %d\n", cs->ics.parm.dss1_io.proc);
							break;
						}

						break;

					default:
						printk(KERN_WARNING "dss1_divert unknown invoke answer %lx\n", ic->arg);
						break;
					}
					cs1 = cs; /* remember structure */
					cs = NULL;
					continue; /* abort search */
				} /* id found */
				break;

			case DSS1_CMD_INVOKE_ABORT:
				printk(KERN_WARNING "dss1_divert unhandled invoke abort\n");
				break;

			default:
				printk(KERN_WARNING "dss1_divert unknown cmd 0x%lx\n", cs->ics.arg);
				break;
			} /* switch ics.arg */
			cs = cs->next;
		} /* driver ok */
	}

	if (!cs1) {
		printk(KERN_WARNING "dss1_divert unhandled process\n");
		return (0);
	}

	if (cs1->ics.driver == -1) {
		spin_lock_irqsave(&divert_lock, flags);
		del_timer(&cs1->timer);
		if (cs1->prev)
			cs1->prev->next = cs1->next; /* forward link */
		else
			divert_head = cs1->next;
		if (cs1->next)
			cs1->next->prev = cs1->prev; /* back link */
		spin_unlock_irqrestore(&divert_lock, flags);
		kfree(cs1);
	}

	return (0);
} /* prot_stat_callback */


/***************************/
/* status callback from HL */
/***************************/
static int isdn_divert_stat_callback(isdn_ctrl *ic)
{
	struct call_struc *cs, *cs1;
	unsigned long flags;
	int retval;

	retval = -1;
	cs = divert_head; /* start of list */
	while (cs) {
		if ((ic->driver == cs->ics.driver) &&
		    (ic->arg == cs->ics.arg)) {
			switch (ic->command) {
			case ISDN_STAT_DHUP:
				sprintf(cs->info, "129 0x%lx\n", cs->divert_id);
				del_timer(&cs->timer);
				cs->ics.driver = -1;
				break;

			case ISDN_STAT_CAUSE:
				sprintf(cs->info, "130 0x%lx %s\n", cs->divert_id, ic->parm.num);
				break;

			case ISDN_STAT_REDIR:
				sprintf(cs->info, "131 0x%lx\n", cs->divert_id);
				del_timer(&cs->timer);
				cs->ics.driver = -1;
				break;

			default:
				sprintf(cs->info, "999 0x%lx 0x%x\n", cs->divert_id, (int)(ic->command));
				break;
			}
			put_info_buffer(cs->info);
			retval = 0;
		}
		cs1 = cs;
		cs = cs->next;
		if (cs1->ics.driver == -1) {
			spin_lock_irqsave(&divert_lock, flags);
			if (cs1->prev)
				cs1->prev->next = cs1->next; /* forward link */
			else
				divert_head = cs1->next;
			if (cs1->next)
				cs1->next->prev = cs1->prev; /* back link */
			spin_unlock_irqrestore(&divert_lock, flags);
			kfree(cs1);
		}
	}
	return (retval); /* not found */
} /* isdn_divert_stat_callback */


/********************/
/* callback from ll */
/********************/
int ll_callback(isdn_ctrl *ic)
{
	switch (ic->command) {
	case ISDN_STAT_ICALL:
	case ISDN_STAT_ICALLW:
		return (isdn_divert_icall(ic));
		break;

	case ISDN_STAT_PROT:
		if ((ic->arg & 0xFF) == ISDN_PTYPE_EURO) {
			if (ic->arg != DSS1_STAT_INVOKE_BRD)
				return (prot_stat_callback(ic));
			else
				return (0); /* DSS1 invoke broadcast */
		} else
			return (-1); /* protocol not euro */

	default:
		return (isdn_divert_stat_callback(ic));
	}
} /* ll_callback */
