/* * Copyright 2019, The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include "cache.h" #include "frame.h" #include "frame_id.h" #include "macaddress.h" #include "netlink_socket.h" #include "result.h" #include #include #include #include struct MacAddress; class LocalConnection { public: using OnFrameCallback = std::function)>; using OnAckCallback = std::function; using OnErrorCallback = OnAckCallback; LocalConnection(OnFrameCallback onFrameCallback, OnAckCallback onAckCallback, OnErrorCallback onErrorCallback); Result init(std::chrono::steady_clock::time_point now); int getFd() const; bool receive(); uint32_t cloneFrame(const Frame& frame, const MacAddress& destination); uint32_t transferFrame(std::unique_ptr frame, const MacAddress& destination); bool ackFrame(FrameInfo& info, bool success); std::chrono::steady_clock::time_point getTimeout() const; void onTimeout(std::chrono::steady_clock::time_point now); private: using Timestamp = std::chrono::steady_clock::time_point; Result registerReceiver(); static int staticOnMessage(struct nl_msg* msg, void* context); static int staticOnAck(struct nl_msg* msg, void* context); static int staticOnError(struct sockaddr_nl* addr, struct nlmsgerr* error, void* context); int onMessage(struct nl_msg* msg); int onFrame(struct nl_msg* msg); std::unique_ptr parseFrame(struct nlmsghdr* hdr); int onAck(struct nl_msg* msg); int onError(struct sockaddr_nl* addr, struct nlmsgerr* error); bool sendFrameOnNetlink(const Frame& frame, const MacAddress& dest); OnFrameCallback mOnFrameCallback; OnAckCallback mOnAckCallback; OnErrorCallback mOnErrorCallback; NetlinkSocket mNetlinkSocket; int mNetlinkFamily = -1; // [cookie,transmitter] -> frame. Cache> mPendingFrames; // sequence number -> [cookie,transmitter] Cache mSequenceNumberCookies; Timestamp mLastCacheTimeUpdate; Timestamp mLastCacheExpiration; // A queue (using an ordered map) with the next timeout mapping to the // cookie and transmitter of the frame to retry. This way we can easily // determine when the next deadline is by looking at the first entry and we // can quickly determine which frames to retry by starting at the beginning. std::priority_queue> mRetryQueue; };