1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <libprotocan/MessageCounter.h>
18 
19 #include <android-base/logging.h>
20 
21 namespace android::hardware::automotive::protocan {
22 
23 /** Whether to log counter state messages. */
24 static constexpr bool kSuperVerbose = false;
25 
MessageCounter(Signal signal)26 MessageCounter::MessageCounter(Signal signal) : upperBound(signal.maxValue + 1), mSignal(signal) {}
27 
next() const28 Signal::value MessageCounter::next() const {
29   CHECK(mCurrent.has_value()) << "Counter not initialized. Did you call isReady?";
30   return (*mCurrent + 1) % upperBound;
31 }
32 
read(const can::V1_0::CanMessage & msg)33 void MessageCounter::read(const can::V1_0::CanMessage& msg) {
34     auto val = mSignal.get(msg);
35 
36     if (!mCurrent.has_value()) {
37         LOG(VERBOSE) << "Got first counter val of " << val;
38         mCurrent = val;
39         return;
40     }
41 
42     auto nextVal = next();
43     if (nextVal == val) {
44         if constexpr (kSuperVerbose) {
45             LOG(VERBOSE) << "Got next counter val of " << nextVal;
46         }
47         mCurrent = nextVal;
48     } else {
49         LOG(DEBUG) << "Ignoring next counter val of " << val << ", waiting for " << nextVal;
50     }
51 }
52 
isReady() const53 bool MessageCounter::isReady() const { return mCurrent.has_value(); }
54 
increment(can::V1_0::CanMessage & msg)55 void MessageCounter::increment(can::V1_0::CanMessage& msg) {
56   auto newVal = next();
57   mCurrent = newVal;
58   mSignal.set(msg, newVal);
59 }
60 
61 }  // namespace android::hardware::automotive::protocan
62