Exemplo n.º 1
0
  void TracFacilities_c::processMsg( const CanPkg_c& arc_data )
  {
    CanPkgExt_c pkg( arc_data, getMultitonInst() );
    if( !pkg.isValid() || (pkg.getMonitorItemForSA() == NULL) )
      return;

    IsoName_c const& rcc_tempISOName = pkg.getISONameForSA();

    switch (pkg.isoPgn() & 0x3FF00LU)
    {
      case TRACTOR_FACILITIES_PGN:
        if ( checkParseReceived (rcc_tempISOName) )
        { // sender is allowed to send

          for (uint8_t ui8_counter = 0;ui8_counter<sizeof(arrui8_facilitiesBitData)/sizeof(uint8_t);++ui8_counter)
            arrui8_facilitiesBitData[ui8_counter] = pkg.getUint8Data(ui8_counter);

          setSelectedDataSourceISOName (rcc_tempISOName);
          setUpdateTime( pkg.time() );
        } else
        { // there is a sender conflict
          IsoAgLib::getILibErrInstance().registerNonFatal( IsoAgLib::iLibErr_c::TracMultipleSender, getMultitonInst() );
        }
      break;
    }
  }
Exemplo n.º 2
0
IsoItem_c &
IsoMonitor_c::insertIsoMember(
  const IsoName_c& acrc_isoName,
  uint8_t aui8_nr,
  IState_c::itemState_t ren_state,
  IdentItem_c* apc_identItemForLocalItems,
  bool ab_announceAddition )
{
  isoaglib_assert( item( acrc_isoName ) == NULL );

  // prepare temp item with wanted data
  mc_tempIsoMemberItem.set (System_c::getTime(), // Actually this value/time can be anything. The time is NOT used in PreAddressClaim and when entering AddressClaim it is being set correctly!
    acrc_isoName, aui8_nr, IState_c::itemState_t(ren_state | IState_c::Active), getMultitonInst() );
  // if it's a local item, we need to set the back-reference.
  if (apc_identItemForLocalItems)
    mc_tempIsoMemberItem.setIdentItem(*apc_identItemForLocalItems);

  // now insert element
  mvec_isoMember.push_front(mc_tempIsoMemberItem);
  IsoItem_c &insertedItem = *mvec_isoMember.begin();

  if( ren_state & ( IState_c::AddressClaim | IState_c::ClaimedAddress ) ) {
    // update lookup
    updateSaItemTable( insertedItem, true );
  }

  if (ab_announceAddition)
  { // immediately announce addition.
    // only not do this if you insert a local isoitem that is in state "AddressClaim" - it will be done there if it changes its state to "ClaimedAddress".
    broadcastIsoItemModification2Clients( ControlFunctionStateHandler_c::AddToMonitorList, insertedItem );
  }

  return insertedItem;
}
Exemplo n.º 3
0
  void TracPTO_c::processMsg( const CanPkg_c& arc_data )
  {
    CanPkgExt_c pkg( arc_data, getMultitonInst() );
    if( !pkg.isValid() || (pkg.getMonitorItemForSA() == NULL) )
      return;

    IsoName_c const& rcc_tempISOName = pkg.getISONameForSA();

    if (((pkg.isoPgn() /*& 0x3FFFF*/) == FRONT_PTO_STATE_PGN) || ((pkg.isoPgn() /*& 0x3FFFF*/) == REAR_PTO_STATE_PGN))
    {
      const ecutime_t ci32_now = pkg.time();
      // only take values, if i am not the regular sender
      // and if actual sender isn't in conflict to previous sender
      if ( checkParseReceived( rcc_tempISOName ) )
      { // sender is allowed to send
        PtoData_t* pt_ptoData = NULL;
        if (pkg.isoPgn() == FRONT_PTO_STATE_PGN)
        { // front PTO
          pt_ptoData = &mt_ptoFront;
        }
        else
        { // rear PTO
          pt_ptoData = &mt_ptoRear;
        }

        pt_ptoData->i32_lastPto = ci32_now;
        pt_ptoData->ui16_pto8DigitPerRpm         = pkg.getUint16Data(0);
        pt_ptoData->ui16_ptoSetPoint8DigitPerRpm = pkg.getUint16Data(2);
        pt_ptoData->t_ptoEngaged = IsoAgLib::IsoActiveFlag_t(          (    pkg.getUint8Data(4) >> 6) & 3 );
        pt_ptoData->t_pto1000    = IsoAgLib::IsoActiveFlag_t(          (    pkg.getUint8Data(4) >> 4) & 3 );
        pt_ptoData->t_ptoEconomy = IsoAgLib::IsoActiveFlag_t(          (    pkg.getUint8Data(4) >> 2) & 3 );
        pt_ptoData->t_ptoEngagementReqStatus   = IsoAgLib::IsoReqFlag_t(    pkg.getUint8Data(4)       & 3 );
        pt_ptoData->t_ptoModeReqStatus         = IsoAgLib::IsoReqFlag_t(   (pkg.getUint8Data(5) >> 6) & 3 );
        pt_ptoData->t_ptoEconomyModeReqStatus  = IsoAgLib::IsoReqFlag_t(   (pkg.getUint8Data(5) >> 4) & 3 );
        pt_ptoData->t_ptoShaftSpeedLimitStatus = IsoAgLib::IsoLimitFlag_t( (pkg.getUint8Data(5) >> 1) & 0x7 );

        // set last time
        setSelectedDataSourceISOName (rcc_tempISOName);
        // update time
        pt_ptoData->i32_lastPto = pkg.time();
        // must be set because this is needed in basecommon_c
        setUpdateTime( pt_ptoData->i32_lastPto );

        //msg from Tractor received do tell Scheduler_c next call not until  3000ms
        mt_task.setNextTriggerTime( pkg.time() + CONFIG_TIMEOUT_TRACTOR_DATA );
      }

      else
      { // there is a sender conflict
        IsoAgLib::getILibErrInstance().registerNonFatal( IsoAgLib::iLibErr_c::TracMultipleSender, getMultitonInst() );
      }
    }
Exemplo n.º 4
0
bool
IsoMonitor_c::registerIdentItem( IdentItem_c& arc_item )
{
  const bool cb_activationSuccess
    = arc_item.activate( getMultitonInst() );

  if (cb_activationSuccess)
  { // Could activate it, so register it!
    /// IsoMonitor_c.timeEvent() should be called from Scheduler_c in 50 ms
    setNextTriggerTime( System_c::getTime() + 50 );
    (void) registerC1 (&arc_item);
    return true;
  }
  else
  { // Couldn't activate it, so we don't register it
    return false;
  }
}
Exemplo n.º 5
0
  void TracLight_c::processMsg( const CanPkg_c& arc_data )
  {    
    CanPkgExt_c pkg( arc_data, getMultitonInst() );
    if( !pkg.isValid() || (pkg.getMonitorItemForSA() == NULL) )
      return;

    IsoName_c const& rcc_tempISOName = pkg.getISONameForSA();

    lightBitData_t* pt_data = NULL;

    switch (pkg.isoPgn() /*& 0x3FFFF*/) // don't need to &, we're interested in the whole PGN!
    {
      case LIGHTING_DATA_PGN:
        // lighting state information is sent by more than one sender -> store ALL messages with SA as key in STL_NAMESPACE::map
        pt_data = &(mmap_data[pkg.isoSa()]);
        if (pt_data != NULL)
          pt_data->dataMsgReq = IsoAgLib::IsoDontCare; //reserved field in lighting data
        break;
      case LIGHTING_COMMAND_PGN:
        // CMD is EXCLUSIVELY SENT BY ONE TRACTOR ECU!!! --> CHECK
        if ( checkParseReceived (rcc_tempISOName) )
        { // sender is allowed to send
          pt_data = &mt_cmd;
          mt_cmd.dataMsgReq = IsoAgLib::IsoDataReq_t( pkg.getUint8Data(7) & 3 );

          if (mt_cmd.dataMsgReq == IsoAgLib::IsoDataRequested)
            mb_cmdWait4Response = true;

          // set last time - use the array of send time stamps which is needed in tractor mode
          // in implement mode, the first item can be used to trace received tractor commands
          marr_timeStamp[0] = pkg.time();

          setSelectedDataSourceISOName (rcc_tempISOName);
          setUpdateTime( pkg.time() );
        } else
        { // there is a sender conflict
          IsoAgLib::getILibErrInstance().registerNonFatal( IsoAgLib::iLibErr_c::TracMultipleSender, getMultitonInst() );
        }
        break;
    }

    if ( pt_data == NULL )
    { // preconditions for parsing of this message are NOT fullfilled --> exit function with false
      return;
    }
    // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    // from here on, we can safely process the message as all preconditions are fullfilled
    // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    uint16_t ui16_temp = pkg.getUint16Data( 0 );
    pt_data->daytimeRunning =       IsoAgLib::IsoActiveFlag_t( (ui16_temp >>  0) & 3 ) ;
    pt_data->alternateHead  =       IsoAgLib::IsoActiveFlag_t( (ui16_temp >>  2) & 3 ) ;
    pt_data->lowBeamHead  =         IsoAgLib::IsoActiveFlag_t( (ui16_temp >>  4) & 3 ) ;
    pt_data->highBeamHead  =        IsoAgLib::IsoActiveFlag_t( (ui16_temp >>  6) & 3 ) ;
    pt_data->frontFog =             IsoAgLib::IsoActiveFlag_t( (ui16_temp >>  8) & 3 ) ;
    pt_data->beacon  =              IsoAgLib::IsoActiveFlag_t( (ui16_temp >> 10) & 3 ) ;
    pt_data->rightTurn  =           IsoAgLib::IsoActiveFlag_t( (ui16_temp >> 12) & 3 ) ;
    pt_data->leftTurn  =            IsoAgLib::IsoActiveFlag_t( (ui16_temp >> 14) & 3 ) ;
    ui16_temp = pkg.getUint16Data( 2 );
    pt_data->backUpLightAlarmHorn = IsoAgLib::IsoActiveFlag_t( (ui16_temp >>  0) & 3 ) ;
    pt_data->centerStop  =          IsoAgLib::IsoActiveFlag_t( (ui16_temp >>  2) & 3 ) ;
    pt_data->rightStop  =           IsoAgLib::IsoActiveFlag_t( (ui16_temp >>  4) & 3 ) ;
    pt_data->leftStop  =            IsoAgLib::IsoActiveFlag_t( (ui16_temp >>  6) & 3 ) ;
    pt_data->implClearance =        IsoAgLib::IsoActiveFlag_t( (ui16_temp >>  8) & 3 ) ;
    pt_data->tracClearance  =       IsoAgLib::IsoActiveFlag_t( (ui16_temp >> 10) & 3 ) ;
    pt_data->implMarker  =          IsoAgLib::IsoActiveFlag_t( (ui16_temp >> 12) & 3 ) ;
    pt_data->tracMarker  =          IsoAgLib::IsoActiveFlag_t( (ui16_temp >> 14) & 3 ) ;
    ui16_temp = pkg.getUint16Data( 4 );
    pt_data->rearFog =              IsoAgLib::IsoActiveFlag_t( (ui16_temp >>  0) & 3 ) ;
    pt_data->undersideWork  =       IsoAgLib::IsoActiveFlag_t( (ui16_temp >>  2) & 3 ) ;
    pt_data->rearLowWork  =         IsoAgLib::IsoActiveFlag_t( (ui16_temp >>  4) & 3 ) ;
    pt_data->rearHighWork  =        IsoAgLib::IsoActiveFlag_t( (ui16_temp >>  6) & 3 ) ;
    pt_data->sideLowWork =          IsoAgLib::IsoActiveFlag_t( (ui16_temp >>  8) & 3 ) ;
    pt_data->sideHighWork  =        IsoAgLib::IsoActiveFlag_t( (ui16_temp >> 10) & 3 ) ;
    pt_data->frontLowWork  =        IsoAgLib::IsoActiveFlag_t( (ui16_temp >> 12) & 3 ) ;
    pt_data->frontHighWork  =       IsoAgLib::IsoActiveFlag_t( (ui16_temp >> 14) & 3 ) ;
    ui16_temp = pkg.getUint16Data( 6 );
    pt_data->implOEMOpt2 =          IsoAgLib::IsoActiveFlag_t( (ui16_temp >>  0) & 3 ) ;
    pt_data->implOEMOpt1  =         IsoAgLib::IsoActiveFlag_t( (ui16_temp >>  2) & 3 ) ;
    pt_data->implRightForwardWork  =IsoAgLib::IsoActiveFlag_t( (ui16_temp >>  4) & 3 ) ;
    pt_data->implLeftForwardWork  = IsoAgLib::IsoActiveFlag_t( (ui16_temp >>  6) & 3 ) ;
    // pt_data->dataMsgReq is treated separately
    pt_data->implRightFacingWork  = IsoAgLib::IsoActiveFlag_t( (ui16_temp >> 10) & 3 ) ;
    pt_data->implLeftFacingWork  =  IsoAgLib::IsoActiveFlag_t( (ui16_temp >> 12) & 3 ) ;
    pt_data->implRearWork  =        IsoAgLib::IsoActiveFlag_t( (ui16_temp >> 14) & 3 ) ;

    if ( mb_cmdWait4Response )
      sendMessage();
  }
Exemplo n.º 6
0
  void TracAux_c::processMsg( const CanPkg_c& arc_data )
  {
    CanPkgExt_c pkg( arc_data, getMultitonInst() );
    if( !pkg.isValid() || (pkg.getMonitorItemForSA() == NULL) )
      return;

    IsoName_c const& rcc_tempISOName = pkg.getISONameForSA();

    unsigned int valveNumber = 15;
    const int32_t ci32_now = pkg.time();

    switch (pkg.isoPgn() /*& 0x3FFFF*/) // don't need to &, as this is the complete PGN anyway...
    {
      case AUX_VALVE_0_ESTIMATED_FLOW:
        valveNumber--;
      case AUX_VALVE_1_ESTIMATED_FLOW:
        valveNumber--;
      case AUX_VALVE_2_ESTIMATED_FLOW:
        valveNumber--;
      case AUX_VALVE_3_ESTIMATED_FLOW:
        valveNumber--;
      case AUX_VALVE_4_ESTIMATED_FLOW:
        valveNumber--;
      case AUX_VALVE_5_ESTIMATED_FLOW:
        valveNumber--;
      case AUX_VALVE_6_ESTIMATED_FLOW:
        valveNumber--;
      case AUX_VALVE_7_ESTIMATED_FLOW:
        valveNumber--;
      case AUX_VALVE_8_ESTIMATED_FLOW:
        valveNumber--;
      case AUX_VALVE_9_ESTIMATED_FLOW:
        valveNumber--;
      case AUX_VALVE_10_ESTIMATED_FLOW:
        valveNumber--;
      case AUX_VALVE_11_ESTIMATED_FLOW:
        valveNumber--;
      case AUX_VALVE_12_ESTIMATED_FLOW:
        valveNumber--;
      case AUX_VALVE_13_ESTIMATED_FLOW:
        valveNumber--;
      case AUX_VALVE_14_ESTIMATED_FLOW:
        valveNumber--;
      case AUX_VALVE_15_ESTIMATED_FLOW:
        if ( checkParseReceived( rcc_tempISOName ) )
        { // sender is allowed to send
          marr_valve[valveNumber].ui8_extendPortEstFlow = pkg.getUint8Data(0);
          marr_valve[valveNumber].ui8_retractPortEstFlow = pkg.getUint8Data(1);
          marr_valve[valveNumber].ui8_estFailSaveMode = ( (pkg.getUint8Data(2) >> 6) & 3 );
          marr_valve[valveNumber].ui8_estValveState = ( pkg.getUint8Data(2) & 0xF );
          marr_valve[valveNumber].ui8_estValveLimitStatus = ( pkg.getUint8Data(3) >> 5);

          setSelectedDataSourceISOName (rcc_tempISOName);
          setUpdateTime( ci32_now );
        }
        else
        { // there is a sender conflict
          IsoAgLib::getILibErrInstance().registerNonFatal( IsoAgLib::iLibErr_c::TracMultipleSender, getMultitonInst() );
        }
        break;
      case AUX_VALVE_0_MEASURED_FLOW:
        valveNumber--;
      case AUX_VALVE_1_MEASURED_FLOW:
        valveNumber--;
      case AUX_VALVE_2_MEASURED_FLOW:
        valveNumber--;
      case AUX_VALVE_3_MEASURED_FLOW:
        valveNumber--;
      case AUX_VALVE_4_MEASURED_FLOW:
        valveNumber--;
      case AUX_VALVE_5_MEASURED_FLOW:
        valveNumber--;
      case AUX_VALVE_6_MEASURED_FLOW:
        valveNumber--;
      case AUX_VALVE_7_MEASURED_FLOW:
        valveNumber--;
      case AUX_VALVE_8_MEASURED_FLOW:
        valveNumber--;
      case AUX_VALVE_9_MEASURED_FLOW:
        valveNumber--;
      case AUX_VALVE_10_MEASURED_FLOW:
        valveNumber--;
      case AUX_VALVE_11_MEASURED_FLOW:
        valveNumber--;
      case AUX_VALVE_12_MEASURED_FLOW:
        valveNumber--;
      case AUX_VALVE_13_MEASURED_FLOW:
        valveNumber--;
      case AUX_VALVE_14_MEASURED_FLOW:
        valveNumber--;
      case AUX_VALVE_15_MEASURED_FLOW:
        if ( checkParseReceived( rcc_tempISOName ) )
        { // sender is allowed to send
          marr_valve[valveNumber].ui8_extendPortMeasuredFlow = pkg.getUint8Data(0);
          marr_valve[valveNumber].ui8_retractPortMeasuredFlow = pkg.getUint8Data(1);
          marr_valve[valveNumber].ui16_extendPortPressure =  ( static_cast<uint16_t>(pkg.getUint8Data(2)) +
                                                             ( static_cast<uint16_t>(pkg.getUint8Data(3)) << 8 ) );
          marr_valve[valveNumber].ui16_retractPortPressure = ( static_cast<uint16_t>(pkg.getUint8Data(4)) +
                                                             ( static_cast<uint16_t>(pkg.getUint8Data(5)) << 8 ) );
          marr_valve[valveNumber].ui8_returnPortPressure = pkg.getUint8Data(6);
          marr_valve[valveNumber].ui8_measuredValveLimitStatus = ( pkg.getUint8Data(7) >> 5 );

          setSelectedDataSourceISOName (rcc_tempISOName);
          setUpdateTime( ci32_now );
        }
        else
        { // there is a sender conflict
Exemplo n.º 7
0
void
IsoMonitor_c::processMsg( const CanPkg_c& arc_data )
{
#if DEBUG_ISOMONITOR
  INTERNAL_DEBUG_DEVICE << INTERNAL_DEBUG_DEVICE_ENDL << "IsoMonitor_c::processMsg()-BEGIN" << INTERNAL_DEBUG_DEVICE_ENDL;
  debugPrintNameTable();
#endif

  CanPkgExt_c pkg( arc_data, getMultitonInst() );

  const IsoName_c cc_dataIsoName (pkg.getDataUnionConst());

  // Special NETWORK-MANAGEMENT Handling of ADDRESS_CLAIM_PGN
  // don't do the generic "valid-resolving" check here!
  if( (pkg.isoPgn() & 0x3FF00LU) == ADDRESS_CLAIM_PGN )
  {
    const int32_t ci32_time = pkg.time();
    const uint8_t cui8_sa = pkg.isoSa();

    IsoItem_c *pc_itemSameISOName = item( cc_dataIsoName );
    if( pc_itemSameISOName != NULL )
    {
      if (pc_itemSameISOName->itemState(IState_c::PreAddressClaim))
        // no need to check here for LostAddress, as it's only about the ISOName,
        // and that's correct in all other cases!
      { // this item is still in PreAddressClaim, so don't consider its
        // ISOName as final, it may be able to adapt it when switching to AddressClaim
        // Note: Only LOCAL Items can be in state PreAddressClaim
        pc_itemSameISOName = NULL;
      }
    }

    IsoItem_c *pc_itemSameSa = item( cui8_sa );
    if( pc_itemSameSa != NULL )
    {
      if (pc_itemSameSa->itemState(IState_c::PreAddressClaim)
       || pc_itemSameSa->itemState(IState_c::AddressLost) )
      { // this item has no valid address, as it's not (anymore) active.
        // so don't consider it as item with the same SA as the received one.
        pc_itemSameSa = NULL;
      }
    }

    /// Receiving REMOTE Address-Claim
    /// ##############################

    if (NULL == pc_itemSameISOName)
    { // We have NO item with this IsoName
      /// Insert this new remote node (new isoname). Just check before if it steals a SA from someone
      if (NULL == pc_itemSameSa)
      { // New remote node took a fresh SA. The way it should be. Insert it to the list.
        insertIsoMember (cc_dataIsoName, cui8_sa, IState_c::ClaimedAddress, NULL, true);
      }
      else
      { // New remote node stole a SA. Check if it stole from local or remote.
        if (pc_itemSameSa->itemState(IState_c::Local))
        { /// New remote node steals SA from Local node!
          // --> change address if it has lower PRIO
          if (pc_itemSameSa->isoName() < cc_dataIsoName)
          { // the LOCAL item has lower PRIO
            if (pc_itemSameSa->itemState(IState_c::AddressClaim))
            { // the LOCAL item was still in AddressClaim (250ms) phase
              pc_itemSameSa->setNr (unifyIsoSa (pc_itemSameSa, true));
              // No need to broadcast anything, we didn't yet even call AddToMonitorList...
              pc_itemSameSa->sendAddressClaim (false); // false: Address-Claim due to SA-change on conflict **while 250ms-phase** , so we can skip the "AddressClaim"-phase!
            }
            else
            { // the LOCAL item is already up and running, so simply change the SA, claim again and go on
              pc_itemSameSa->changeAddressAndBroadcast (unifyIsoSa (pc_itemSameSa, true));
              pc_itemSameSa->sendAddressClaim (true); // true: Address-Claim due to SA-change on conflict **after 250ms-phase**, so we can skip the "AddressClaim"-phase!
            }

            if (pc_itemSameSa->nr() == 254)
            { // Couldn't get a new address -> remove the item and let IdentItem go to OffUnable!
              if (pc_itemSameSa->getIdentItem())
              { // as it should be! as it's local!
                pc_itemSameSa->getIdentItem()->goOffline(false); // false: we couldn't get a new address for this item!
              }
            } else {
              updateSaItemTable( *pc_itemSameSa, true );
            }
            insertIsoMember (cc_dataIsoName, cui8_sa, IState_c::ClaimedAddress, NULL, true);
          }
          else
          { // let local IsoItem_c process the conflicting adr claim
            // --> the IsoItem_c::processMsg() will send an ADR CLAIM to indicate the higher prio
            pc_itemSameSa->processAddressClaimed (ci32_time, cui8_sa);
            insertIsoMember (cc_dataIsoName, 0xFE, IState_c::AddressLost, NULL, true);
            /// ATTENTION: We insert the IsoName WITHOUT a valid Address. (and even notify the registered clients about it!)
            /// But this may also happen anyway if you register your handler at a later time -
            /// then your handler will be called with "AddToMonitorList" for all yet known IsoItems -
            /// and those don't need to have a valid SA at this moment!!
          }
        }
        else
        { /// New remote node steals SA from Remote node!
          pc_itemSameSa->giveUpAddressAndBroadcast();
          insertIsoMember (cc_dataIsoName, cui8_sa, IState_c::ClaimedAddress, NULL, true);
        }
      }
    }
    else
    { // We already have an item with this IsoName
      if (pc_itemSameISOName->itemState(IState_c::Local))
      { // We have a local item with this IsoName
        isoaglib_assert( pc_itemSameISOName->getIdentItem() );
        pc_itemSameISOName->getIdentItem()->goOffline( false ); // false: we couldn't get a new address for this item!
        IsoAgLib::getILibErrInstance().registerNonFatal( IsoAgLib::iLibErr_c::MonitorNameRxConflict, getMultitonInst() );
        // now create a new node for the remote SA claim
        insertIsoMember (cc_dataIsoName, cui8_sa, IState_c::ClaimedAddress, NULL, true);
      }
      else
      { // We have a remote item with this IsoName
        /// Change SA of existing remote node. Just check before if it steals a SA from someone
        if (NULL == pc_itemSameSa)
        { // (A9) Existing remote node took a fresh SA. The way it should be. Just change its address.
          updateSaItemTable( *pc_itemSameISOName, false );
          pc_itemSameISOName->processAddressClaimed (ci32_time, cui8_sa);
          updateSaItemTable( *pc_itemSameISOName, true );
        }
        else
        { // Existing remote node took an already existing SA.
          if (pc_itemSameSa == pc_itemSameISOName)
          { // (A1) Existing remote node reclaimed its SA, so it's just a repeated address-claim.
            pc_itemSameISOName->processAddressClaimed (ci32_time, cui8_sa); // only call to update the timestamp basically
          }
          else if (pc_itemSameSa->itemState(IState_c::Local))
          { // (A5) Existing remote node steals SA from Local node!
            // --> change address if it has lower PRIO
            if (pc_itemSameSa->isoName() < cc_dataIsoName)
            { // the LOCAL item has lower PRIO
              if (pc_itemSameSa->itemState(IState_c::AddressClaim))
              { // the LOCAL item was still in AddressClaim (250ms) phase
                pc_itemSameSa->setNr (unifyIsoSa (pc_itemSameSa, true));
                // No need to broadcast anything, we didn't yet even call AddToMonitorList...
                pc_itemSameSa->sendAddressClaim (false); // false: Address-Claim due to SA-change on conflict **while 250ms-phase** , so we can skip the "AddressClaim"-phase!
              }
              else
              { // the LOCAL item is already up and running, so simply change the SA, claim again and go on
                pc_itemSameSa->changeAddressAndBroadcast (unifyIsoSa (pc_itemSameSa, true));
                pc_itemSameSa->sendAddressClaim (true); // true: Address-Claim due to SA-change on conflict **after 250ms-phase**, so we can skip the "AddressClaim"-phase!
              }

              if (pc_itemSameSa->nr() == 254)
              { // Couldn't get a new address -> remove the item and let IdentItem go to OffUnable!
                if (pc_itemSameSa->getIdentItem())
                { // as it should be! as it's local!
                  pc_itemSameSa->getIdentItem()->goOffline(false); // false: we couldn't get a new address for this item!
                }
              } else {
                /* we could change our SA -> update */
                updateSaItemTable( *pc_itemSameSa, true );
              }
              pc_itemSameISOName->processAddressClaimed (ci32_time, cui8_sa);
              updateSaItemTable( *pc_itemSameISOName, true );
            }
            else
            { // let local IsoItem_c process the conflicting adr claim
              // --> the IsoItem_c::processMsg() will send an ADR CLAIM to indicate the higher prio
              pc_itemSameSa->processAddressClaimed (ci32_time, cui8_sa);
              updateSaItemTable( *pc_itemSameISOName, false ); // update table before item get FE
              pc_itemSameISOName->giveUpAddressAndBroadcast();
            }
          }
          else
          { // (A3) Existing remote node steals other remote node's SA
            pc_itemSameSa->giveUpAddressAndBroadcast();
            pc_itemSameISOName->processAddressClaimed (ci32_time, cui8_sa); // will set the new SA and do broadcasting
            updateSaItemTable( *pc_itemSameISOName, true );
          }
        }
      }
    }
  }
  else
  {
    // for all following modules, we do the "typical" "valid-resolving"-check!
    if( !pkg.isValid() || (pkg.getMonitorItemForSA() == NULL) )
      return;

#ifdef USE_WORKING_SET
    // Handle NON-DESTINATION PGNs
    switch ((pkg.isoPgn() /* & 0x3FFFF */ )) // isoPgn is already "& 0x3FFFF" !
    {
      case WORKING_SET_MASTER_PGN:
        pkg.getMonitorItemForSA()->processMsgWsMaster (uint8_t(pkg.getUint8Data(1-1) - 1), pkg.time() );
      break;

      case WORKING_SET_MEMBER_PGN:
        pkg.getMonitorItemForSA()->processMsgWsMember (cc_dataIsoName, pkg.time());
      break;

      default:
        break;
    } // end switch for NON-DESTINATION pgn
#endif
  }

#if DEBUG_ISOMONITOR
  INTERNAL_DEBUG_DEVICE << "IsoMonitor_c::processMsg()-END" << INTERNAL_DEBUG_DEVICE_ENDL;
  debugPrintNameTable();
#endif
}
Exemplo n.º 8
0
IsoMonitor_c::IsoMonitor_c() :
  SchedulerTask_c( 125, true ),
  mvec_isoMember(),
  mt_handler(*this),
  mt_customer(*this),
  CONTAINER_CLIENT1_CTOR_INITIALIZER_LIST
{
}


void
IsoMonitor_c::init()
{
  isoaglib_assert (!initialized());
  isoaglib_assert (mvec_isoMember.empty());

  mi32_lastSaRequest = -1; // not yet requested. Do NOT use 0, as the first "setLastRequest()" could (and does randomly) occur at time0 as it's called at init() time.
  mc_tempIsoMemberItem.set( 0, IsoName_c::IsoNameUnspecified(), 0xFE, IState_c::Active, getMultitonInst() );

  setPeriod( 125, false );
  getSchedulerInstance().registerTask( *this, 0 );

  CNAMESPACE::memset( &m_isoItems, 0x0, sizeof( m_isoItems ) );

  // add filter REQUEST_PGN_MSG_PGN via IsoRequestPgn_c
  getIsoRequestPgnInstance4Comm().registerPGN (mt_handler, ADDRESS_CLAIM_PGN);
#ifdef USE_WORKING_SET
  getIsoRequestPgnInstance4Comm().registerPGN (mt_handler, WORKING_SET_MASTER_PGN);
  getIsoRequestPgnInstance4Comm().registerPGN (mt_handler, WORKING_SET_MEMBER_PGN);
#endif

  getIsoBusInstance4Comm().insertFilter( mt_customer, IsoAgLib::iMaskFilter_c( 0x3FFFF00UL, ((ADDRESS_CLAIM_PGN)+0xFF)<<8 ), 8 );
#ifdef USE_WORKING_SET
  getIsoBusInstance4Comm().insertFilter( mt_customer, IsoAgLib::iMaskFilter_c( 0x3FFFF00UL, (WORKING_SET_MASTER_PGN<<8) ), 8 );
  getIsoBusInstance4Comm().insertFilter( mt_customer, IsoAgLib::iMaskFilter_c( 0x3FFFF00UL, (WORKING_SET_MEMBER_PGN<<8) ), 8 );
#endif

  setInitialized();
}