Boolean doInit(RunTimeOpts *rtOpts, PtpClock *ptpClock)
{
  DBG("manufacturerIdentity: %s\n", MANUFACTURER_ID);

  /* initialize networking */
  netShutdown(&ptpClock->netPath);
  if(!netInit(&ptpClock->netPath, rtOpts, ptpClock))
  {
    ERROR("failed to initialize network\n");
    toState(PTP_FAULTY, rtOpts, ptpClock);
    return FALSE;
  }

  /* initialize other stuff */
  initData(rtOpts, ptpClock);
  initTimer();
  initClock(rtOpts, ptpClock);
  m1(ptpClock);
  msgPackHeader(ptpClock->msgObuf, ptpClock);

  DBG("sync message interval: %d\n", PTP_SYNC_INTERVAL_TIMEOUT(ptpClock->sync_interval));
  DBG("clock identifier: %s\n", ptpClock->clock_identifier);
  DBG("256*log2(clock variance): %d\n", ptpClock->clock_variance);
  DBG("clock stratum: %d\n", ptpClock->clock_stratum);
  DBG("clock preferred?: %s\n", ptpClock->preferred?"yes":"no");
  DBG("bound interface name: %s\n", rtOpts->ifaceName);
  DBG("communication technology: %d\n", ptpClock->port_communication_technology);
  DBG("uuid: %02x:%02x:%02x:%02x:%02x:%02x\n",
    ptpClock->port_uuid_field[0], ptpClock->port_uuid_field[1], ptpClock->port_uuid_field[2],
    ptpClock->port_uuid_field[3], ptpClock->port_uuid_field[4], ptpClock->port_uuid_field[5]);
  DBG("PTP subdomain name: %s\n", ptpClock->subdomain_name);
  DBG("subdomain address: %x.%x.%x.%x\n",
    ptpClock->subdomain_address[0], ptpClock->subdomain_address[1],
    ptpClock->subdomain_address[2], ptpClock->subdomain_address[3]);
  DBG("event port address: %x %x\n",
    ptpClock->event_port_address[0], ptpClock->event_port_address[1]);
  DBG("general port address: %x %x\n",
    ptpClock->general_port_address[0], ptpClock->general_port_address[1]);

  toState(PTP_LISTENING, rtOpts, ptpClock);
  return TRUE;
}
Example #2
0
void probe(PtpClock *ptpClock)
{
  UInteger16 i;
  UInteger16 length;
  TimeInternal interval, now, finish;
  
  /* check */
  if(ptpClock->runTimeOpts.probe_management_key == PTP_MM_UPDATE_DEFAULT_DATA_SET
    || ptpClock->runTimeOpts.probe_management_key == PTP_MM_UPDATE_GLOBAL_TIME_PROPERTIES
    || ptpClock->runTimeOpts.probe_management_key == PTP_MM_SET_SYNC_INTERVAL)
  {
    ERROR("send not supported for that management message\n");
    return;
  }
  
  /* init */
  if(!netInit(ptpClock))
  {
    ERROR("failed to initialize network\n");
    return;
  }
  
  initData(ptpClock);
  msgPackHeader(ptpClock->msgObuf, ptpClock);
  
  memset(&ptpClock->msgTmp.manage, 0, sizeof(MsgManagement));
  ptpClock->msgTmp.manage.targetCommunicationTechnology = PTP_DEFAULT;
  
  /* send */
  for(i = 0; i < KEY_ARRAY_LEN; ++i)
  {
    if(ptpClock->runTimeOpts.probe_management_key > 0)
    {
      ptpClock->msgTmp.manage.managementMessageKey = ptpClock->runTimeOpts.probe_management_key;
      ptpClock->msgTmp.manage.recordKey = ptpClock->runTimeOpts.probe_record_key;
    }
    else
      ptpClock->msgTmp.manage.managementMessageKey = management_key_array[i];
    
    if(!(length = msgPackManagement(ptpClock->msgObuf, &ptpClock->msgTmp.manage, ptpClock)))
    {
      ERROR("failed to pack management message\n");
      return;
    }
    
    printf("\n(sending managementMessageKey %hhu)\n", ptpClock->msgTmp.manage.managementMessageKey); 
    
    if(!netSendGeneral(ptpClock->msgObuf, length, ptpClock))
    {
      ERROR("failed to send message\n");
      return;
    }
    
    if(ptpClock->runTimeOpts.probe_management_key > 0)
      break;
  }
  
  timerNow(&finish);
  finish.seconds += PTP_SYNC_INTERVAL_TIMEOUT(ptpClock->sync_interval);
  for(;;)
  {
    interval.seconds = PTP_SYNC_INTERVAL_TIMEOUT(ptpClock->sync_interval);
    interval.nanoseconds = 0;
    netSelect(&interval, ptpClock);
    
    netRecvEvent(ptpClock->msgIbuf, NULL, ptpClock);
    
    if(netRecvGeneral(ptpClock->msgIbuf, ptpClock))
    {
      msgUnpackHeader(ptpClock->msgIbuf, &ptpClock->msgTmpHeader);
      
      if(ptpClock->msgTmpHeader.control == PTP_MANAGEMENT_MESSAGE)
      {
        msgUnpackManagement(ptpClock->msgIbuf, &ptpClock->msgTmp.manage);
        msgUnpackManagementPayload(ptpClock->msgIbuf, &ptpClock->msgTmp.manage);
        
        displayManagement(&ptpClock->msgTmpHeader, &ptpClock->msgTmp.manage);
      }
      
      fflush(stdout);
    }
    
    timerNow(&now);
    if( now.seconds > finish.seconds || (now.seconds == finish.seconds
      && now.nanoseconds > finish.nanoseconds) )
      break;
  }
  
  /* done */
  printf("\n");
  ptpdShutdown();
  
  exit(0);
}
Example #3
0
Boolean doInit(PtpClock *ptpClock)
{
  DBG("manufacturerIdentity: %s\n", MANUFACTURER_ID);
  
  /* initialize networking */
  netShutdown(ptpClock);
  if(!netInit(ptpClock))
  {
    ERROR("failed to initialize network\n");
    toState(PTP_FAULTY, ptpClock);
    return FALSE;
  }

  /* initialize timing, may fail e.g. if timer depends on hardware */
  if(!initTime(ptpClock))
  {
    ERROR("failed to initialize timing\n");
    toState(PTP_FAULTY, ptpClock);
    return FALSE;
  }

  switch (ptpClock->runTimeOpts.time) {
  case TIME_SYSTEM:
  case TIME_SYSTEM_LINUX_HW:
  case TIME_SYSTEM_LINUX_SW:
      /*
       * send time stamp will be returned to socket when available,
       * either via IP_MULTICAST_LOOP or SIOCSHWTSTAMP + error queue
       */
      ptpClock->delayedTiming = FALSE;
      break;
  default:
      /* ask for time stamp shortly after sending */
      ptpClock->delayedTiming = TRUE;
      break;
  }

  /* initialize other stuff */
  initData(ptpClock);
  initTimer();
  initClock(ptpClock);
  m1(ptpClock);
  msgPackHeader(ptpClock->msgObuf, ptpClock);
  
  DBG("sync message interval: %d\n", PTP_SYNC_INTERVAL_TIMEOUT(ptpClock->sync_interval));
  DBG("clock identifier: %s\n", ptpClock->clock_identifier);
  DBG("256*log2(clock variance): %d\n", ptpClock->clock_variance);
  DBG("clock stratum: %d\n", ptpClock->clock_stratum);
  DBG("clock preferred?: %s\n", ptpClock->preferred?"yes":"no");
  DBG("bound interface name: %s\n", ptpClock->runTimeOpts.ifaceName);
  DBG("communication technology: %d\n", ptpClock->port_communication_technology);
  DBG("uuid: %02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx\n",
    ptpClock->port_uuid_field[0], ptpClock->port_uuid_field[1], ptpClock->port_uuid_field[2],
    ptpClock->port_uuid_field[3], ptpClock->port_uuid_field[4], ptpClock->port_uuid_field[5]);
  DBG("PTP subdomain name: %s\n", ptpClock->subdomain_name);
  DBG("subdomain address: %hhx.%hhx.%hhx.%hhx\n",
    ptpClock->subdomain_address[0], ptpClock->subdomain_address[1],
    ptpClock->subdomain_address[2], ptpClock->subdomain_address[3]);
  DBG("event port address: %hhx %hhx\n",
    ptpClock->event_port_address[0], ptpClock->event_port_address[1]);
  DBG("general port address: %hhx %hhx\n",
    ptpClock->general_port_address[0], ptpClock->general_port_address[1]);
  
  toState(PTP_LISTENING, ptpClock);
  return TRUE;
}
Example #4
0
/* perform actions required when leaving 'port_state' and entering 'state' */
void toState(UInteger8 state, PtpClock *ptpClock)
{
  ptpClock->message_activity = TRUE;

  /* leaving state tasks */
  switch(ptpClock->port_state)
  {
  case PTP_MASTER:
    timerStop(SYNC_INTERVAL_TIMER, ptpClock->itimer);
    timerStart(SYNC_RECEIPT_TIMER, PTP_SYNC_RECEIPT_TIMEOUT(ptpClock->sync_interval), ptpClock->itimer);
    break;
    
  case PTP_SLAVE:
    initClock(ptpClock);
    break;
    
  default:
    break;
  }

  timeToState(state, ptpClock);
  
  /* entering state tasks */
  switch(state)
  {
  case PTP_INITIALIZING:
    DBG("state PTP_INITIALIZING\n");
    timerStop(SYNC_RECEIPT_TIMER, ptpClock->itimer);
    
    ptpClock->port_state = PTP_INITIALIZING;
    break;
    
  case PTP_FAULTY:
    DBG("state PTP_FAULTY\n");
    timerStop(SYNC_RECEIPT_TIMER, ptpClock->itimer);
    
    ptpClock->port_state = PTP_FAULTY;
    break;
    
  case PTP_DISABLED:
    DBG("state change to PTP_DISABLED\n");
    timerStop(SYNC_RECEIPT_TIMER, ptpClock->itimer);
    
    ptpClock->port_state = PTP_DISABLED;
    break;
    
  case PTP_LISTENING:
    DBG("state PTP_LISTENING\n");
    
    timerStart(SYNC_RECEIPT_TIMER, PTP_SYNC_RECEIPT_TIMEOUT(ptpClock->sync_interval), ptpClock->itimer);
    
    ptpClock->port_state = PTP_LISTENING;
    break;
    
  case PTP_MASTER:
    DBG("state PTP_MASTER\n");
    
    if(ptpClock->port_state != PTP_PRE_MASTER)
      timerStart(SYNC_INTERVAL_TIMER, PTP_SYNC_INTERVAL_TIMEOUT(ptpClock->sync_interval), ptpClock->itimer);
    
    timerStop(SYNC_RECEIPT_TIMER, ptpClock->itimer);
    
    ptpClock->port_state = PTP_MASTER;
    break;
    
  case PTP_PASSIVE:
    DBG("state PTP_PASSIVE\n");
    ptpClock->port_state = PTP_PASSIVE;
    break;
    
  case PTP_UNCALIBRATED:
    DBG("state PTP_UNCALIBRATED\n");
    ptpClock->port_state = PTP_UNCALIBRATED;
    break;
    
  case PTP_SLAVE:
    DBG("state PTP_PTP_SLAVE\n");
    
    initClock(ptpClock);
    
    /* R is chosen to allow a few syncs before we first get a one-way delay estimate */
    /* this is to allow the offset filter to fill for an accurate initial clock reset */
    ptpClock->Q = 0;
    ptpClock->R = getRand(&ptpClock->random_seed)%4 + 4;
    DBG("Q = %d, R = %d\n", ptpClock->Q, ptpClock->R);
    
    ptpClock->waitingForFollow = FALSE;
    ptpClock->delay_req_send_time.seconds = 0;
    ptpClock->delay_req_send_time.nanoseconds = 0;
    ptpClock->delay_req_receive_time.seconds = 0;
    ptpClock->delay_req_receive_time.nanoseconds = 0;
    
    timerStart(SYNC_RECEIPT_TIMER, PTP_SYNC_RECEIPT_TIMEOUT(ptpClock->sync_interval), ptpClock->itimer);
    
    ptpClock->port_state = PTP_SLAVE;
    break;
    
  default:
    DBG("to unrecognized state\n");
    break;
  }
  
  if(ptpClock->runTimeOpts.displayStats)
    displayStats(ptpClock);
}