📄 eicon_idi.c
字号:
} } }}voididi_bc2si(unsigned char *bc, unsigned char *hlc, unsigned char *sin, unsigned char *si1, unsigned char *si2){ si1[0] = 0; si2[0] = 0; switch (bc[0] & 0x7f) { case 0x00: /* Speech */ si1[0] = 1;#ifdef EICON_FULL_SERVICE_OKTETT si1[0] = sin[0]; si2[0] = sin[1];#endif break; case 0x10: /* 3.1 Khz audio */ si1[0] = 1;#ifdef EICON_FULL_SERVICE_OKTETT si1[0] = sin[0]; si2[0] = sin[1];#endif break; case 0x08: /* Unrestricted digital information */ si1[0] = 7; si2[0] = sin[1]; break; case 0x09: /* Restricted digital information */ si1[0] = 2; break; case 0x11: /* Unrestr. digital information with * tones/announcements ( or 7 kHz audio */ si1[0] = 3; break; case 0x18: /* Video */ si1[0] = 4; break; } switch (bc[1] & 0x7f) { case 0x40: /* packed mode */ si1[0] = 8; break; case 0x10: /* 64 kbit */ case 0x11: /* 2*64 kbit */ case 0x13: /* 384 kbit */ case 0x15: /* 1536 kbit */ case 0x17: /* 1920 kbit */ /* moderate = bc[1] & 0x7f; */ break; }}/********************* FAX stuff ***************************/#ifdef CONFIG_ISDN_TTY_FAXintidi_fill_in_T30(eicon_chan *chan, unsigned char *buffer){ eicon_t30_s *t30 = (eicon_t30_s *) buffer; if (!chan->fax) { eicon_log(NULL, 1,"idi_T30: fill_in with NULL fax struct, ERROR\n"); return 0; } memset(t30, 0, sizeof(eicon_t30_s)); t30->station_id_len = EICON_FAXID_LEN; memcpy(&t30->station_id[0], &chan->fax->id[0], EICON_FAXID_LEN); t30->resolution = chan->fax->resolution; t30->rate = chan->fax->rate + 1; /* eicon rate starts with 1 */ t30->format = T30_FORMAT_SFF; t30->pages_low = 0; t30->pages_high = 0; t30->atf = 1; /* optimised for AT+F command set */ t30->code = 0; t30->feature_bits_low = 0; t30->feature_bits_high = 0; t30->control_bits_low = 0; t30->control_bits_high = 0; if (chan->fax->nbc) { /* set compression by DCC value */ switch(chan->fax->compression) { case (0): /* 1-D modified */ break; case (1): /* 2-D modified Read */ t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_2D_CODING; t30->feature_bits_low |= T30_FEATURE_BIT_2D_CODING; break; case (2): /* 2-D uncompressed */ t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_UNCOMPR; t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_2D_CODING; t30->feature_bits_low |= T30_FEATURE_BIT_UNCOMPR_ENABLED; t30->feature_bits_low |= T30_FEATURE_BIT_2D_CODING; break; case (3): /* 2-D modified Read */ t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_T6_CODING; t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_2D_CODING; t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_UNCOMPR; t30->feature_bits_low |= T30_FEATURE_BIT_UNCOMPR_ENABLED; t30->feature_bits_low |= T30_FEATURE_BIT_T6_CODING; t30->feature_bits_low |= T30_FEATURE_BIT_2D_CODING; t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_ECM; t30->feature_bits_low |= T30_FEATURE_BIT_ECM; break; } } else { /* set compression to best */ t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_T6_CODING; t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_2D_CODING; t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_UNCOMPR; t30->feature_bits_low |= T30_FEATURE_BIT_UNCOMPR_ENABLED; t30->feature_bits_low |= T30_FEATURE_BIT_T6_CODING; t30->feature_bits_low |= T30_FEATURE_BIT_2D_CODING; t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_ECM; t30->feature_bits_low |= T30_FEATURE_BIT_ECM; } switch(chan->fax->ecm) { case (0): /* disable ECM */ break; case (1): t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_ECM; t30->control_bits_low |= T30_CONTROL_BIT_ECM_64_BYTES; t30->feature_bits_low |= T30_FEATURE_BIT_ECM; t30->feature_bits_low |= T30_FEATURE_BIT_ECM_64_BYTES; break; case (2): t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_ECM; t30->feature_bits_low |= T30_FEATURE_BIT_ECM; break; } if (DebugVar & 128) { char st[40]; eicon_log(NULL, 128, "sT30:code = %x\n", t30->code); eicon_log(NULL, 128, "sT30:rate = %x\n", t30->rate); eicon_log(NULL, 128, "sT30:res = %x\n", t30->resolution); eicon_log(NULL, 128, "sT30:format = %x\n", t30->format); eicon_log(NULL, 128, "sT30:pages_low = %x\n", t30->pages_low); eicon_log(NULL, 128, "sT30:pages_high = %x\n", t30->pages_high); eicon_log(NULL, 128, "sT30:atf = %x\n", t30->atf); eicon_log(NULL, 128, "sT30:control_bits_low = %x\n", t30->control_bits_low); eicon_log(NULL, 128, "sT30:control_bits_high = %x\n", t30->control_bits_high); eicon_log(NULL, 128, "sT30:feature_bits_low = %x\n", t30->feature_bits_low); eicon_log(NULL, 128, "sT30:feature_bits_high = %x\n", t30->feature_bits_high); //eicon_log(NULL, 128, "sT30:universal_5 = %x\n", t30->universal_5); //eicon_log(NULL, 128, "sT30:universal_6 = %x\n", t30->universal_6); //eicon_log(NULL, 128, "sT30:universal_7 = %x\n", t30->universal_7); eicon_log(NULL, 128, "sT30:station_id_len = %x\n", t30->station_id_len); eicon_log(NULL, 128, "sT30:head_line_len = %x\n", t30->head_line_len); strncpy(st, t30->station_id, t30->station_id_len); st[t30->station_id_len] = 0; eicon_log(NULL, 128, "sT30:station_id = <%s>\n", st); } return(sizeof(eicon_t30_s));}/* send fax struct */intidi_send_edata(eicon_card *card, eicon_chan *chan){ struct sk_buff *skb; struct sk_buff *skb2; eicon_REQ *reqbuf; eicon_chan_ptr *chan2; if ((chan->fsm_state == EICON_STATE_NULL) || (chan->fsm_state == EICON_STATE_LISTEN)) { eicon_log(card, 1, "idi_snd: Ch%d: send edata on state %d !\n", chan->No, chan->fsm_state); return -ENODEV; } eicon_log(card, 128, "idi_snd: Ch%d: edata (fax)\n", chan->No); skb = alloc_skb(sizeof(eicon_REQ) + sizeof(eicon_t30_s), GFP_ATOMIC); skb2 = alloc_skb(sizeof(eicon_chan_ptr), GFP_ATOMIC); if ((!skb) || (!skb2)) { eicon_log(card, 1, "idi_err: Ch%d: alloc_skb failed in send_edata()\n", chan->No); if (skb) dev_kfree_skb(skb); if (skb2) dev_kfree_skb(skb2); return -ENOMEM; } chan2 = (eicon_chan_ptr *)skb_put(skb2, sizeof(eicon_chan_ptr)); chan2->ptr = chan; reqbuf = (eicon_REQ *)skb_put(skb, sizeof(eicon_t30_s) + sizeof(eicon_REQ)); reqbuf->Req = N_EDATA; reqbuf->ReqCh = chan->e.IndCh; reqbuf->ReqId = 1; reqbuf->XBuffer.length = idi_fill_in_T30(chan, reqbuf->XBuffer.P); reqbuf->Reference = 1; /* Net Entity */ skb_queue_tail(&chan->e.X, skb); skb_queue_tail(&card->sndq, skb2); eicon_schedule_tx(card); return (0);}voididi_parse_edata(eicon_card *ccard, eicon_chan *chan, unsigned char *buffer, int len){ eicon_t30_s *p = (eicon_t30_s *)buffer; int i; if (DebugVar & 128) { char st[40]; eicon_log(ccard, 128, "rT30:len %d , size %d\n", len, sizeof(eicon_t30_s)); eicon_log(ccard, 128, "rT30:code = %x\n", p->code); eicon_log(ccard, 128, "rT30:rate = %x\n", p->rate); eicon_log(ccard, 128, "rT30:res = %x\n", p->resolution); eicon_log(ccard, 128, "rT30:format = %x\n", p->format); eicon_log(ccard, 128, "rT30:pages_low = %x\n", p->pages_low); eicon_log(ccard, 128, "rT30:pages_high = %x\n", p->pages_high); eicon_log(ccard, 128, "rT30:atf = %x\n", p->atf); eicon_log(ccard, 128, "rT30:control_bits_low = %x\n", p->control_bits_low); eicon_log(ccard, 128, "rT30:control_bits_high = %x\n", p->control_bits_high); eicon_log(ccard, 128, "rT30:feature_bits_low = %x\n", p->feature_bits_low); eicon_log(ccard, 128, "rT30:feature_bits_high = %x\n", p->feature_bits_high); //eicon_log(ccard, 128, "rT30:universal_5 = %x\n", p->universal_5); //eicon_log(ccard, 128, "rT30:universal_6 = %x\n", p->universal_6); //eicon_log(ccard, 128, "rT30:universal_7 = %x\n", p->universal_7); eicon_log(ccard, 128, "rT30:station_id_len = %x\n", p->station_id_len); eicon_log(ccard, 128, "rT30:head_line_len = %x\n", p->head_line_len); strncpy(st, p->station_id, p->station_id_len); st[p->station_id_len] = 0; eicon_log(ccard, 128, "rT30:station_id = <%s>\n", st); } if (!chan->fax) { eicon_log(ccard, 1, "idi_edata: parse to NULL fax struct, ERROR\n"); return; } chan->fax->code = p->code; i = (p->station_id_len < FAXIDLEN) ? p->station_id_len : (FAXIDLEN - 1); memcpy(chan->fax->r_id, p->station_id, i); chan->fax->r_id[i] = 0; chan->fax->r_resolution = p->resolution; chan->fax->r_rate = p->rate - 1; chan->fax->r_binary = 0; /* no binary support */ chan->fax->r_width = 0; chan->fax->r_length = 2; chan->fax->r_scantime = 0; chan->fax->r_compression = 0; chan->fax->r_ecm = 0; if (p->feature_bits_low & T30_FEATURE_BIT_2D_CODING) { chan->fax->r_compression = 1; if (p->feature_bits_low & T30_FEATURE_BIT_UNCOMPR_ENABLED) { chan->fax->r_compression = 2; } } if (p->feature_bits_low & T30_FEATURE_BIT_T6_CODING) { chan->fax->r_compression = 3; } if (p->feature_bits_low & T30_FEATURE_BIT_ECM) { chan->fax->r_ecm = 2; if (p->feature_bits_low & T30_FEATURE_BIT_ECM_64_BYTES) chan->fax->r_ecm = 1; }}voididi_fax_send_header(eicon_card *card, eicon_chan *chan, int header){ static __u16 wd2sff[] = { 1728, 2048, 2432, 1216, 864 }; static __u16 ln2sff[2][3] = { { 1143, 1401, 0 } , { 2287, 2802, 0 } }; struct sk_buff *skb; eicon_sff_dochead *doc; eicon_sff_pagehead *page; u_char *docp; if (!chan->fax) { eicon_log(card, 1, "idi_fax: send head with NULL fax struct, ERROR\n"); return; } if (header == 2) { /* DocHeader + PageHeader */ skb = alloc_skb(sizeof(eicon_sff_dochead) + sizeof(eicon_sff_pagehead), GFP_ATOMIC); } else { skb = alloc_skb(sizeof(eicon_sff_pagehead), GFP_ATOMIC); } if (!skb) { eicon_log(card, 1, "idi_err: Ch%d: alloc_skb failed in fax_send_header()\n", chan->No); return; } if (header == 2) { /* DocHeader + PageHeader */ docp = skb_put(skb, sizeof(eicon_sff_dochead) + sizeof(eicon_sff_pagehead)); doc = (eicon_sff_dochead *) docp; page = (eicon_sff_pagehead *) (docp + sizeof(eicon_sff_dochead)); memset(docp, 0,sizeof(eicon_sff_dochead) + sizeof(eicon_sff_pagehead)); doc->id = 0x66666653; doc->version = 0x01; doc->off1pagehead = sizeof(eicon_sff_dochead); } else { page = (eicon_sff_pagehead *)skb_put(skb, sizeof(eicon_sff_pagehead)); memset(page, 0, sizeof(eicon_sff_pagehead)); } switch(header) { case 1: /* PageHeaderEnd */ page->pageheadid = 254; page->pageheadlen = 0; break; case 0: /* PageHeader */ case 2: /* DocHeader + PageHeader */ page->pageheadid = 254; page->pageheadlen = sizeof(eicon_sff_pagehead) - 2; page->resvert = chan->fax->resolution; page->reshoriz = 0; /* always 203 dpi */ page->coding = 0; /* always 1D */ page->linelength = wd2sff[chan->fax->width]; page->pagelength = ln2sff[chan->fax->resolution][chan->fax->length]; eicon_log(card, 128, "sSFF-Head: linelength = %d\n", page->linelength); eicon_log(card, 128, "sSFF-Head: pagelength = %d\n", page->pagelength); break; } idi_send_data(card, chan, 0, skb, 0, 0);}voididi_fax_cmd(eicon_card *card, eicon_chan *chan) { isdn_ctrl cmd; if ((!card) || (!chan)) return; if (!chan->fax) { eicon_log(card, 1, "idi_fax: cmd with NULL fax struct, ERROR\n"); return; } switch (chan->fax->code) { case ISDN_TTY_FAX_DT: if (chan->fax->phase == ISDN_FAX_PHASE_B) { idi_send_edata(card, chan); break; } if (chan->fax->phase == ISDN_FAX_PHASE_D) { idi_send_edata(card, chan); break; } break; case ISDN_TTY_FAX_DR: if (chan->fax->phase == ISDN_FAX_PHASE_B) { idi_send_edata(card, chan); cmd.driver = card->myid; cmd.command = ISDN_STAT_FAXIND; cmd.arg = chan->No; chan->fax->r_code = ISDN_TTY_FAX_CFR; card->interface.statcallb(&cmd); cmd.driver = card->myid; cmd.command = ISDN_STAT_FAXIND; cmd.arg = chan->No; chan->fax->r_code = ISDN_TTY_FAX_RID; card->interface.statcallb(&cmd); /* telling 1-D compression */ chan->fax->r_compression = 0; cmd.driver = card->myid; cmd.command = ISDN_STAT_FAXIND; cmd.arg = chan->No; chan->fax->r_code = ISDN_TTY_FAX_DCS; card->interface.statcallb(&cmd); chan->fax2.NextObject = FAX_OBJECT_DOCU; chan->fax2.PrevObject = FAX_OBJECT_DOCU; break; } if (chan->fax->phase == ISDN_FAX_PHASE_D) { idi_send_edata(card, chan); break; } break; case ISDN_TTY_FAX_ET: switch(chan->fax->fet) { case 0: case 1: idi_fax_send_header(card, chan, 0); break; case 2: idi_fax_send_header(card, chan, 1); break; } break; }}voididi_edata_rcveop(eicon_card *card, eicon_chan *chan){ isdn_ctrl cmd; if (!chan->fax) { eicon_log(card, 1, "idi_edata: rcveop with NULL fax struct, ERROR\n"); return; } cmd.driver = card->myid; cmd.command = ISDN_STAT_FAXIND; cmd.arg = chan->No; chan->fax->r_code = ISDN_TTY_FAX_ET; card->interface.statcallb(&cmd);}voididi_reset_fax_stat(eicon_chan *chan){ chan->fax2.LineLen = 0; chan->fax2.LineData = 0; chan->fax2.LineDataLen = 0; chan->fax2.NullByteExist = 0; chan->fax2.Dle = 0; chan->fax2.PageCount = 0; chan->fax2.Eop = 0;}voididi_edata_action(eicon_card *ccard, eicon_chan *chan, char *buffer, int len){ isdn_ctrl cmd; if (!chan->fax) { eicon_log(ccard, 1, "idi_edata: action with NULL fax struct, ERROR\n"); return; } if (chan->fax->direction == ISDN_TTY_FAX_CONN_OUT) { idi_parse_edata(ccard, chan, buffer, len); if (chan->fax->phase == ISDN_FAX_PHASE_A) { idi_reset_fax_stat(chan); chan->fsm_state = EICON_STATE_ACTIVE; cmd.driver = ccard->myid; cmd.command = ISDN_STAT_BCONN; cmd.arg = chan->No; strcpy(cmd.parm.num, ""); ccard->interface.statcallb(&cmd); cmd.driver = ccard->myid; cmd.command = ISDN_STAT_FAXIND; cmd.arg = chan->No; chan->fax->r_code = ISDN_TTY_FAX_FCON; ccard->interface.statcallb(&cmd); cmd.driver = ccard->myid; cmd.command = ISDN_STAT_FAXIND; cmd.arg = chan->No; chan->fax->r_code = ISDN_TTY_FAX_RID; ccard->interface.statcallb(&cmd); cmd.driver = ccard->myid; cmd.command = ISDN_STAT_FAXIND; cmd.arg = chan->No; chan->fax->r_code = ISDN_TTY_FAX_DIS; ccard->interface.statcallb(&cmd); if (chan->fax->r_compression != 0) { /* telling fake compression in second DIS message */ chan->fax->r_compression = 0; cmd.driver = ccard->myid; cmd.command = ISDN_STAT_FAXIND; cmd.arg = chan->No; chan->fax->r_code = ISDN_TTY_FAX_DIS; ccard->interface.statcallb(&cmd); } cmd.driver = ccard->myid;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -