Enscript Output

extractedLnx/linux-2.6.4/drivers/isdn/hardware/eicon/i4l_idi.c_idi_IndParse.c

static void
idi_IndParse(eicon_card *ccard, eicon_chan *chan, idi_ind_message *message, unsigned char *buffer, int len)
{
	int i,j;
	int pos = 0;
	int codeset = 0;
	int wlen = 0;
	int lock = 0;
	__u8 w;
	__u16 code;
	isdn_ctrl cmd;

	memset(message, 0, sizeof(idi_ind_message));

	if ((!len) || (!buffer[pos])) return;

  while(pos <= len) {
	w = buffer[pos++];
	if (!w) return;
	if (w & 0x80) {
		wlen = 0;
	}
	else {
		wlen = buffer[pos++];
	}

	if (pos > len) return;

	if (lock & 0x80) lock &= 0x7f;
	else codeset = lock;

	if((w&0xf0) == SHIFT) {
		codeset = w;
		if(!(codeset & 0x08)) lock = codeset & 7;
		codeset &= 7;
		lock |= 0x80;
	}
	else {
		if (w==ESC && wlen >=2) {
			code = buffer[pos++]|0x800;
			wlen--;
		}
		else code = w;
		code |= (codeset<<8);

		if (pos + wlen > len) {
			eicon_log(ccard, 1, "idi_err: Ch%d: IElen %d of %x exceeds Ind_Length (+%d)\n", chan->No, 
					wlen, code, (pos + wlen) - len);
			return;
		}

		switch(code) {
			case OAD:
				if (wlen > sizeof(message->oad)) {
					pos += wlen;
					break;
				}
				j = 1;
				if (wlen) {
					message->plan = buffer[pos++];
					if (message->plan &0x80) 
						message->screen = 0;
					else {
						message->screen = buffer[pos++];
						j = 2;
					}
				}
				for(i=0; i < wlen-j; i++) 
					message->oad[i] = buffer[pos++];
				eicon_log(ccard, 2, "idi_inf: Ch%d: OAD=(0x%02x,0x%02x) %s\n", chan->No, 
					message->plan, message->screen, message->oad);
				break;
			case RDN:
				if (wlen > sizeof(message->rdn)) {
					pos += wlen;
					break;
				}
				j = 1;
				if (wlen) {
					if (!(buffer[pos++] & 0x80)) {
						pos++; 
						j = 2;
					}
				}
				for(i=0; i < wlen-j; i++) 
					message->rdn[i] = buffer[pos++];
				eicon_log(ccard, 2, "idi_inf: Ch%d: RDN= %s\n", chan->No, 
						message->rdn);
				break;
			case CPN:
				if (wlen > sizeof(message->cpn)) {
					pos += wlen;
					break;
				}
				for(i=0; i < wlen; i++) 
					message->cpn[i] = buffer[pos++];
				eicon_log(ccard, 2, "idi_inf: Ch%d: CPN=(0x%02x) %s\n", chan->No,
					(__u8)message->cpn[0], message->cpn + 1);
				break;
			case DSA:
				if (wlen > sizeof(message->dsa)) {
					pos += wlen;
					break;
				}
				pos += 2;
				for(i=0; i < wlen-2; i++) 
					message->dsa[i] = buffer[pos++];
				eicon_log(ccard, 2, "idi_inf: Ch%d: DSA=%s\n", chan->No, message->dsa);
				break;
			case OSA:
				if (wlen > sizeof(message->osa)) {
					pos += wlen;
					break;
				}
				pos += 2;
				for(i=0; i < wlen-2; i++) 
					message->osa[i] = buffer[pos++];
				eicon_log(ccard, 2, "idi_inf: Ch%d: OSA=%s\n", chan->No, message->osa);
				break;
			case CAD:
				pos += wlen;
				eicon_log(ccard, 2, "idi_inf: Ch%d: Connected Address in ind, len:%x\n", 
					chan->No, wlen);
				break;
			case BC:
				if (wlen > sizeof(message->bc)) {
					pos += wlen;
					break;
				}
				for(i=0; i < wlen; i++) 
					message->bc[i] = buffer[pos++];
				eicon_log(ccard, 4, "idi_inf: Ch%d: BC = 0x%02x 0x%02x 0x%02x\n", chan->No,
					message->bc[0],message->bc[1],message->bc[2]);
				break;
			case 0x800|BC:
				if (wlen > sizeof(message->e_bc)) {
					pos += wlen;
					break;
				}
				for(i=0; i < wlen; i++) 
					message->e_bc[i] = buffer[pos++];
				eicon_log(ccard, 4, "idi_inf: Ch%d: ESC/BC=%d\n", chan->No, message->bc[0]);
				break;
			case LLC:
				if (wlen > sizeof(message->llc)) {
					pos += wlen;
					break;
				}
				for(i=0; i < wlen; i++) 
					message->llc[i] = buffer[pos++];
				eicon_log(ccard, 4, "idi_inf: Ch%d: LLC=%d %d %d %d ...\n", chan->No, message->llc[0],
					message->llc[1],message->llc[2],message->llc[3]);
				break;
			case HLC:
				if (wlen > sizeof(message->hlc)) {
					pos += wlen;
					break;
				}
				for(i=0; i < wlen; i++) 
					message->hlc[i] = buffer[pos++];
				eicon_log(ccard, 4, "idi_inf: Ch%d: HLC=%x %x %x %x %x ...\n", chan->No,
					message->hlc[0], message->hlc[1],
					message->hlc[2], message->hlc[3], message->hlc[4]);
				break;
			case DSP:
			case 0x600|DSP:
				if (wlen > sizeof(message->display)) {
					pos += wlen;
					break;
				}
				for(i=0; i < wlen; i++) 
					message->display[i] = buffer[pos++];
				eicon_log(ccard, 4, "idi_inf: Ch%d: Display: %s\n", chan->No,
					message->display);
				break;
			case 0x600|KEY:
				if (wlen > sizeof(message->keypad)) {
					pos += wlen;
					break;
				}
				for(i=0; i < wlen; i++) 
					message->keypad[i] = buffer[pos++];
				eicon_log(ccard, 4, "idi_inf: Ch%d: Keypad: %s\n", chan->No,
					message->keypad);
				break;
			case NI:
			case 0x600|NI:
				if (wlen) {
					switch(buffer[pos] & 127) {
						case 0:
							eicon_log(ccard, 4, "idi_inf: Ch%d: User suspended.\n", chan->No);
							break;
						case 1:
							eicon_log(ccard, 4, "idi_inf: Ch%d: User resumed.\n", chan->No);
							break;
						case 2:
							eicon_log(ccard, 4, "idi_inf: Ch%d: Bearer service change.\n", chan->No);
							break;
						default:
							eicon_log(ccard, 4, "idi_inf: Ch%d: Unknown Notification %x.\n", 
									chan->No, buffer[pos] & 127);
					}
					pos += wlen;
				}
				break;
			case PI:
			case 0x600|PI:
				if (wlen > 1) {
					switch(buffer[pos+1] & 127) {
						case 1:
							eicon_log(ccard, 4, "idi_inf: Ch%d: Call is not end-to-end ISDN.\n", chan->No);
							break;
						case 2:
							eicon_log(ccard, 4, "idi_inf: Ch%d: Destination address is non ISDN.\n", chan->No);
							break;
						case 3:
							eicon_log(ccard, 4, "idi_inf: Ch%d: Origination address is non ISDN.\n", chan->No);
							break;
						case 4:
							eicon_log(ccard, 4, "idi_inf: Ch%d: Call has returned to the ISDN.\n", chan->No);
							break;
						case 5:
							eicon_log(ccard, 4, "idi_inf: Ch%d: Interworking has occurred.\n", chan->No);
							break;
						case 8:
							eicon_log(ccard, 4, "idi_inf: Ch%d: In-band information available.\n", chan->No);
							break;
						default:
							eicon_log(ccard, 4, "idi_inf: Ch%d: Unknown Progress %x.\n", 
									chan->No, buffer[pos+1] & 127);
					}
				}
				pos += wlen;
				break;
			case CAU:
				if (wlen > sizeof(message->cau)) {
					pos += wlen;
					break;
				}
				for(i=0; i < wlen; i++) 
					message->cau[i] = buffer[pos++];
				memcpy(&chan->cause, &message->cau, 2);
				eicon_log(ccard, 4, "idi_inf: Ch%d: CAU=%d %d\n", chan->No,
					message->cau[0],message->cau[1]);
				break;
			case 0x800|CAU:
				if (wlen > sizeof(message->e_cau)) {
					pos += wlen;
					break;
				}
				for(i=0; i < wlen; i++) 
					message->e_cau[i] = buffer[pos++];
				eicon_log(ccard, 4, "idi_inf: Ch%d: ECAU=%d %d\n", chan->No,
					message->e_cau[0],message->e_cau[1]);
				break;
			case 0x800|CHI:
				if (wlen > sizeof(message->e_chi)) {
					pos += wlen;
					break;
				}
				for(i=0; i < wlen; i++) 
					message->e_chi[i] = buffer[pos++];
				eicon_log(ccard, 4, "idi_inf: Ch%d: ESC/CHI=%d\n", chan->No,
					message->e_cau[0]);
				break;
			case 0x800|0x7a:
				pos ++;
				message->e_mt=buffer[pos++];
				eicon_log(ccard, 4, "idi_inf: Ch%d: EMT=0x%x\n", chan->No, message->e_mt);
				break;
			case DT:
				if (wlen > sizeof(message->dt)) {
					pos += wlen;
					break;
				}
				for(i=0; i < wlen; i++) 
					message->dt[i] = buffer[pos++];
				eicon_log(ccard, 4, "idi_inf: Ch%d: DT: %02d.%02d.%02d %02d:%02d:%02d\n", chan->No,
					message->dt[2], message->dt[1], message->dt[0],
					message->dt[3], message->dt[4], message->dt[5]);
				break;
			case 0x600|SIN:
				if (wlen > sizeof(message->sin)) {
					pos += wlen;
					break;
				}
				for(i=0; i < wlen; i++) 
					message->sin[i] = buffer[pos++];
				eicon_log(ccard, 2, "idi_inf: Ch%d: SIN=%d %d\n", chan->No,
					message->sin[0],message->sin[1]);
				break;
			case 0x600|CPS:
				eicon_log(ccard, 2, "idi_inf: Ch%d: Called Party Status in ind\n", chan->No);
				pos += wlen;
				break;
			case 0x600|CIF:
				for (i = 0; i < wlen; i++)
					if (buffer[pos + i] != '0') break;
				memcpy(&cmd.parm.num, &buffer[pos + i], wlen - i);
				cmd.parm.num[wlen - i] = 0;
				eicon_log(ccard, 2, "idi_inf: Ch%d: CIF=%s\n", chan->No, cmd.parm.num);
				pos += wlen;
				cmd.driver = ccard->myid;
				cmd.command = ISDN_STAT_CINF;
				cmd.arg = chan->No;
				ccard->interface.statcallb(&cmd);
				break;
			case 0x600|DATE:
				eicon_log(ccard, 2, "idi_inf: Ch%d: Date in ind\n", chan->No);
				pos += wlen;
				break;
			case 0xa1: 
				eicon_log(ccard, 2, "idi_inf: Ch%d: Sending Complete in ind.\n", chan->No);
				pos += wlen;
				break;
			case 0xe08: 
			case 0xe7a: 
			case 0xe04: 
			case 0xe00: 
				/* *** TODO *** */
			case CHA:
				/* Charge advice */
			case FTY:
			case 0x600|FTY:
			case CHI:
			case 0x800:
				/* Not yet interested in this */
				pos += wlen;
				break;
			case 0x880:
				/* Managment Information Element */
				if (!manbuf) {
					eicon_log(ccard, 1, "idi_err: manbuf not allocated\n");
				}
				else {
					memcpy(&manbuf->data[manbuf->pos], &buffer[pos], wlen);
					manbuf->length[manbuf->count] = wlen;
					manbuf->count++;
					manbuf->pos += wlen;
				}
				pos += wlen;
				break;
			default:
				pos += wlen;
				eicon_log(ccard, 6, "idi_inf: Ch%d: unknown information element 0x%x in ind, len:%x\n", 
					chan->No, code, wlen);
		}
	}
  }
}

Generated by GNU enscript 1.6.4.