⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 l3ni1.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
			iecpy(pc->para.setup.phone, p, 1);			pc->para.setup.screen = 0;		} else {			iecpy(pc->para.setup.phone, p, 2);			pc->para.setup.screen = p[3];		}	} else {		pc->para.setup.phone[0] = 0;		pc->para.setup.plan = 0;		pc->para.setup.screen = 0;	}	p = skb->data;	if ((p = findie(p, skb->len, 0x6d, 0))) {		/* Calling party subaddress */		if ((p[1] >= 2) && (p[2] == 0x80) && (p[3] == 0x50)) {			tmp[0] = '.';			iecpy(&tmp[1], p, 2);			strcat(pc->para.setup.phone, tmp);		} else if (pc->debug & L3_DEB_WARN)			l3_debug(pc->st, "wrong calling subaddress");	}	newl3state(pc, 6);	if (err) /* STATUS for none mandatory IE errors after actions are taken */		l3ni1_std_ie_err(pc, err);	pc->st->l3.l3l4(pc->st, CC_SETUP | INDICATION, pc);}static voidl3ni1_reset(struct l3_process *pc, u_char pr, void *arg){	ni1_release_l3_process(pc);}static voidl3ni1_disconnect_req(struct l3_process *pc, u_char pr, void *arg){	struct sk_buff *skb;	u_char tmp[16+40];	u_char *p = tmp;	int l;	u_char cause = 16;	if (pc->para.cause != NO_CAUSE)		cause = pc->para.cause;	StopAllL3Timer(pc);	MsgHead(p, pc->callref, MT_DISCONNECT);	*p++ = IE_CAUSE;	*p++ = 0x2;	*p++ = 0x80;	*p++ = cause | 0x80;        if (pc->prot.ni1.uus1_data[0])	 { *p++ = IE_USER_USER; /* UUS info element */           *p++ = strlen(pc->prot.ni1.uus1_data) + 1;           *p++ = 0x04; /* IA5 chars */           strcpy(p,pc->prot.ni1.uus1_data);           p += strlen(pc->prot.ni1.uus1_data);           pc->prot.ni1.uus1_data[0] = '\0';            } 	l = p - tmp;	if (!(skb = l3_alloc_skb(l)))		return;	memcpy(skb_put(skb, l), tmp, l);	newl3state(pc, 11);	l3_msg(pc->st, DL_DATA | REQUEST, skb);	L3AddTimer(&pc->timer, T305, CC_T305);}static voidl3ni1_setup_rsp(struct l3_process *pc, u_char pr,		 void *arg){        if (!pc->para.bchannel) 	 { if (pc->debug & L3_DEB_WARN)	       l3_debug(pc->st, "D-chan connect for waiting call");           l3ni1_disconnect_req(pc, pr, arg);           return;         }	newl3state(pc, 8);	if (pc->debug & L3_DEB_WARN)		l3_debug(pc->st, "D-chan connect for waiting call");	l3ni1_message_plus_chid(pc, MT_CONNECT); /* GE 05/09/00 */ 	L3DelTimer(&pc->timer);	L3AddTimer(&pc->timer, T313, CC_T313);}static voidl3ni1_connect_ack(struct l3_process *pc, u_char pr, void *arg){	struct sk_buff *skb = arg;	int ret;	ret = check_infoelements(pc, skb, ie_CONNECT_ACKNOWLEDGE);	if (ERR_IE_COMPREHENSION == ret) {		l3ni1_std_ie_err(pc, ret);		return;	}	newl3state(pc, 10);	L3DelTimer(&pc->timer);	if (ret)		l3ni1_std_ie_err(pc, ret);	pc->st->l3.l3l4(pc->st, CC_SETUP_COMPL | INDICATION, pc);}static voidl3ni1_reject_req(struct l3_process *pc, u_char pr, void *arg){	struct sk_buff *skb;	u_char tmp[16];	u_char *p = tmp;	int l;	u_char cause = 21;	if (pc->para.cause != NO_CAUSE)		cause = pc->para.cause;	MsgHead(p, pc->callref, MT_RELEASE_COMPLETE);	*p++ = IE_CAUSE;	*p++ = 0x2;	*p++ = 0x80;	*p++ = cause | 0x80;	l = p - tmp;	if (!(skb = l3_alloc_skb(l)))		return;	memcpy(skb_put(skb, l), tmp, l);	l3_msg(pc->st, DL_DATA | REQUEST, skb);	pc->st->l3.l3l4(pc->st, CC_RELEASE | INDICATION, pc);	newl3state(pc, 0);	ni1_release_l3_process(pc);}static voidl3ni1_release(struct l3_process *pc, u_char pr, void *arg){	struct sk_buff *skb = arg;	u_char *p;	int ret, cause=0;	StopAllL3Timer(pc);	if ((ret = l3ni1_get_cause(pc, skb))>0) {		if (pc->debug & L3_DEB_WARN)			l3_debug(pc->st, "REL get_cause ret(%d)", ret);	} else if (ret<0)		pc->para.cause = NO_CAUSE;	if ((p = findie(skb->data, skb->len, IE_FACILITY, 0))) {		l3ni1_parse_facility(pc->st, pc, pc->callref, p);	}	if ((ret<0) && (pc->state != 11))		cause = 96;	else if (ret>0)		cause = 100;	ret = check_infoelements(pc, skb, ie_RELEASE);	if (ERR_IE_COMPREHENSION == ret)		cause = 96;	else if ((ERR_IE_UNRECOGNIZED == ret) && (!cause))		cause = 99;  	if (cause)		l3ni1_message_cause(pc, MT_RELEASE_COMPLETE, cause);	else		l3ni1_message(pc, MT_RELEASE_COMPLETE);	pc->st->l3.l3l4(pc->st, CC_RELEASE | INDICATION, pc);	newl3state(pc, 0);	ni1_release_l3_process(pc);}static voidl3ni1_alert_req(struct l3_process *pc, u_char pr,		 void *arg){	newl3state(pc, 7);	if (!pc->prot.ni1.uus1_data[0]) 		l3ni1_message(pc, MT_ALERTING);	else		l3ni1_msg_with_uus(pc, MT_ALERTING); }static voidl3ni1_proceed_req(struct l3_process *pc, u_char pr,		   void *arg){	newl3state(pc, 9);	l3ni1_message(pc, MT_CALL_PROCEEDING);	pc->st->l3.l3l4(pc->st, CC_PROCEED_SEND | INDICATION, pc); }static voidl3ni1_setup_ack_req(struct l3_process *pc, u_char pr,		   void *arg){	newl3state(pc, 25);	L3DelTimer(&pc->timer);	L3AddTimer(&pc->timer, T302, CC_T302);	l3ni1_message(pc, MT_SETUP_ACKNOWLEDGE);}/********************************************//* deliver a incoming display message to HL *//********************************************/static voidl3ni1_deliver_display(struct l3_process *pc, int pr, u_char *infp){       u_char len;        isdn_ctrl ic; 	struct IsdnCardState *cs;        char *p;         if (*infp++ != IE_DISPLAY) return;        if ((len = *infp++) > 80) return; /* total length <= 82 */	if (!pc->chan) return;	p = ic.parm.display;         while (len--)	  *p++ = *infp++;	*p = '\0';	ic.command = ISDN_STAT_DISPLAY;	cs = pc->st->l1.hardware;	ic.driver = cs->myid;	ic.arg = pc->chan->chan; 	cs->iif.statcallb(&ic);} /* l3ni1_deliver_display */static voidl3ni1_progress(struct l3_process *pc, u_char pr, void *arg){	struct sk_buff *skb = arg;	int err = 0;	u_char *p;	if ((p = findie(skb->data, skb->len, IE_PROGRESS, 0))) {		if (p[1] != 2) {			err = 1;			pc->para.cause = 100;		} else if (!(p[2] & 0x70)) {			switch (p[2]) {				case 0x80:				case 0x81:				case 0x82:				case 0x84:				case 0x85:				case 0x87:				case 0x8a:					switch (p[3]) {						case 0x81:						case 0x82:						case 0x83:						case 0x84:						case 0x88:							break;						default:							err = 2;							pc->para.cause = 100;							break;					}					break;				default:					err = 3;					pc->para.cause = 100;					break;			}		}	} else {		pc->para.cause = 96;		err = 4;	}	if (err) {			if (pc->debug & L3_DEB_WARN)			l3_debug(pc->st, "progress error %d", err);		l3ni1_status_send(pc, pr, NULL);		return;	}	/* Now we are on none mandatory IEs */	err = check_infoelements(pc, skb, ie_PROGRESS);	if (err)		l3ni1_std_ie_err(pc, err);	if (ERR_IE_COMPREHENSION != err)		pc->st->l3.l3l4(pc->st, CC_PROGRESS | INDICATION, pc);}static voidl3ni1_notify(struct l3_process *pc, u_char pr, void *arg){	struct sk_buff *skb = arg;	int err = 0;	u_char *p;	if ((p = findie(skb->data, skb->len, IE_NOTIFY, 0))) {		if (p[1] != 1) {			err = 1;			pc->para.cause = 100;		} else {			switch (p[2]) {				case 0x80:				case 0x81:				case 0x82:					break;				default:					pc->para.cause = 100;					err = 2;					break;			}		}	} else {		pc->para.cause = 96;		err = 3;	}	if (err) {			if (pc->debug & L3_DEB_WARN)			l3_debug(pc->st, "notify error %d", err);		l3ni1_status_send(pc, pr, NULL);		return;	}	/* Now we are on none mandatory IEs */	err = check_infoelements(pc, skb, ie_NOTIFY);	if (err)		l3ni1_std_ie_err(pc, err);	if (ERR_IE_COMPREHENSION != err)		pc->st->l3.l3l4(pc->st, CC_NOTIFY | INDICATION, pc);}static voidl3ni1_status_enq(struct l3_process *pc, u_char pr, void *arg){	int ret;	struct sk_buff *skb = arg;	ret = check_infoelements(pc, skb, ie_STATUS_ENQUIRY);	l3ni1_std_ie_err(pc, ret);	pc->para.cause = 30; /* response to STATUS_ENQUIRY */        l3ni1_status_send(pc, pr, NULL);}static voidl3ni1_information(struct l3_process *pc, u_char pr, void *arg){	int ret;	struct sk_buff *skb = arg;	u_char *p;	char tmp[32];	ret = check_infoelements(pc, skb, ie_INFORMATION);	if (ret)		l3ni1_std_ie_err(pc, ret);	if (pc->state == 25) { /* overlap receiving */		L3DelTimer(&pc->timer);		p = skb->data;		if ((p = findie(p, skb->len, 0x70, 0))) {			iecpy(tmp, p, 1);			strcat(pc->para.setup.eazmsn, tmp);			pc->st->l3.l3l4(pc->st, CC_MORE_INFO | INDICATION, pc);		}		L3AddTimer(&pc->timer, T302, CC_T302);	}}/******************************//* handle deflection requests *//******************************/static void l3ni1_redir_req(struct l3_process *pc, u_char pr, void *arg){	struct sk_buff *skb;	u_char tmp[128];	u_char *p = tmp;        u_char *subp;        u_char len_phone = 0;        u_char len_sub = 0;	int l;         strcpy(pc->prot.ni1.uus1_data,pc->chan->setup.eazmsn); /* copy uus element if available */        if (!pc->chan->setup.phone[0])          { pc->para.cause = -1;            l3ni1_disconnect_req(pc,pr,arg); /* disconnect immediately */            return;          } /* only uus */         if (pc->prot.ni1.invoke_id)           free_invoke_id(pc->st,pc->prot.ni1.invoke_id);         if (!(pc->prot.ni1.invoke_id = new_invoke_id(pc->st)))           return;        MsgHead(p, pc->callref, MT_FACILITY);        for (subp = pc->chan->setup.phone; (*subp) && (*subp != '.'); subp++) len_phone++; /* len of phone number */        if (*subp++ == '.') len_sub = strlen(subp) + 2; /* length including info subaddress element */ 	*p++ = 0x1c;   /* Facility info element */        *p++ = len_phone + len_sub + 2 + 2 + 8 + 3 + 3; /* length of element */        *p++ = 0x91;  /* remote operations protocol */        *p++ = 0xa1;  /* invoke component */	          *p++ = len_phone + len_sub + 2 + 2 + 8 + 3; /* length of data */        *p++ = 0x02;  /* invoke id tag, integer */	*p++ = 0x01;  /* length */        *p++ = pc->prot.ni1.invoke_id;  /* invoke id */         *p++ = 0x02;  /* operation value tag, integer */	*p++ = 0x01;  /* length */        *p++ = 0x0D;  /* Call Deflect */	          *p++ = 0x30;  /* sequence phone number */        *p++ = len_phone + 2 + 2 + 3 + len_sub; /* length */	          *p++ = 0x30;  /* Deflected to UserNumber */        *p++ = len_phone+2+len_sub; /* length */        *p++ = 0x80; /* NumberDigits */	*p++ = len_phone; /* length */        for (l = 0; l < len_phone; l++)	 *p++ = pc->chan->setup.phone[l];        if (len_sub)	  { *p++ = 0x04; /* called party subaddress */            *p++ = len_sub - 2;            while (*subp) *p++ = *subp++;          }        *p++ = 0x01; /* screening identifier */        *p++ = 0x01;        *p++ = pc->chan->setup.screen;	l = p - tmp;	if (!(skb = l3_alloc_skb(l))) return;	memcpy(skb_put(skb, l), tmp, l);        l3_msg(pc->st, DL_DATA | REQUEST, skb);} /* l3ni1_redir_req *//********************************************//* handle deflection request in early state *//********************************************/static void l3ni1_redir_req_early(struct l3_process *pc, u_char pr, void *arg){  l3ni1_proceed_req(pc,pr,arg);  l3ni1_redir_req(pc,pr,arg);} /* l3ni1_redir_req_early *//***********************************************//* handle special commands for this protocol.  *//* Examples are call independant services like *//* remote operations with dummy  callref.      *//***********************************************/static int l3ni1_cmd_global(struct PStack *st, isdn_ctrl *ic){ u_char id;  u_char temp[265];  u_char *p = temp;  int i, l, proc_len;   struct sk_buff *skb;  struct l3_process *pc = NULL;  switch (ic->arg)   { case NI1_CMD_INVOKE:       if (ic->parm.ni1_io.datalen < 0) return(-2); /* invalid parameter */        for (proc_len = 1, i = ic->parm.ni1_io.proc >> 8; i; i++)          i = i >> 8; /* add one byte */           l = ic->parm.ni1_io.datalen + proc_len + 8; /* length excluding ie header */       if (l > 255)          return(-2); /* too long */       if (!(id = new_invoke_id(st)))          return(0); /* first get a invoke id -> return if no available */              i = -1;        MsgHead(p, i, MT_FACILITY); /* build message head */       *p++ = 0x1C; /* Facility IE */       *p++ = l; /* length of ie */       *p++ = 0x91; /* remote operations */       *p++ = 0xA1; /* invoke */       *p++ = l - 3; /* length of invoke */       *p++ = 0x02; /* invoke id tag */       *p++ = 0x01; /* length is 1 */       *p++ = id; /* invoke id */       *p++ = 0x02; /* operation */       *p++ = proc_len; /* length of operation */              for (i = proc_len; i; i--)         *p++ = (ic->parm.ni1_io.proc >> (i-1)) & 0xFF;       memcpy(p, ic->parm.ni1_io.data, ic->parm.ni1_io.datalen); /* copy data */       l = (p - temp) + ic->parm.ni1_io.datalen; /* total length */                if (ic->parm.ni1_io.timeout > 0)        if (!(pc = ni1_new_l3_process(st, -1)))          { free_invoke_id(st, id);            return(-2);          }        pc->prot.ni1.ll_id = ic->parm.ni1_io.ll_id; /* remember id */        pc->prot.ni1.proc = ic->parm.ni1_io.proc; /* and procedure */       if (!(skb = l3_alloc_skb(l)))          { free_invoke_id(st, id);           if (pc) ni1_release_l3_process(pc);           return(-2);         }       memcpy(skb_put(skb, l), temp, l);              if (pc)        { pc->prot.ni1.invoke_id = id; /* remember id */          L3AddTimer(&pc->timer, ic->parm.ni1_io.timeout, CC_TNI1_IO | REQUEST);        }              l3_msg(st, DL_DATA | REQUEST, skb);       ic->parm.ni1_io.hl_id = id; /* return id */       return(0);     case NI1_CMD_INVOKE_ABORT:       if ((pc = l3ni1_search_dummy_proc(st, ic->parm.ni1_io.hl_id)))	{ L3DelTimer(&pc->timer); /* remove timer */          ni1_release_l3_process(pc);          return(0);         }        else	{ l3_debug(st, "l3ni1_cmd_global abort unknown id");          return(-2);        }        break;         default:        l3_debug(st, "l3ni1_cmd_global unknown cmd 0x%lx", ic->arg);       return(-1);     } /* switch ic-> arg */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -