/*
 * Parse an ICN-type command string sent to the 'card'.
 * Perform misc. actions depending on the command.
 *
 * Parameter:
 *   card = pointer to card struct.
 */
static void
isdnloop_parse_cmd(isdnloop_card * card)
{
	char *p = card->omsg;
	isdn_ctrl cmd;
	char buf[60];
	isdnloop_stat *s = isdnloop_cmd_table;
	int action = -1;
	int i;
	int ch;

	if ((card->omsg[0] != '0') && (card->omsg[2] != ';')) {
		isdnloop_fake_err(card);
		return;
	}
	ch = card->omsg[1] - '0';
	if ((ch < 0) || (ch > 2)) {
		isdnloop_fake_err(card);
		return;
	}
	p += 3;
	while (s->statstr) {
		if (!strncmp(p, s->statstr, strlen(s->statstr))) {
			action = s->action;
			if (s->command && (ch != 0)) {
				isdnloop_fake_err(card);
				return;
			}
			break;
		}
		s++;
	}
	if (action == -1)
		return;
	switch (action) {
		case 1:
			/* 0x;BCON_R */
			if (card->rcard[ch - 1]) {
				isdnloop_fake(card->rcard[ch - 1], "BCON_I",
					      card->rch[ch - 1] + 1);
				isdnloop_fake(card, "BCON_C", ch);
			}
			break;
		case 17:
			/* 0x;BCON_I */
			if (card->rcard[ch - 1]) {
				isdnloop_fake(card->rcard[ch - 1], "BCON_C",
					      card->rch[ch - 1] + 1);
			}
			break;
		case 2:
			/* 0x;BDIS_R */
			isdnloop_fake(card, "BDIS_C", ch);
			if (card->rcard[ch - 1]) {
				isdnloop_fake(card->rcard[ch - 1], "BDIS_I",
					      card->rch[ch - 1] + 1);
			}
			break;
		case 16:
			/* 0x;DCON_R */
			isdnloop_kill_ctimer(card, ch - 1);
			if (card->rcard[ch - 1]) {
				isdnloop_kill_ctimer(card->rcard[ch - 1], card->rch[ch - 1]);
				isdnloop_fake(card->rcard[ch - 1], "DCON_C",
					      card->rch[ch - 1] + 1);
				isdnloop_fake(card, "DCON_C", ch);
			}
			break;
		case 3:
			/* 0x;DDIS_R */
			isdnloop_kill_ctimer(card, ch - 1);
			if (card->rcard[ch - 1]) {
				isdnloop_kill_ctimer(card->rcard[ch - 1], card->rch[ch - 1]);
				isdnloop_fake(card->rcard[ch - 1], "DDIS_I",
					      card->rch[ch - 1] + 1);
				card->rcard[ch - 1] = NULL;
			}
			isdnloop_fake(card, "DDIS_C", ch);
			break;
		case 4:
			/* 0x;DSCA_Rdd,yy,zz,oo */
			if (card->ptype != ISDN_PTYPE_1TR6) {
				isdnloop_fake_err(card);
				return;
			}
			/* Fall through */
		case 5:
			/* 0x;DCAL_Rdd,yy,zz,oo */
			p += 6;
			switch (isdnloop_try_call(card, p, ch - 1, &cmd)) {
				case 0:
					/* Alerting */
					sprintf(buf, "D%s_I%s,%02d,%02d,%s",
					   (action == 4) ? "SCA" : "CAL",
						isdnloop_vstphone(card, cmd.parm.setup.eazmsn, 1),
						cmd.parm.setup.si1,
						cmd.parm.setup.si2,
					isdnloop_vstphone(card->rcard[ch - 1],
					       cmd.parm.setup.phone, 0));
					isdnloop_fake(card->rcard[ch - 1], buf, card->rch[ch - 1] + 1);
					/* Fall through */
				case 3:
					/* si1 does not match, don't alert but start timer */
					isdnloop_start_ctimer(card, ch - 1);
					break;
				case 1:
					/* Remote busy */
					isdnloop_fake(card, "DDIS_I", ch);
					sprintf(buf, "CAU%s", isdnloop_unicause(card, 1, 1));
					isdnloop_fake(card, buf, ch);
					break;
				case 2:
					/* No such user */
					isdnloop_fake(card, "DDIS_I", ch);
					sprintf(buf, "CAU%s", isdnloop_unicause(card, 1, 2));
					isdnloop_fake(card, buf, ch);
					break;
			}
			break;
		case 6:
			/* 0x;EAZC */
			card->eazlist[ch - 1][0] = '\0';
			break;
		case 7:
			/* 0x;EAZ */
			p += 3;
			strcpy(card->eazlist[ch - 1], p);
			break;
		case 8:
			/* 0x;SEEAZ */
			sprintf(buf, "EAZ-LIST: %s", card->eazlist[ch - 1]);
			isdnloop_fake(card, buf, ch + 1);
			break;
		case 9:
			/* 0x;MSN */
			break;
		case 10:
			/* 0x;MSNALL */
			break;
		case 11:
			/* 0x;SETSIL */
			p += 6;
			i = 0;
			while (strchr("0157", *p)) {
				if (i)
					card->sil[ch - 1] |= si2bit[*p - '0'];
				i = (*p++ == '0');
			}
			if (*p)
				isdnloop_fake_err(card);
			break;
		case 12:
			/* 0x;SEESIL */
			sprintf(buf, "SIN-LIST: ");
			p = buf + 10;
			for (i = 0; i < 3; i++)
				if (card->sil[ch - 1] & (1 << i))
					p += sprintf(p, "%02d", bit2si[i]);
			isdnloop_fake(card, buf, ch + 1);
			break;
		case 13:
			/* 0x;SILC */
			card->sil[ch - 1] = 0;
			break;
		case 14:
			/* 00;FV2ON */
			break;
		case 15:
			/* 00;FV2OFF */
			break;
	}
}
static void
isdnloop_parse_cmd(isdnloop_card *card)
{
	char *p = card->omsg;
	isdn_ctrl cmd;
	char buf[60];
	isdnloop_stat *s = isdnloop_cmd_table;
	int action = -1;
	int i;
	int ch;

	if ((card->omsg[0] != '0') && (card->omsg[2] != ';')) {
		isdnloop_fake_err(card);
		return;
	}
	ch = card->omsg[1] - '0';
	if ((ch < 0) || (ch > 2)) {
		isdnloop_fake_err(card);
		return;
	}
	p += 3;
	while (s->statstr) {
		if (!strncmp(p, s->statstr, strlen(s->statstr))) {
			action = s->action;
			if (s->command && (ch != 0)) {
				isdnloop_fake_err(card);
				return;
			}
			break;
		}
		s++;
	}
	if (action == -1)
		return;
	switch (action) {
	case 1:
		
		if (card->rcard[ch - 1]) {
			isdnloop_fake(card->rcard[ch - 1], "BCON_I",
				      card->rch[ch - 1] + 1);
			isdnloop_fake(card, "BCON_C", ch);
		}
		break;
	case 17:
		
		if (card->rcard[ch - 1]) {
			isdnloop_fake(card->rcard[ch - 1], "BCON_C",
				      card->rch[ch - 1] + 1);
		}
		break;
	case 2:
		
		isdnloop_fake(card, "BDIS_C", ch);
		if (card->rcard[ch - 1]) {
			isdnloop_fake(card->rcard[ch - 1], "BDIS_I",
				      card->rch[ch - 1] + 1);
		}
		break;
	case 16:
		
		isdnloop_kill_ctimer(card, ch - 1);
		if (card->rcard[ch - 1]) {
			isdnloop_kill_ctimer(card->rcard[ch - 1], card->rch[ch - 1]);
			isdnloop_fake(card->rcard[ch - 1], "DCON_C",
				      card->rch[ch - 1] + 1);
			isdnloop_fake(card, "DCON_C", ch);
		}
		break;
	case 3:
		
		isdnloop_kill_ctimer(card, ch - 1);
		if (card->rcard[ch - 1]) {
			isdnloop_kill_ctimer(card->rcard[ch - 1], card->rch[ch - 1]);
			isdnloop_fake(card->rcard[ch - 1], "DDIS_I",
				      card->rch[ch - 1] + 1);
			card->rcard[ch - 1] = NULL;
		}
		isdnloop_fake(card, "DDIS_C", ch);
		break;
	case 4:
		
		if (card->ptype != ISDN_PTYPE_1TR6) {
			isdnloop_fake_err(card);
			return;
		}
		
	case 5:
		
		p += 6;
		switch (isdnloop_try_call(card, p, ch - 1, &cmd)) {
		case 0:
			
			sprintf(buf, "D%s_I%s,%02d,%02d,%s",
				(action == 4) ? "SCA" : "CAL",
				isdnloop_vstphone(card, cmd.parm.setup.eazmsn, 1),
				cmd.parm.setup.si1,
				cmd.parm.setup.si2,
				isdnloop_vstphone(card->rcard[ch - 1],
						  cmd.parm.setup.phone, 0));
			isdnloop_fake(card->rcard[ch - 1], buf, card->rch[ch - 1] + 1);
			
		case 3:
			
			isdnloop_start_ctimer(card, ch - 1);
			break;
		case 1:
			
			isdnloop_fake(card, "DDIS_I", ch);
			sprintf(buf, "CAU%s", isdnloop_unicause(card, 1, 1));
			isdnloop_fake(card, buf, ch);
			break;
		case 2:
			
			isdnloop_fake(card, "DDIS_I", ch);
			sprintf(buf, "CAU%s", isdnloop_unicause(card, 1, 2));
			isdnloop_fake(card, buf, ch);
			break;
		}
		break;
	case 6:
		
		card->eazlist[ch - 1][0] = '\0';
		break;
	case 7:
		
		p += 3;
		strcpy(card->eazlist[ch - 1], p);
		break;
	case 8:
		
		sprintf(buf, "EAZ-LIST: %s", card->eazlist[ch - 1]);
		isdnloop_fake(card, buf, ch + 1);
		break;
	case 9:
		
		break;
	case 10:
		
		break;
	case 11:
		
		p += 6;
		i = 0;
		while (strchr("0157", *p)) {
			if (i)
				card->sil[ch - 1] |= si2bit[*p - '0'];
			i = (*p++ == '0');
		}
		if (*p)
			isdnloop_fake_err(card);
		break;
	case 12:
		
		sprintf(buf, "SIN-LIST: ");
		p = buf + 10;
		for (i = 0; i < 3; i++)
			if (card->sil[ch - 1] & (1 << i))
				p += sprintf(p, "%02d", bit2si[i]);
		isdnloop_fake(card, buf, ch + 1);
		break;
	case 13:
		
		card->sil[ch - 1] = 0;
		break;
	case 14:
		
		break;
	case 15:
		
		break;
	}
}