Пример #1
0
bool
Layer3::registerBusmonitor (L_Busmonitor_CallBack * c)
{
  TRACEPRINTF (t, 3, this, "registerBusmontior %08X", c);
  if (individual ())
    return 0;
  if (group ())
    return 0;
  if (broadcast ())
    return 0;
  if (mode == 0)
    {
      layer2->Close ();
      if (!layer2->enterBusmonitor ())
	{
	  layer2->Open ();
	  return 0;
	}
    }
  mode = 1;
  busmonitor.resize (busmonitor () + 1);
  busmonitor[busmonitor () - 1].cb = c;
  TRACEPRINTF (t, 3, this, "registerBusmontior %08X = 1", c);
  return 1;
}
Пример #2
0
bool
Layer3::deregisterBusmonitor (L_Busmonitor_CallBack * c)
{
  unsigned i;
  for (i = 0; i < busmonitor (); i++)
    if (busmonitor[i].cb == c)
      {
	busmonitor[i] = busmonitor[busmonitor () - 1];
	busmonitor.resize (busmonitor () - 1);
	if (busmonitor () == 0)
          for (unsigned int i = 0; i < layer2 (); i++)
            if (layer2[i]->leaveBusmonitor ())
              layer2[i]->Open ();
	TRACEPRINTF (t, 3, this, "deregisterBusmonitor %08X = 1", c);
	return 1;
      }
  TRACEPRINTF (t, 3, this, "deregisterBusmonitor %08X = 0", c);
  return 0;
}
Пример #3
0
bool
Layer3::registerBusmonitor (L_Busmonitor_CallBack * c)
{
  TRACEPRINTF (t, 3, this, "registerBusmonitor %08X", c);
  if (!busmonitor()) 
    {
      bool have_monitor = false;
      for (unsigned int i = 0; i < layer2 (); i++)
        if (layer2[i]->Close ()) 
          {
            if (layer2[i]->enterBusmonitor ())
              have_monitor = true;
            else
              layer2[i]->Open ();
          }
      if (! have_monitor)
        return false;
    }
  busmonitor.resize (busmonitor () + 1);
  busmonitor[busmonitor () - 1].cb = c;
  TRACEPRINTF (t, 3, this, "registerBusmontitr %08X = 1", c);
  return true;
}
Пример #4
0
bool
Layer3::registerLayer2 (Layer2 * l2)
{
  TRACEPRINTF (t, 3, this, "registerLayer2 %08X", l2);
  if (! busmonitor () || ! l2->enterBusmonitor ())
    if (! l2->Open ())
      {
        TRACEPRINTF (t, 3, this, "registerLayer2 %08X = 0", l2);
        return 0;
      }
  layer2.resize (layer2() + 1);
  layer2[layer2 () - 1] = l2;
  TRACEPRINTF (t, 3, this, "registerLayer2 %08X = 1", l2);
  return 1;
}
Пример #5
0
void
Layer3::Run (pth_sem_t * stop1)
{
  pth_event_t stop = pth_event (PTH_EVENT_SEM, stop1);
  unsigned i;

  while (pth_event_status (stop) != PTH_STATUS_OCCURRED)
    {
      LPDU *l = layer2->Get_L_Data (stop);
      if (!l)
	continue;
      if (l->getType () == L_Busmonitor)
	{
	  L_Busmonitor_PDU *l1, *l2;
	  l1 = (L_Busmonitor_PDU *) l;

	  TRACEPRINTF (t, 3, this, "Recv %s", l1->Decode ()());
	  for (i = 0; i < busmonitor (); i++)
	    {
	      l2 = new L_Busmonitor_PDU (*l1);
	      busmonitor[i].cb->Get_L_Busmonitor (l2);
	    }
	  for (i = 0; i < vbusmonitor (); i++)
	    {
	      l2 = new L_Busmonitor_PDU (*l1);
	      vbusmonitor[i].cb->Get_L_Busmonitor (l2);
	    }
	}
      if (l->getType () == L_Data)
	{
	  L_Data_PDU *l1;
	  l1 = (L_Data_PDU *) l;
	  if (l1->repeated)
	    {
	      CArray d1 = l1->ToPacket ();
	      for (i = 0; i < ignore (); i++)
		if (d1 == ignore[i].data)
		  {
		    TRACEPRINTF (t, 3, this, "Repeated discareded");
		    goto wt;
		  }
	    }
	  l1->repeated = 1;
	  ignore.resize (ignore () + 1);
	  ignore[ignore () - 1].data = l1->ToPacket ();
	  ignore[ignore () - 1].end = getTime () + 1000000;
	  l1->repeated = 0;

	  if (l1->AddrType == IndividualAddress
	      && l1->dest == layer2->getDefaultAddr ())
	    l1->dest = 0;
	  TRACEPRINTF (t, 3, this, "Recv %s", l1->Decode ()());

	  if (l1->AddrType == GroupAddress && l1->dest == 0)
	    {
	      for (i = 0; i < broadcast (); i++)
		broadcast[i].cb->Get_L_Data (new L_Data_PDU (*l1));
	    }
	  if (l1->AddrType == GroupAddress && l1->dest != 0)
	    {
	      for (i = 0; i < group (); i++)
		if (group[i].dest == l1->dest || group[i].dest == 0)
		  group[i].cb->Get_L_Data (new L_Data_PDU (*l1));
	    }
	  if (l1->AddrType == IndividualAddress)
	    {
	      for (i = 0; i < individual (); i++)
		if (individual[i].dest == l1->dest
		    || individual[i].dest == 0)
		  if (individual[i].src == l1->source
		      || individual[i].src == 0)
		    individual[i].cb->Get_L_Data (new L_Data_PDU (*l1));
	    }
	}
    redel:
      for (i = 0; i < ignore (); i++)
	if (ignore[i].end < getTime ())
	  {
	    ignore.deletepart (i, 1);
	    goto redel;
	  }
    wt:
      delete l;

    }
  pth_event_free (stop, PTH_FREE_THIS);
}
Пример #6
0
void
Layer3::Run (pth_sem_t * stop1)
{
  pth_event_t stop = pth_event (PTH_EVENT_SEM, stop1);
  unsigned i;

  running = true;
  for (i = 0; i < layer2 (); i++)
    layer2[i].Start ();

  TRACEPRINTF (t, 3, this, "L3 started");
  while (pth_event_status (stop) != PTH_STATUS_OCCURRED)
    {
      pth_event_t bufev = pth_event (PTH_EVENT_SEM, &bufsem);
      pth_event_concat (bufev, stop, NULL);
      pth_wait (bufev);
      pth_event_isolate (bufev);

      if (pth_event_status (bufev) != PTH_STATUS_OCCURRED)
        {
          pth_event_free (bufev, PTH_FREE_THIS);
          continue;
        }
      pth_event_free (bufev, PTH_FREE_THIS);

      pth_sem_dec (&bufsem);
      LPDU *l = buf.get ();
      if (!l)
	continue;
      if (l->getType () == L_Busmonitor)
	{
	  L_Busmonitor_PDU *l1, *l2;
	  l1 = (L_Busmonitor_PDU *) l;

	  TRACEPRINTF (t, 3, this, "Recv %s", l1->Decode ()());
	  for (i = 0; i < busmonitor (); i++)
	    {
	      l2 = new L_Busmonitor_PDU (*l1);
	      busmonitor[i].cb->Send_L_Busmonitor (l2);
	    }
	  for (i = 0; i < vbusmonitor (); i++)
	    {
	      l2 = new L_Busmonitor_PDU (*l1);
	      vbusmonitor[i].cb->Send_L_Busmonitor (l2);
	    }
	}
      if (l->getType () == L_Data)
	{
	  L_Data_PDU *l1;
	  l1 = (L_Data_PDU *) l;
	  if (l1->repeated)
	    {
	      CArray d1 = l1->ToPacket ();
	      for (i = 0; i < ignore (); i++)
		if (d1 == ignore[i].data)
		  {
		    TRACEPRINTF (t, 3, this, "Repeated discareded");
		    goto wt;
		  }
	    }
	  l1->repeated = 1;
	  ignore.resize (ignore () + 1);
	  ignore[ignore () - 1].data = l1->ToPacket ();
	  ignore[ignore () - 1].end = getTime () + 1000000;
	  l1->repeated = 0;

	  if (l1->AddrType == IndividualAddress
	      && l1->dest == defaultAddr)
	    l1->dest = 0;
	  TRACEPRINTF (t, 3, this, "Recv %s", l1->Decode ()());

	  if (l1->AddrType == GroupAddress && l1->dest == 0)
	    {
	      for (i = 0; i < broadcast (); i++)
		broadcast[i].cb->Send_L_Data (new L_Data_PDU (*l1));
	    }
	  if (l1->AddrType == GroupAddress && l1->dest != 0)
	    {
	      for (i = 0; i < group (); i++)
                {
                  Group_Info &grp = group[i];
		  if (grp.dest == l1->dest || grp.dest == 0)
		    grp.cb->Send_L_Data (new L_Data_PDU (*l1));
                }
	    }
	  if (l1->AddrType == IndividualAddress)
	    {
	      for (i = 0; i < individual (); i++)
                {
                  Individual_Info &indiv = individual[i];
		  if (indiv.dest == l1->dest || indiv.dest == 0)
		    if (indiv.src == l1->source || indiv.src == 0)
		      indiv.cb->Send_L_Data (new L_Data_PDU (*l1));
	        }
	    }

          // finally, send to all (other(?)) L2 interfaces
          // TODO: filter by addresses
          send_L_Data(l1);
	}
      // ignore[] is ordered, any timed-out items are at the front
      for (i = 0; i < ignore (); i++)
	if (ignore[i].end >= getTime ())
          break;
      if (i)
        ignore.deletepart (0, i);
    wt:
      delete l;

    }
  TRACEPRINTF (t, 3, this, "L3 stopping");

  running = false;
  for (i = 0; i < layer2 (); i++)
    layer2[i].Stop ();

  pth_event_free (stop, PTH_FREE_THIS);
}