📄 eicon_idi.c
字号:
if (sub) { reqbuf->XBuffer.P[l++] = DSA; reqbuf->XBuffer.P[l++] = strlen(sub) + 2; reqbuf->XBuffer.P[l++] = 0x80; /* NSAP coded */ reqbuf->XBuffer.P[l++] = 0x50; /* local IDI format */ while (*sub) reqbuf->XBuffer.P[l++] = *sub++ & 0x7f; } sub = NULL; sp = eazmsn; while (*sp) { if (*sp == '.') { sub = sp + 1; *sp = 0; } else sp++; } reqbuf->XBuffer.P[l++] = OAD; reqbuf->XBuffer.P[l++] = strlen(eazmsn) + 2; reqbuf->XBuffer.P[l++] = 0x01; reqbuf->XBuffer.P[l++] = 0x80; for(i=0; i<strlen(eazmsn);i++) reqbuf->XBuffer.P[l++] = eazmsn[i] & 0x7f; if (sub) { reqbuf->XBuffer.P[l++] = OSA; reqbuf->XBuffer.P[l++] = strlen(sub) + 2; reqbuf->XBuffer.P[l++] = 0x80; /* NSAP coded */ reqbuf->XBuffer.P[l++] = 0x50; /* local IDI format */ while (*sub) reqbuf->XBuffer.P[l++] = *sub++ & 0x7f; } if (si2 > 2) { reqbuf->XBuffer.P[l++] = SHIFT|6; reqbuf->XBuffer.P[l++] = SIN; reqbuf->XBuffer.P[l++] = 2; reqbuf->XBuffer.P[l++] = si1; reqbuf->XBuffer.P[l++] = si2; } else if ((tmp = idi_si2bc(si1, si2, bc, hlc)) > 0) { reqbuf->XBuffer.P[l++] = BC; reqbuf->XBuffer.P[l++] = tmp; for(i=0; i<tmp;i++) reqbuf->XBuffer.P[l++] = bc[i]; if ((tmp=hlc[0])) { reqbuf->XBuffer.P[l++] = HLC; reqbuf->XBuffer.P[l++] = tmp; for(i=1; i<=tmp;i++) reqbuf->XBuffer.P[l++] = hlc[i]; } } reqbuf->XBuffer.P[l++] = CAI; reqbuf->XBuffer.P[l++] = 6; reqbuf->XBuffer.P[l++] = 0x09; reqbuf->XBuffer.P[l++] = 0; reqbuf->XBuffer.P[l++] = 0; reqbuf->XBuffer.P[l++] = 0; reqbuf->XBuffer.P[l++] = 32; reqbuf->XBuffer.P[l++] = 0; switch(chan->l2prot) { case ISDN_PROTO_L2_X75I: case ISDN_PROTO_L2_X75UI: case ISDN_PROTO_L2_X75BUI: case ISDN_PROTO_L2_HDLC: reqbuf->XBuffer.P[l-6] = 5; reqbuf->XBuffer.P[l-7] = 1; l -= 5; break; case ISDN_PROTO_L2_V11096: reqbuf->XBuffer.P[l-7] = 3; reqbuf->XBuffer.P[l-6] = 0x0d; reqbuf->XBuffer.P[l-5] = 5; reqbuf->XBuffer.P[l-4] = 0; l -= 3; break; case ISDN_PROTO_L2_V11019: reqbuf->XBuffer.P[l-7] = 3; reqbuf->XBuffer.P[l-6] = 0x0d; reqbuf->XBuffer.P[l-5] = 6; reqbuf->XBuffer.P[l-4] = 0; l -= 3; break; case ISDN_PROTO_L2_V11038: reqbuf->XBuffer.P[l-7] = 3; reqbuf->XBuffer.P[l-6] = 0x0d; reqbuf->XBuffer.P[l-5] = 7; reqbuf->XBuffer.P[l-4] = 0; l -= 3; break; case ISDN_PROTO_L2_MODEM: reqbuf->XBuffer.P[l-6] = 0x11; reqbuf->XBuffer.P[l-5] = 7; reqbuf->XBuffer.P[l-4] = 0; reqbuf->XBuffer.P[l-3] = 0; reqbuf->XBuffer.P[l-2] = 128; reqbuf->XBuffer.P[l-1] = 0; break; case ISDN_PROTO_L2_FAX: reqbuf->XBuffer.P[l-6] = 0x10; reqbuf->XBuffer.P[l-5] = 0; reqbuf->XBuffer.P[l-4] = 0; reqbuf->XBuffer.P[l-3] = 0; reqbuf->XBuffer.P[l-2] = 128; reqbuf->XBuffer.P[l-1] = 0; break; case ISDN_PROTO_L2_TRANS: switch(chan->l3prot) { case ISDN_PROTO_L3_TRANSDSP: reqbuf->XBuffer.P[l-6] = 22; /* DTMF, audio events on */ } break; } reqbuf->XBuffer.P[l++] = 0; /* end */ reqbuf->XBuffer.length = l; reqbuf->Reference = 0; /* Sig Entity */ if (chan->statectrl & WAITING_FOR_HANGUP) { /* If the line did not disconnect yet, we have to delay this command */ eicon_log(card, 32, "idi_req: Ch%d: delaying conn_req\n", chan->No); chan->statectrl |= HAVE_CONN_REQ; chan->tskb1 = skb; chan->tskb2 = skb2; } else { skb_queue_tail(&chan->e.X, skb); skb_queue_tail(&card->sndq, skb2); eicon_schedule_tx(card); } eicon_log(card, 8, "idi_req: Ch%d: Conn_Req %s -> %s\n",chan->No, eazmsn, phone); return(0);}voididi_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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -