-/*
- * hunts an mISDNport that is available for an outgoing call
- * if no ifname was given, any interface that is not an extension
- * will be searched.
- */
-static struct mISDNport *EndpointAppPBX::hunt_port(char *ifname, int *channel)
-{
- struct interface *interface;
- struct mISDNport *mISDNport;
-
- interface = interface_first;
-
- /* first find the given interface or, if not given, one with no extension */
- checknext:
- if (!interface)
- return(null);
-
- /* check for given interface */
- if (ifname)
- {
- if (!strcasecmp(interface->name, ifname))
- {
- /* found explicit interface */
- printlog("%3d interface %s found as given\n", ea_endpoint->ep_serial, ifname);
- goto found;
- }
-
- } else
- {
- if (!interface->extension)
- {
- /* found non extension */
- printlog("%3d interface %s found, that is not an extension\n", ea_endpoint->ep_serial, interface->name);
- goto found;
- }
- }
-
- interface = interface->next;
- goto checknext;
-
- /* see if interface has ports */
- if (!interface->ifport)
- {
- /* no ports */
- printlog("%3d interface %s has no active ports, skipping.\n", ea_endpoint->ep_serial, interface->name);
- interface = interface->next;
- goto checknext;
- }
-
- /* select port by algorithm */
- ifport_start = interface->port;
- index = 0;
- if (interface->hunt == HUNT_ROUNDROBIN)
- {
- while(ifport_start->next && index<interface->hunt_next)
- {
- ifport_start = ifport_start->next;
- i++;
- }
- printlog("%3d starting with port#%d position %d (round-robin)\n", ea_endpoint->ep_serial, ifport_start->portnum, index);
- }
-
- /* loop ports */
- ifport = ifport_start;
- nextport:
-
- /* see if port is available */
- if (!ifport->mISDNport)
- {
- printlog("%3d port#%d position %d is not available, skipping.\n", ea_endpoint->ep_serial, ifport->portnum, index);
- goto portbusy;
- }
- mISDNport = ifport->mISDNport;
-
-#warning admin block auch bei incomming calls
-#warning calls releasen, wenn port entfernt wird, geblockt wird
- /* see if port is administratively blocked */
- if (ifport->block)
- {
- printlog("%3d port#%d position %d is administratively blocked, skipping.\n", ea_endpoint->ep_serial, ifport->portnum, index);
- goto portbusy;
- }
-
- /* see if link is up */
- if (mISDNport->ptp && !mISDNport->l2link)
- {
- printlog("%3d port#%d position %d is ptp but layer 2 is down.\n", ea_endpoint->ep_serial, ifport->portnum, index);
- PDEBUG(DEBUG_EPOINT, "EPOINT(%d) skipping because it is PTP with L2 down\n", ea_endpoint->ep_serial);
- goto portbusy;
- }
-
- /* check for channel form selection list */
- *channel = 0;
- selchannel = ifport->selchannel;
- while(selchannel)
- {
- switch(selchannel->channel)
- {
- case CHANNEL_FREE: /* free channel */
- if (mISDNport->b_inuse >= mISDNport->b_num)
- break; /* all channel in use or reserverd */
- /* find channel */
- i = 0;
- while(i < mISDNport->b_num)
- {
- if (mISDNport->b_port[i] == NULL)
- {
- *channel = i+1+(i>=15);
- printlog("%3d port#%d position %d selecting free channel %d\n", ea_endpoint->ep_serial, ifport->portnum, index, *channel);
- break;
- }
- i++;
- }
- break;
-
- case CHANNEL_ANY: /* don't ask for channel */
- if (mISDNport->b_inuse >= mISDNport->b_num)
- {
- break; /* all channel in use or reserverd */
- }
- printlog("%3d port#%d position %d using with 'any channel'\n", ea_endpoint->ep_serial, ifport->portnum, index);
- *channel = SEL_CHANNEL_ANY;
- break;
-
- case CHANNEL_NO: /* call waiting */
- printlog("%3d port#%d position %d using with 'no channel'\n", ea_endpoint->ep_serial, ifport->portnum, index);
- *channel = SEL_CHANNEL_NO;
- break;
-
- default:
- if (selchannel->channel<1 || selchannel->channel==16)
- break; /* invalid channels */
- i = selchannel->channel-1-(selchannel->channel>=17);
- if (i >= mISDNport->b_num)
- break; /* channel not in port */
- if (mISDNport->b_port[i] == NULL)
- {
- *channel = selchannel->channel;
- printlog("%3d port#%d position %d selecting given channel %d\n", ea_endpoint->ep_serial, ifport->portnum, index, *channel);
- break;
- }
- break;
- }
- if (*channel)
- break; /* found channel */
- selchannel = selchannel->next;
- }
-
- /* if channel was found, return mISDNport and channel */
- if (*channel)
- {
- /* setting next port to start next time */
- if (interface->hunt == HUNT_ROUNDROBIN)
- {
- index++;
- if (!ifport->next)
- index = 0;
- interface->hunt_next = index;
- }
-
- return(mISDNport);
- }
-
- printlog("%3d port#%d position %d skipping, because no channel found.\n", ea_endpoint->ep_serial, ifport->portnum, index);
-
- portbusy:
- /* go next port, until all ports are checked */
- index++;
- ifport = ifport->next;
- if (!ifport)
- {
- index = 0;
- ifport = interface->ifport;
- }
- if (ifport != ifport_start)
- goto nextport;
-
- return(NULL); /* no port found */
-}
-