1 /*
2  * Copyright (C) 2019 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 #pragma once
18 
19 #include "CanSocket.h"
20 
21 #include <android-base/unique_fd.h>
22 #include <android/hardware/automotive/can/1.0/ICanBus.h>
23 #include <android/hardware/automotive/can/1.0/ICanController.h>
24 #include <utils/Mutex.h>
25 
26 #include <atomic>
27 #include <mutex>
28 #include <thread>
29 
30 namespace android::hardware::automotive::can::V1_0::implementation {
31 
32 struct CanBus : public ICanBus {
33     using ErrorCallback = std::function<void()>;
34 
35     virtual ~CanBus();
36 
37     Return<Result> send(const CanMessage& message) override;
38     Return<void> listen(const hidl_vec<CanMessageFilter>& filter,
39                         const sp<ICanMessageListener>& listener, listen_cb _hidl_cb) override;
40     Return<sp<ICloseHandle>> listenForErrors(const sp<ICanErrorListener>& listener) override;
41 
42     void setErrorCallback(ErrorCallback errcb);
43     ICanController::Result up();
44     bool down();
45 
46   protected:
47     /**
48      * Blank constructor, since some interface types (such as SLCAN) don't get a name until after
49      * being initialized.
50      *
51      * If using this constructor, you MUST initialize mIfname prior to the completion of preUp().
52      */
53     CanBus();
54 
55     CanBus(const std::string& ifname);
56 
57     /**
58      * Prepare the SocketCAN interface.
59      *
60      * After calling this method, mIfname network interface is available and ready to be brought up.
61      *
62      * \return OK on success, or an error state on failure. See ICanController::Result
63      */
64     virtual ICanController::Result preUp();
65 
66     /**
67      * Cleanup after bringing the interface down.
68      *
69      * This is a counterpart to preUp().
70      *
71      * \return true upon success and false upon failure
72      */
73     virtual bool postDown();
74 
75     /** Network interface name. */
76     std::string mIfname;
77 
78   private:
79     struct CanMessageListener {
80         sp<ICanMessageListener> callback;
81         hidl_vec<CanMessageFilter> filter;
82         wp<ICloseHandle> closeHandle;
83         bool failedOnce = false;
84     };
85     void clearMsgListeners();
86     void clearErrListeners();
87 
88     void notifyErrorListeners(ErrorEvent err, bool isFatal);
89 
90     void onRead(const struct canfd_frame& frame, std::chrono::nanoseconds timestamp);
91     void onError(int errnoVal);
92 
93     std::mutex mMsgListenersGuard;
94     std::vector<CanMessageListener> mMsgListeners GUARDED_BY(mMsgListenersGuard);
95 
96     std::mutex mErrListenersGuard;
97     std::vector<sp<ICanErrorListener>> mErrListeners GUARDED_BY(mErrListenersGuard);
98 
99     std::unique_ptr<CanSocket> mSocket;
100     bool mDownAfterUse;
101 
102     /**
103      * Guard for up flag is required to be held for entire time when the interface is being used
104      * (i.e. message being sent), because we don't want the interface to be torn down while
105      * executing that operation.
106      */
107     std::mutex mIsUpGuard;
108     bool mIsUp GUARDED_BY(mIsUpGuard) = false;
109 
110     ErrorCallback mErrCb;
111 };
112 
113 }  // namespace android::hardware::automotive::can::V1_0::implementation
114