Logo Search packages:      
Sourcecode: bayonne version File versions  Download package

driver.cpp

// Copyright (C) 2000 Open Source Telecom Corporation.
//  
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
// 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software 
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
// As a special exception to the GNU General Public License, permission is
// granted for additional uses of the text contained in its release
// of Bayonne as noted here.
//
// This exception is that permission is hereby granted to link Bayonne 
// with  the Pika MonteCarlo libraries to produce a executable image
// without requiring MonteCarlo itself to be supplied in source form so
// long as each source file so linked contains this exclusion.
//
// This exception does not however invalidate any other reasons why
// the resulting executable file might be covered by the GNU General
// public license or invalidate the licensing requirements of any
// other component or library.
//
// This exception applies only to the code released by OST under the
// name Bayonne.  If you copy code from other releases into a copy of
// Bayonne, as the General Public License permits, the exception does not
// apply to the code that you add in this way.  To avoid misleading
// anyone as to the status of such modified files, you must delete
// this exception notice from them.
//
// If you write modifications of your own to Bayonne, it is your choice
// whether to permit this exception to apply to your modifications.
// If you do not wish that, delete this exception notice, at which
// point the terms of your modification would be covered under the GPL
// as explicitly stated in "COPYING".

#include "driver.h"

char *PikaDriver::names[] = {
      "Unknown",
      "V12",
      "Daytona",
      "Premiere",
      "Trans4M",
      "DSP Module",
      "InLine GT",
      "InLine GTB",
      "InLine EX",
      "InLine ST",
      "PrimeNet",
      "Daytona PCI",
      "Premiere PCI",
      "PrimeNet PCI"
};
 
PikaConfig::PikaConfig() :
Keydata("/bayonne/pika")
{
      static KEYDEF defkeys[] = {
      {"buffers", "4"},
      {"ringdebounce", "60"},
      {"members", "16"},
      {"groups", "8"},
      {NULL, NULL}};

      if(chkHosting(NULL))
            Load("/hosting/pika");

      Load(defkeys);
}

PikaDriver::PikaDriver() :
Driver()
{
      static SCRKEYWORDS keywords[] = {
            {"join", (scriptmethod_t)&PikaTrunk::scrJoin, &ScriptCommand::chkHasArgs},
            {"wait", (scriptmethod_t)&PikaTrunk::scrWait, &ScriptCommand::chkHasArgs},
            {"enter", (scriptmethod_t)&PikaTrunk::scrConf, &ScriptCommand::chkHasArgs},
            {"leave", (scriptmethod_t)&PikaTrunk::scrLeave, &ScriptCommand::chkNoArgs},
            {"detect", (scriptmethod_t)&PikaTrunk::scrDetect, &ScriptCommand::chkHasArgs},
            {"duplex", (scriptmethod_t)&PikaTrunk::scrDuplex, &ScriptCommand::chkHasArgs},
            {NULL, NULL, NULL}};

      int id;
      unsigned trkcount, dspcount;
      unsigned good = 0;
      unsigned confgroups = getMixerGroups();

      keyflag = false;
      dsps = NULL;
      ports = NULL;
      groups = NULL;
      dsp_count = 0;
      conf_count = 0;
      port_count = 0;
      mixer_count = 0;
      card_count = PK_CTI_NumberOfBoards();

      for(id = 0; id < card_count; ++id)
      {
            if(PK_CTI_Reset(id))
            {
                  slog(SLOG_ERROR) << getCardName(id) << ": cti reset failed" << endl;
                  continue;
            }

            if(PK_DSP_Reset(id))
            {
                  slog(SLOG_ERROR) << getCardName(id) << ": dsp reset failed" << endl;
                  continue;
            }

            if(PK_CTI_Initialize(id))
            {
                  slog(SLOG_ERROR) << getCardName(id) << ": init failed" << endl;
                  continue;
            }

            PK_TRUNK_SetRingDetect(id, pikaivr.getRingDebounce());

            if(PK_MVIP_Initialize(id))
            {
                  slog(SLOG_ERROR) << getCardName(id) << ": mvip failed" << endl;
                  continue;
            }

            if(PK_DSP_Initialize(id))
            {
                  slog(SLOG_ERROR) << getCardName(id) << ": dsp failed" << endl;
                  continue;
            }

            ++good;
            trkcount = PK_TRUNK_NumberOfTrunks(id);
            port_count += trkcount;

            dspcount = PK_DSP_NumberOfDevices(id);
            dsp_count += dspcount;
            slog() << getCardName(id) << " started; trunks=" <<
                  trkcount << " dsp=" << dsp_count << endl;
      }

      if(!port_count)
      {
            slog(SLOG_ERROR) << "pika driver failed" << endl;
            return;
      }

      // dsp devices
      dsps = new trunkdsp_t[card_count];
      ports = new PikaTrunk *[port_count];
      conf = new PikaConf *[dsp_count * confgroups];
      mixer = new PikaMixer *[dsp_count];
      groups = new TrunkGroup *[port_count];
      memset(dsps, 0, sizeof(trunkdsp_t) * card_count);
      memset(ports, 0, sizeof(PikaTrunk *) * port_count);
      memset(groups, 0, sizeof(TrunkGroup *) * port_count);
      memset(conf, 0, sizeof(PikaConf *) * dsp_count);
      status = PikaTrunk::status = new char[port_count];
      memset(status, ' ', port_count);

      slog(SLOG_INFO) << "Pika driver loaded " << good << " of " << card_count
            << " cards; trunks=" << port_count << ", dsps=" << dsp_count << endl;


      ScriptCommand::Load(keywords);
      ccxx_sleep(4000);
}

