Thread: fill in ticks in active timestamp
This commit fills in the ticks of active timestamp of randomly generated dataset as defined in Thread spec. Bug: 347838683 Change-Id: I5d8ba3ca7728e1890996fdd64198f7bc90bfb1fa
This commit is contained in:
parent
4c701fbfa0
commit
e2ab96f3c7
4 changed files with 87 additions and 4 deletions
|
|
@ -65,11 +65,32 @@ public final class OperationalDatasetTimestamp {
|
|||
*/
|
||||
@NonNull
|
||||
public static OperationalDatasetTimestamp fromInstant(@NonNull Instant instant) {
|
||||
return OperationalDatasetTimestamp.fromInstant(instant, true /* isAuthoritativeSource */);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link OperationalDatasetTimestamp} object from an {@link Instant}.
|
||||
*
|
||||
* <p>The {@code seconds} is set to {@code instant.getEpochSecond()}, {@code ticks} is set to
|
||||
* {@link instant#getNano()} based on frequency of 32768 Hz, and {@code isAuthoritativeSource}
|
||||
* is set to {@code isAuthoritativeSource}.
|
||||
*
|
||||
* <p>Note that this conversion can lose precision and a value returned by {@link #toInstant}
|
||||
* may not equal exactly the {@code instant}.
|
||||
*
|
||||
* @throws IllegalArgumentException if {@code instant.getEpochSecond()} is larger than {@code
|
||||
* 0xffffffffffffL}
|
||||
* @see toInstant
|
||||
* @hide
|
||||
*/
|
||||
@NonNull
|
||||
public static OperationalDatasetTimestamp fromInstant(
|
||||
@NonNull Instant instant, boolean isAuthoritativeSource) {
|
||||
int ticks = getRoundedTicks(instant.getNano());
|
||||
long seconds = instant.getEpochSecond() + ticks / TICKS_UPPER_BOUND;
|
||||
// the rounded ticks can be 0x8000 if instant.getNano() >= 999984742
|
||||
ticks = ticks % TICKS_UPPER_BOUND;
|
||||
return new OperationalDatasetTimestamp(seconds, ticks, true /* isAuthoritativeSource */);
|
||||
return new OperationalDatasetTimestamp(seconds, ticks, isAuthoritativeSource);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -884,9 +884,7 @@ final class ThreadNetworkControllerService extends IThreadNetworkController.Stub
|
|||
final byte[] securityFlags = new byte[] {(byte) 0xff, (byte) 0xf8};
|
||||
|
||||
return new ActiveOperationalDataset.Builder()
|
||||
.setActiveTimestamp(
|
||||
new OperationalDatasetTimestamp(
|
||||
now.getEpochSecond() & 0xffffffffffffL, 0, authoritative))
|
||||
.setActiveTimestamp(OperationalDatasetTimestamp.fromInstant(now, authoritative))
|
||||
.setExtendedPanId(newRandomBytes(random, LENGTH_EXTENDED_PAN_ID))
|
||||
.setPanId(panId)
|
||||
.setNetworkName(networkName)
|
||||
|
|
|
|||
|
|
@ -40,6 +40,19 @@ public final class OperationalDatasetTimestampTest {
|
|||
() -> OperationalDatasetTimestamp.fromTlvValue(new byte[7]));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void fromInstant_authoritativeIsSetAsSpecified() {
|
||||
Instant instant = Instant.now();
|
||||
|
||||
OperationalDatasetTimestamp timestampAuthoritativeFalse =
|
||||
OperationalDatasetTimestamp.fromInstant(instant, false);
|
||||
OperationalDatasetTimestamp timestampAuthoritativeTrue =
|
||||
OperationalDatasetTimestamp.fromInstant(instant, true);
|
||||
|
||||
assertThat(timestampAuthoritativeFalse.isAuthoritativeSource()).isEqualTo(false);
|
||||
assertThat(timestampAuthoritativeTrue.isAuthoritativeSource()).isEqualTo(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void fromTlvValue_goodValue_success() {
|
||||
OperationalDatasetTimestamp timestamp =
|
||||
|
|
|
|||
|
|
@ -98,6 +98,8 @@ import org.mockito.MockitoSession;
|
|||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.Clock;
|
||||
import java.time.DateTimeException;
|
||||
import java.time.Instant;
|
||||
import java.time.ZoneId;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
|
@ -584,6 +586,55 @@ public final class ThreadNetworkControllerServiceTest {
|
|||
assertThat(activeDataset.getActiveTimestamp().isAuthoritativeSource()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createRandomizedDataset_zeroNanoseconds_returnsZeroTicks() throws Exception {
|
||||
Instant now = Instant.ofEpochSecond(0, 0);
|
||||
Clock clock = Clock.fixed(now, ZoneId.systemDefault());
|
||||
MockitoSession session =
|
||||
ExtendedMockito.mockitoSession().mockStatic(SystemClock.class).startMocking();
|
||||
final IActiveOperationalDatasetReceiver mockReceiver =
|
||||
ExtendedMockito.mock(IActiveOperationalDatasetReceiver.class);
|
||||
|
||||
try {
|
||||
ExtendedMockito.when(SystemClock.currentNetworkTimeClock()).thenReturn(clock);
|
||||
mService.createRandomizedDataset(DEFAULT_NETWORK_NAME, mockReceiver);
|
||||
mTestLooper.dispatchAll();
|
||||
} finally {
|
||||
session.finishMocking();
|
||||
}
|
||||
|
||||
verify(mockReceiver, never()).onError(anyInt(), anyString());
|
||||
verify(mockReceiver, times(1)).onSuccess(mActiveDatasetCaptor.capture());
|
||||
ActiveOperationalDataset activeDataset = mActiveDatasetCaptor.getValue();
|
||||
assertThat(activeDataset.getActiveTimestamp().getTicks()).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createRandomizedDataset_maxNanoseconds_returnsMaxTicks() throws Exception {
|
||||
// The nanoseconds to ticks conversion is rounded in the current implementation.
|
||||
// 32767.5 / 32768 * 1000000000 = 999984741.2109375, using 999984741 to
|
||||
// produce the maximum ticks.
|
||||
Instant now = Instant.ofEpochSecond(0, 999984741);
|
||||
Clock clock = Clock.fixed(now, ZoneId.systemDefault());
|
||||
MockitoSession session =
|
||||
ExtendedMockito.mockitoSession().mockStatic(SystemClock.class).startMocking();
|
||||
final IActiveOperationalDatasetReceiver mockReceiver =
|
||||
ExtendedMockito.mock(IActiveOperationalDatasetReceiver.class);
|
||||
|
||||
try {
|
||||
ExtendedMockito.when(SystemClock.currentNetworkTimeClock()).thenReturn(clock);
|
||||
mService.createRandomizedDataset(DEFAULT_NETWORK_NAME, mockReceiver);
|
||||
mTestLooper.dispatchAll();
|
||||
} finally {
|
||||
session.finishMocking();
|
||||
}
|
||||
|
||||
verify(mockReceiver, never()).onError(anyInt(), anyString());
|
||||
verify(mockReceiver, times(1)).onSuccess(mActiveDatasetCaptor.capture());
|
||||
ActiveOperationalDataset activeDataset = mActiveDatasetCaptor.getValue();
|
||||
assertThat(activeDataset.getActiveTimestamp().getTicks()).isEqualTo(32767);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createRandomizedDataset_hasNetworkTimeClock_datasetActiveTimestampIsAuthoritative()
|
||||
throws Exception {
|
||||
|
|
|
|||
Loading…
Reference in a new issue