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

📄 isdn_divert.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
           if (*p++ != *p1++)              break; /* not accepted */           if ((!*p) && (!*p1))             accept = 1;         } /* complete compare */        if (!accept) continue; /* not accepted */      }       switch (dv->rule.action)       { case DEFLECT_IGNORE:           return(0);           break;         case DEFLECT_ALERT:         case DEFLECT_PROCEED:         case DEFLECT_REPORT:         case DEFLECT_REJECT:           if (dv->rule.action == DEFLECT_PROCEED)	    if ((!if_used) || ((!extern_wait_max) && (!dv->rule.waittime)))               return(0); /* no external deflection needed */             if (!(cs = (struct call_struc *) kmalloc(sizeof(struct call_struc), GFP_ATOMIC)))              return(0); /* no memory */           init_timer(&cs->timer);           cs->info[0] = '\0';           cs->timer.function = deflect_timer_expire;           cs->timer.data = (ulong) cs; /* pointer to own structure */                      cs->ics = *ic; /* copy incoming data */           if (!cs->ics.parm.setup.phone[0]) strcpy(cs->ics.parm.setup.phone,"0");           if (!cs->ics.parm.setup.eazmsn[0]) strcpy(cs->ics.parm.setup.eazmsn,"0");	   cs->ics.parm.setup.screen = dv->rule.screen;             if (dv->rule.waittime)              cs->timer.expires = jiffies + (HZ * dv->rule.waittime);           else            if (dv->rule.action == DEFLECT_PROCEED)              cs->timer.expires = jiffies + (HZ * extern_wait_max);             else                cs->timer.expires = 0;           cs->akt_state = dv->rule.action;                           spin_lock_irqsave(&divert_lock, flags);           cs->divert_id = next_id++; /* new sequence number */           spin_unlock_irqrestore(&divert_lock, flags);           cs->prev = NULL;           if (cs->akt_state == DEFLECT_ALERT)             { strcpy(cs->deflect_dest,dv->rule.to_nr);               if (!cs->timer.expires)		 { strcpy(ic->parm.setup.eazmsn,"Testtext direct");                   ic->parm.setup.screen = dv->rule.screen;                   strcpy(ic->parm.setup.phone,dv->rule.to_nr);                   cs->akt_state = DEFLECT_AUTODEL; /* delete after timeout */                   cs->timer.expires = jiffies + (HZ * AUTODEL_TIME);                   retval = 5;                  }               else                 retval = 1; /* alerting */                              }           else             { cs->deflect_dest[0] = '\0';	       retval = 4; /* only proceed */             }             sprintf(cs->info,"%d 0x%lx %s %s %s %s 0x%x 0x%x %d %d %s\n",                   cs->akt_state,                   cs->divert_id,                   divert_if.drv_to_name(cs->ics.driver),                   (ic->command == ISDN_STAT_ICALLW) ? "1":"0",                    cs->ics.parm.setup.phone,                    cs->ics.parm.setup.eazmsn,                   cs->ics.parm.setup.si1,                   cs->ics.parm.setup.si2,                   cs->ics.parm.setup.screen,                   dv->rule.waittime,                   cs->deflect_dest);           if ((dv->rule.action == DEFLECT_REPORT) ||               (dv->rule.action == DEFLECT_REJECT))	    { put_info_buffer(cs->info);	      kfree(cs); /* remove */              return((dv->rule.action == DEFLECT_REPORT) ? 0:2); /* nothing to do */             }                         break;           default:           return(0); /* ignore call */           break;       } /* switch action */         break;    } /* scan_table */  if (cs)    { cs->prev = NULL;     spin_lock_irqsave(&divert_lock, flags);     cs->next = divert_head;     divert_head = cs;      if (cs->timer.expires) add_timer(&cs->timer);     spin_unlock_irqrestore(&divert_lock, flags);     put_info_buffer(cs->info);      return(retval);   }  else     return(0);} /* isdn_divert_icall */void deleteprocs(void){ struct call_struc *cs, *cs1;   unsigned long flags;  spin_lock_irqsave(&divert_lock, flags);  cs = divert_head;  divert_head = NULL;  while (cs)   { del_timer(&cs->timer);     cs1 = cs;     cs = cs->next;     kfree(cs1);   }   spin_unlock_irqrestore(&divert_lock, flags);} /* deleteprocs *//****************************************************//* put a address including address type into buffer *//****************************************************/static int put_address(char *st, u_char *p, int len){ u_char retval = 0;  u_char adr_typ = 0; /* network standard */  if (len < 2) return(retval);  if (*p == 0xA1)   { retval = *(++p) + 2; /* total length */     if (retval > len) return(0); /* too short */     len = retval - 2; /* remaining length */     if (len < 3) return(0);     if ((*(++p) != 0x0A) || (*(++p) != 1)) return(0);     adr_typ = *(++p);     len -= 3;     p++;     if (len < 2) return(0);     if (*p++ != 0x12) return(0);     if (*p > len) return(0); /* check number length */     len = *p++;   }     else   if (*p == 0x80)    { retval = *(++p) + 2; /* total length */      if (retval > len) return(0);      len = retval - 2;      p++;    }   else      return(0); /* invalid address information */  sprintf(st,"%d ",adr_typ);  st += strlen(st);  if (!len)     *st++ = '-';  else   while (len--)     *st++ = *p++;  *st = '\0';  return(retval);} /* put_address *//*************************************//* report a succesfull interrogation *//*************************************/static int interrogate_success(isdn_ctrl *ic, struct call_struc *cs){ char *src = ic->parm.dss1_io.data;  int restlen = ic->parm.dss1_io.datalen;  int cnt = 1;  u_char n,n1;  char st[90], *p, *stp;  if (restlen < 2) return(-100); /* frame too short */  if (*src++ != 0x30) return(-101);  if ((n = *src++) > 0x81) return(-102); /* invalid length field */  restlen -= 2; /* remaining bytes */  if (n == 0x80)   { if (restlen < 2) return(-103);     if ((*(src+restlen-1)) || (*(src+restlen-2))) return(-104);     restlen -= 2;   }  else   if ( n == 0x81)    { n = *src++;      restlen--;      if (n > restlen) return(-105);      restlen = n;    }   else    if (n > restlen) return(-106);     else       restlen = n; /* standard format */     if (restlen < 3) return(-107); /* no procedure */  if ((*src++ != 2) || (*src++ != 1) || (*src++ != 0x0B)) return(-108);  restlen -= 3;   if (restlen < 2) return(-109); /* list missing */  if (*src == 0x31)   { src++;      if ((n = *src++) > 0x81) return(-110); /* invalid length field */     restlen -= 2; /* remaining bytes */     if (n == 0x80)      { if (restlen < 2) return(-111);        if ((*(src+restlen-1)) || (*(src+restlen-2))) return(-112);        restlen -= 2;      }     else      if ( n == 0x81)       { n = *src++;         restlen--;         if (n > restlen) return(-113);         restlen = n;       }      else       if (n > restlen) return(-114);        else          restlen = n; /* standard format */      } /* result list header */   while (restlen >= 2)   { stp = st;     sprintf(stp,"%d 0x%lx %d %s ",DIVERT_REPORT, ic->parm.dss1_io.ll_id,                 cnt++,divert_if.drv_to_name(ic->driver));     stp += strlen(stp);     if (*src++ != 0x30) return(-115); /* invalid enum */     n = *src++;     restlen -= 2;     if (n > restlen) return(-116); /* enum length wrong */     restlen -= n;     p = src; /* one entry */     src += n;     if (!(n1 = put_address(stp,p,n & 0xFF))) continue;     stp += strlen(stp);     p += n1;     n -= n1;     if (n < 6) continue; /* no service and proc */     if ((*p++ != 0x0A) || (*p++ != 1)) continue;     sprintf(stp," 0x%02x ",(*p++) & 0xFF);     stp += strlen(stp);     if ((*p++ != 0x0A) || (*p++ != 1)) continue;     sprintf(stp,"%d ",(*p++) & 0xFF);     stp += strlen(stp);     n -= 6;     if (n > 2)      { if (*p++ != 0x30) continue;        if (*p > (n-2)) continue;        n = *p++;        if (!(n1 = put_address(stp,p,n & 0xFF))) continue;        stp += strlen(stp);      }     sprintf(stp,"\n");     put_info_buffer(st);   } /* while restlen */  if (restlen) return(-117);  return(0);   } /* interrogate_success *//*********************************************//* callback for protocol specific extensions *//*********************************************/static int prot_stat_callback(isdn_ctrl *ic){ struct call_struc *cs, *cs1;  int i;  unsigned long flags;  cs = divert_head; /* start of list */  cs1 = NULL;  while (cs)   { if (ic->driver == cs->ics.driver)       { switch (cs->ics.arg)	 { case DSS1_CMD_INVOKE:             if ((cs->ics.parm.dss1_io.ll_id == ic->parm.dss1_io.ll_id) &&                 (cs->ics.parm.dss1_io.hl_id == ic->parm.dss1_io.hl_id))	      { switch (ic->arg)		{  case DSS1_STAT_INVOKE_ERR:                     sprintf(cs->info,"128 0x%lx 0x%x\n",                              ic->parm.dss1_io.ll_id,                             ic->parm.dss1_io.timeout);                     put_info_buffer(cs->info);                   break;                                      case DSS1_STAT_INVOKE_RES:                     switch (cs->ics.parm.dss1_io.proc)		      {  case  7:                         case  8:                            put_info_buffer(cs->info);                            break;                                                case  11:                           i = interrogate_success(ic,cs);                           if (i)                             sprintf(cs->info,"%d 0x%lx %d\n",DIVERT_REPORT,                                      ic->parm.dss1_io.ll_id,i);                           put_info_buffer(cs->info);                            break;                       		         default:                            printk(KERN_WARNING "dss1_divert: unknown proc %d\n",cs->ics.parm.dss1_io.proc);                           break;                      }                    break; 		   default:                     printk(KERN_WARNING "dss1_divert unknown invoke answer %lx\n",ic->arg);                   break;                   }                 cs1 = cs; /* remember structure */                cs = NULL;                 continue; /* abort search */              } /* id found */            break;   	   case DSS1_CMD_INVOKE_ABORT:             printk(KERN_WARNING "dss1_divert unhandled invoke abort\n");            break;            	   default:             printk(KERN_WARNING "dss1_divert unknown cmd 0x%lx\n",cs->ics.arg);            break;          } /* switch ics.arg */         cs = cs->next;       } /* driver ok */   }       if (!cs1)    { printk(KERN_WARNING "dss1_divert unhandled process\n");     return(0);   }    if (cs1->ics.driver == -1)   {     spin_lock_irqsave(&divert_lock, flags);     del_timer(&cs1->timer);     if (cs1->prev)        cs1->prev->next = cs1->next; /* forward link */     else       divert_head = cs1->next;     if (cs1->next)       cs1->next->prev = cs1->prev; /* back link */                spin_unlock_irqrestore(&divert_lock, flags);     kfree(cs1);   }   return(0);} /* prot_stat_callback *//***************************//* status callback from HL *//***************************/static int isdn_divert_stat_callback(isdn_ctrl *ic){ struct call_struc *cs, *cs1;  unsigned long flags;  int retval;  retval = -1;  cs = divert_head; /* start of list */     while (cs)      { if ((ic->driver == cs->ics.driver) && (ic->arg == cs->ics.arg))         { switch (ic->command)	    { case ISDN_STAT_DHUP:                sprintf(cs->info,"129 0x%lx\n",cs->divert_id);                del_timer(&cs->timer);                cs->ics.driver = -1;                break;	      case ISDN_STAT_CAUSE:                sprintf(cs->info,"130 0x%lx %s\n",cs->divert_id,ic->parm.num);                break;	      case ISDN_STAT_REDIR:                sprintf(cs->info,"131 0x%lx\n",cs->divert_id);                del_timer(&cs->timer);                cs->ics.driver = -1;                break; 	      default:                sprintf(cs->info,"999 0x%lx 0x%x\n",cs->divert_id,(int)(ic->command));                break;             }          put_info_buffer(cs->info);          retval = 0;          }        cs1 = cs;         cs = cs->next;        if (cs1->ics.driver == -1)          {             spin_lock_irqsave(&divert_lock, flags);            if (cs1->prev)               cs1->prev->next = cs1->next; /* forward link */            else              divert_head = cs1->next;            if (cs1->next)              cs1->next->prev = cs1->prev; /* back link */                       spin_unlock_irqrestore(&divert_lock, flags);            kfree(cs1);          }       }    return(retval); /* not found */} /* isdn_divert_stat_callback */ /********************//* callback from ll *//********************/ int ll_callback(isdn_ctrl *ic){  switch (ic->command)   { case ISDN_STAT_ICALL:     case ISDN_STAT_ICALLW:       return(isdn_divert_icall(ic));     break;     case ISDN_STAT_PROT:       if ((ic->arg & 0xFF) == ISDN_PTYPE_EURO)	{ if (ic->arg != DSS1_STAT_INVOKE_BRD)            return(prot_stat_callback(ic));          else            return(0); /* DSS1 invoke broadcast */        }       else         return(-1); /* protocol not euro */         default:       return(isdn_divert_stat_callback(ic));   }} /* ll_callback */

⌨️ 快捷键说明

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