PikaDriver::~PikaDriver()
{
      Stop();
      
      if(dsps)
            delete[] dsps;

      if(ports)
            delete[] ports;

      if(groups)
            delete[] groups;

      if(conf)
            delete[] conf;

      if(mixer)
            delete[] mixer;

      delete[] PikaTrunk::status;
      PikaTrunk::status = NULL;
}

int PikaDriver::Start(void)
{
      static TPatternState StateTable[3][2] = {
            {{1000 - 100, 2000 + 100}, {3000 - 100, 4000 + 100}},  //ringback
            {{ 500 - 100,  500 + 100}, { 500 - 100,  500 + 100}},  //busy
            {{ 250 -  50,  250 +  50}, { 250 -  50,  250 +  50}}}; //fail

      TResourceHandle hRes;
      int pat = 0;
      int count = 0;
      int card = 0;
      int grp, grpmax = getMixerGroups();
      int dsp, dsp_count;
      TResourceHandle hGrp, hDsp;

      if(active)
      {
            slog(SLOG_ERROR) << "driver already started" << endl;
            return 0;
      }

      for(card = 0; card < card_count; ++card)
      {
            dsp = 0;
            dsp_count = PK_DSP_NumberOfDevices(card);
            if(dsp_count > MAX_DSP_DEVICES)
                  dsp_count = MAX_DSP_DEVICES;

            while(dsp < dsp_count)
            {
                  hDsp = dsps[card].dsp[dsp] = PK_DSP_GetDeviceHandle(card, dsp);
                  if(!hDsp)
                  {
                        slog(SLOG_ERROR) << "dsp: failed; card=" << card << " device=" << dsp << endl;
                        ++dsp;
                        continue;
                  }
                  slog(SLOG_DEBUG) << "dsp: activated; card=" << card << ", device=" << dsp << endl;
                  ++dsp;
                  mixer[mixer_count] = new PikaMixer(hDsp, conf_count);
                  grp = 0;
                  while(grp < grpmax)
                  {
                        hGrp = PK_VC_CreateGroup(hDsp);
                        if(!hGrp)
                              break;
                        conf[conf_count++] = new PikaConf(mixer[mixer_count], hGrp);
                        ++grp;
                  }
                  if(grp)
                        mixer[mixer_count++]->setGroups(grp);
                  ++dsp;
            }
      }

      cpTable = PK_PAT_CreateTable(3);
      PK_PAT_MatchLastOnTimeout(cpTable, PK_FALSE);
      while(pat < 3)
            PK_PAT_AddPattern(cpTable, PK_ATD_CALL_PROGRESS_TONE,
                  StateTable[pat++], 2);
      
      card = 0;
      while(card < card_count && count < port_count)
      {
            if((hRes = PK_TRUNK_SeizeResource(card, (TNetworkInterfaceType)(PK_LS_PORT))))
            {
                  ports[count] = new PikaTrunk(hRes, (trunknti_t)PK_LS_PORT, card, count);
                  ++count;
                  continue;
            }
            if((hRes = PK_TRUNK_SeizeResource(card, (TNetworkInterfaceType)(PK_DID_PORT))))
            {
                  ports[count] = new PikaTrunk(hRes, (trunknti_t)PK_DID_PORT, card, count);
                  ++count;
                  continue;
            }
            if((hRes = PK_TRUNK_SeizeResource(card, (TNetworkInterfaceType)(PK_EM_PORT))))
            {
                  ports[count] = new PikaTrunk(hRes, (trunknti_t)PK_EM_PORT, card, count);
                  ++count;
                  continue;
            }
            ++card;
      }

      slog(SLOG_INFO) << "conf: initialized " << conf_count << " groups  from " << mixer_count << " mixers" << endl;

      active = true;
      return count;
}

