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

📄 l3dss1.c

📁 是关于linux2.5.1的完全源码
💻 C
📖 第 1 页 / 共 5 页
字号:
        strcpy(pc->prot.dss1.uus1_data,pc->chan->setup.eazmsn); /* copy uus element if available */        if (!pc->chan->setup.phone[0])          { pc->para.cause = -1;            l3dss1_disconnect_req(pc,pr,arg); /* disconnect immediately */            return;          } /* only uus */         if (pc->prot.dss1.invoke_id)           free_invoke_id(pc->st,pc->prot.dss1.invoke_id);         if (!(pc->prot.dss1.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.dss1.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);} /* l3dss1_redir_req *//********************************************//* handle deflection request in early state *//********************************************/static void l3dss1_redir_req_early(struct l3_process *pc, u_char pr, void *arg){  l3dss1_proceed_req(pc,pr,arg);  l3dss1_redir_req(pc,pr,arg);} /* l3dss1_redir_req_early *//***********************************************//* handle special commands for this protocol.  *//* Examples are call independant services like *//* remote operations with dummy  callref.      *//***********************************************/static int l3dss1_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 DSS1_CMD_INVOKE:       if (ic->parm.dss1_io.datalen < 0) return(-2); /* invalid parameter */        for (proc_len = 1, i = ic->parm.dss1_io.proc >> 8; i; i++)          i = i >> 8; /* add one byte */           l = ic->parm.dss1_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.dss1_io.proc >> (i-1)) & 0xFF;       memcpy(p, ic->parm.dss1_io.data, ic->parm.dss1_io.datalen); /* copy data */       l = (p - temp) + ic->parm.dss1_io.datalen; /* total length */                if (ic->parm.dss1_io.timeout > 0)        if (!(pc = dss1_new_l3_process(st, -1)))          { free_invoke_id(st, id);            return(-2);          }        pc->prot.dss1.ll_id = ic->parm.dss1_io.ll_id; /* remember id */        pc->prot.dss1.proc = ic->parm.dss1_io.proc; /* and procedure */       if (!(skb = l3_alloc_skb(l)))          { free_invoke_id(st, id);           if (pc) dss1_release_l3_process(pc);           return(-2);         }       memcpy(skb_put(skb, l), temp, l);              if (pc)        { pc->prot.dss1.invoke_id = id; /* remember id */          L3AddTimer(&pc->timer, ic->parm.dss1_io.timeout, CC_TDSS1_IO | REQUEST);        }              l3_msg(st, DL_DATA | REQUEST, skb);       ic->parm.dss1_io.hl_id = id; /* return id */       return(0);     case DSS1_CMD_INVOKE_ABORT:       if ((pc = l3dss1_search_dummy_proc(st, ic->parm.dss1_io.hl_id)))	{ L3DelTimer(&pc->timer); /* remove timer */          dss1_release_l3_process(pc);          return(0);         }        else	{ l3_debug(st, "l3dss1_cmd_global abort unknown id");          return(-2);        }        break;         default:        l3_debug(st, "l3dss1_cmd_global unknown cmd 0x%lx", ic->arg);       return(-1);     } /* switch ic-> arg */  return(-1);} /* l3dss1_cmd_global */static void l3dss1_io_timer(struct l3_process *pc){ isdn_ctrl ic;  struct IsdnCardState *cs = pc->st->l1.hardware;  L3DelTimer(&pc->timer); /* remove timer */  ic.driver = cs->myid;  ic.command = ISDN_STAT_PROT;  ic.arg = DSS1_STAT_INVOKE_ERR;  ic.parm.dss1_io.hl_id = pc->prot.dss1.invoke_id;  ic.parm.dss1_io.ll_id = pc->prot.dss1.ll_id;  ic.parm.dss1_io.proc = pc->prot.dss1.proc;  ic.parm.dss1_io.timeout= -1;  ic.parm.dss1_io.datalen = 0;  ic.parm.dss1_io.data = NULL;  free_invoke_id(pc->st, pc->prot.dss1.invoke_id);  pc->prot.dss1.invoke_id = 0; /* reset id */  cs->iif.statcallb(&ic);  dss1_release_l3_process(pc); } /* l3dss1_io_timer */static voidl3dss1_release_ind(struct l3_process *pc, u_char pr, void *arg){	u_char *p;	struct sk_buff *skb = arg;	int callState = 0;	p = skb->data;	if ((p = findie(p, skb->len, IE_CALL_STATE, 0))) {		p++;		if (1 == *p++)			callState = *p;	}	if (callState == 0) {		/* ETS 300-104 7.6.1, 8.6.1, 10.6.1... and 16.1		 * set down layer 3 without sending any message		 */		L3L4(pc->st, CC_RELEASE | INDICATION, pc);		newl3state(pc, 0);		dss1_release_l3_process(pc);	} else {		L3L4(pc->st, CC_IGNORE | INDICATION, pc);	}}static voidl3dss1_dummy(struct l3_process *pc, u_char pr, void *arg){}static voidl3dss1_t302(struct l3_process *pc, u_char pr, void *arg){	L3DelTimer(&pc->timer);	pc->para.loc = 0;	pc->para.cause = 28; /* invalid number */	l3dss1_disconnect_req(pc, pr, NULL);	L3L4(pc->st, CC_SETUP_ERR, pc);}static voidl3dss1_t303(struct l3_process *pc, u_char pr, void *arg){	if (pc->N303 > 0) {		pc->N303--;		L3DelTimer(&pc->timer);		l3dss1_setup_req(pc, pr, arg);	} else {		L3DelTimer(&pc->timer);		l3dss1_message_cause(pc, MT_RELEASE_COMPLETE, 102);		L3L4(pc->st, CC_NOSETUP_RSP, pc);		dss1_release_l3_process(pc);	}}static voidl3dss1_t304(struct l3_process *pc, u_char pr, void *arg){	L3DelTimer(&pc->timer);	pc->para.loc = 0;	pc->para.cause = 102;	l3dss1_disconnect_req(pc, pr, NULL);	L3L4(pc->st, CC_SETUP_ERR, pc);}static voidl3dss1_t305(struct l3_process *pc, u_char pr, void *arg){	u_char tmp[16];	u_char *p = tmp;	int l;	struct sk_buff *skb;	u_char cause = 16;	L3DelTimer(&pc->timer);	if (pc->para.cause != NO_CAUSE)		cause = pc->para.cause;	MsgHead(p, pc->callref, MT_RELEASE);	*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);	newl3state(pc, 19);	l3_msg(pc->st, DL_DATA | REQUEST, skb);	L3AddTimer(&pc->timer, T308, CC_T308_1);}static voidl3dss1_t310(struct l3_process *pc, u_char pr, void *arg){	L3DelTimer(&pc->timer);	pc->para.loc = 0;	pc->para.cause = 102;	l3dss1_disconnect_req(pc, pr, NULL);	L3L4(pc->st, CC_SETUP_ERR, pc);}static voidl3dss1_t313(struct l3_process *pc, u_char pr, void *arg){	L3DelTimer(&pc->timer);	pc->para.loc = 0;	pc->para.cause = 102;	l3dss1_disconnect_req(pc, pr, NULL);	L3L4(pc->st, CC_CONNECT_ERR, pc);}static voidl3dss1_t308_1(struct l3_process *pc, u_char pr, void *arg){	newl3state(pc, 19);	L3DelTimer(&pc->timer);	l3dss1_message(pc, MT_RELEASE);	L3AddTimer(&pc->timer, T308, CC_T308_2);}static voidl3dss1_t308_2(struct l3_process *pc, u_char pr, void *arg){	L3DelTimer(&pc->timer);	L3L4(pc->st, CC_RELEASE_ERR, pc);	dss1_release_l3_process(pc);}static voidl3dss1_t318(struct l3_process *pc, u_char pr, void *arg){	L3DelTimer(&pc->timer);	pc->para.cause = 102;	/* Timer expiry */	pc->para.loc = 0;	/* local */	L3L4(pc->st, CC_RESUME_ERR, pc);	newl3state(pc, 19);	l3dss1_message(pc, MT_RELEASE);	L3AddTimer(&pc->timer, T308, CC_T308_1);}static voidl3dss1_t319(struct l3_process *pc, u_char pr, void *arg){	L3DelTimer(&pc->timer);	pc->para.cause = 102;	/* Timer expiry */	pc->para.loc = 0;	/* local */	L3L4(pc->st, CC_SUSPEND_ERR, pc);	newl3state(pc, 10);}static voidl3dss1_restart(struct l3_process *pc, u_char pr, void *arg){	L3DelTimer(&pc->timer);	L3L4(pc->st, CC_RELEASE | INDICATION, pc);	dss1_release_l3_process(pc);}static voidl3dss1_status(struct l3_process *pc, u_char pr, void *arg){	u_char *p;	struct sk_buff *skb = arg;	int ret; 	u_char cause = 0, callState = 0;		if ((ret = l3dss1_get_cause(pc, skb))) {		if (pc->debug & L3_DEB_WARN)			l3_debug(pc->st, "STATUS get_cause ret(%d)",ret);		if (ret < 0)			cause = 96;		else if (ret > 0)			cause = 100;	}	if ((p = findie(skb->data, skb->len, IE_CALL_STATE, 0))) {		p++;		if (1 == *p++) {			callState = *p;			if (!ie_in_set(pc, *p, l3_valid_states))				cause = 100;		} else			cause = 100;	} else		cause = 96;	if (!cause) { /*  no error before */		ret = check_infoelements(pc, skb, ie_STATUS);		if (ERR_IE_COMPREHENSION == ret)			cause = 96;		else if (ERR_IE_UNRECOGNIZED == ret)			cause = 99;	}	if (cause) {		u_char tmp;				if (pc->debug & L3_DEB_WARN)			l3_debug(pc->st, "STATUS error(%d/%d)",ret,cause);		tmp = pc->para.cause;		pc->para.cause = cause;		l3dss1_status_send(pc, 0, NULL);		if (cause == 99)			pc->para.cause = tmp;		else			return;	}	cause = pc->para.cause;	if (((cause & 0x7f) == 111) && (callState == 0)) {		/* ETS 300-104 7.6.1, 8.6.1, 10.6.1...		 * if received MT_STATUS with cause == 111 and call		 * state == 0, then we must set down layer 3		 */		L3L4(pc->st, CC_RELEASE | INDICATION, pc);		newl3state(pc, 0);		dss1_release_l3_process(pc);	}}static voidl3dss1_facility(struct l3_process *pc, u_char pr, void *arg){	struct sk_buff *skb = arg;	int ret;		ret = check_infoelements(pc, skb, ie_FACILITY);	l3dss1_std_ie_err(pc, ret); 	  {		u_char *p;		if ((p = findie(skb->data, skb->len, IE_FACILITY, 0)))			l3dss1_parse_facility(pc->st, pc, pc->callref, p);	}}static voidl3dss1_suspend_req(struct l3_process *pc, u_char pr, void *arg){	struct sk_buff *skb;	u_char tmp[32];	u_char *p = tmp;	u_char i, l;	u_char *msg = pc->chan->setup.phone;	MsgHead(p, pc->callref, MT_SUSPEND);	l = *msg++;	if (l && (l <= 10)) {	/* Max length 10 octets */		*p++ = IE_CALL_ID;		*p++ = l;		for (i = 0; i < l; i++)			*p++ = *msg++;	} else if (l) {		l3_debug(pc->st, "SUS wrong CALL_ID len %d", l);		return;	}	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);	newl3state(pc, 15);	L3AddTimer(&pc->timer, T319, CC_T319);}static voidl3dss1_suspend_ack(struct l3_process *pc, u_char pr, void *arg){	struct sk_buff *skb = arg;	int ret;	L3DelTimer(&pc->timer);	newl3state(pc, 0);	pc->para.cause = NO_CAUSE;	L3L4(pc->st, CC_SUSPEND | CONFIRM, pc);	/* We don't handle suspend_ack for IE errors now */	if ((ret = check_infoelements(pc, skb, ie_SUSPEND_ACKNOWLEDGE)))		if (pc->debug & L3_DEB_WARN)			l3_debug(pc->st, "SUSPACK check ie(%d)",ret);	dss1_release_l3_process(pc);}static voidl3dss1_suspend_rej(struct l3_process *pc, u_char pr, void *arg){	struct sk_buff *skb = arg;	int ret;	if ((ret = l3dss1_get_cause(pc, skb))) {		if (pc->debug & L3_DEB_WARN)			l3_debug(pc->st, "SUSP_REJ get_cause ret(%d)",ret);		if (ret < 0) 			pc->para.cause = 96;		else			pc->para.cause = 100;		l3dss1_status_send(pc, pr, NULL);		return;	}	ret = check_infoelements(pc, skb, ie_SUSPEND_REJECT);	if (ERR_IE_COMPREHENSION == ret) {		l3dss1_std_ie_err(pc, ret);		return;	}	L3DelTimer(&pc->timer);	L3L4(pc->st, CC_SUSPEND_ERR, pc);	newl3state(pc, 10);	if (ret) /* STATUS for none mandatory IE errors after actions are taken */		l3dss1_std_ie_err(pc, ret);}static voidl3dss1_resume_req(struct l3_process *pc, u_char pr, void *arg){	struct sk_buff *skb;	u_char tmp[32];	u_char *p = tmp;	u_char i, l;	u_char *msg = pc->para.setup.phone;	MsgHead(p, pc->callref, MT_RESUME);	l = *msg++;	if (l && (l <= 10)) {	/* Max length 10 octets */		*p++ = IE_CALL_ID;		*p++ = l;		for (i = 0; i < l; i++)			*p++ = *msg++;	} else if (l) {		l3_debug(pc->st, "RES wrong CALL_ID len %d", l);		return;	}	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);	newl3state(pc, 17);	L3AddTimer(&pc->timer, T318, CC_T318);}static voidl3dss1_resume_ack(struct l3_process *pc, u_char pr, void *arg){	struct sk_buff *skb = arg;	int id, ret;	if ((id = 

⌨️ 快捷键说明

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