void PikaDriver::Stop(void)
{
      int id = 0, dsp;
      if(!active || !card_count)
            return;

      active = false;
      if(!ports)
      {
            slog(SLOG_INFO) << "driver stopped" << endl;
            return;
      }

      for(id = 0; id < port_count; ++id)
      {
            if(ports[id])
                  delete (ports[id]);
      }

      for(id = 0; id < conf_count; ++id)
      {
            if(conf[id])
                  delete (conf[id]);
      }

      for(id = 0; id < mixer_count; ++id)
      {
            if(mixer[id])
                  delete (mixer[id]);
      }

      for(id = 0; id < card_count; ++id)
            PK_DSP_StopDriver(id);

      for(id = 0; id < card_count; ++id)
      {
            PK_CTI_StopDriver(id);
            PK_MVIP_StopDriver(id);
      }

      PK_PAT_DeleteTable(cpTable);
      memset(dsps, 0, sizeof(trunkdsp_t) * card_count);
      memset(ports, 0, sizeof(PikaTrunk *) * port_count);
      slog(SLOG_INFO) << "driver stopping..." << endl;
}

Conference *PikaDriver::getConference(int id)
{
      if(id < 0 || id >= conf_count)
            return NULL;

      return (Conference *)conf[id];
}

Mixer *PikaDriver::getMixer(int id)
{
      if(id < 0 || id >= mixer_count)
            return NULL;

      return (Mixer *)mixer[id];
}

Trunk *PikaDriver::getTrunkPort(int id)
{
      if(id < 0 || id >= port_count)
            return NULL;

      if(!ports)
            return NULL;

      return (Trunk *)ports[id];
}

TResourceHandle PikaDriver::getDSPResource(unsigned card, unsigned mask)
{
      TResourceHandle hRes = 0;
      int dsp;

      for(dsp = 0; dsp < MAX_DSP_DEVICES; ++dsp)
      {
            if(dsps[card].dsp[dsp])
                  hRes = PK_DSP_SeizePort(dsps[card].dsp[dsp], mask);
            if(hRes)
                  return hRes;
      }

      for(card = 0; card < card_count; ++card)
            for(dsp = 0; dsp < MAX_DSP_DEVICES; ++dsp)
            {
                  if(dsps[card].dsp[dsp])
                        hRes = PK_DSP_SeizePort(dsps[card].dsp[dsp], mask);
                  if(hRes)
                        return hRes;
            }
      return 0;
}

char *PikaDriver::getCardName(int id)
{
      PK_WORD ctype;

      if(id >= card_count)
            return "Invalid";

      ctype = PK_CTI_BoardType(id & ~0x1000000);
      if(ctype < (sizeof(names) / sizeof(char *)))
            return names[ctype];
      else
            return "Undefined";
}

PikaDriver pikaivr;

Generated by  Doxygen 1.6.0   Back to index