1 /* 2 * Copyright 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 "cache.h" 20 #include "frame.h" 21 #include "frame_id.h" 22 #include "macaddress.h" 23 #include "netlink_socket.h" 24 #include "result.h" 25 26 #include <chrono> 27 #include <functional> 28 #include <memory> 29 #include <queue> 30 31 struct MacAddress; 32 33 class LocalConnection { 34 public: 35 using OnFrameCallback = std::function<void (std::unique_ptr<Frame>)>; 36 using OnAckCallback = std::function<void (FrameInfo&)>; 37 using OnErrorCallback = OnAckCallback; 38 39 LocalConnection(OnFrameCallback onFrameCallback, 40 OnAckCallback onAckCallback, 41 OnErrorCallback onErrorCallback); 42 Result init(std::chrono::steady_clock::time_point now); 43 44 int getFd() const; 45 bool receive(); 46 uint32_t cloneFrame(const Frame& frame, const MacAddress& destination); 47 uint32_t transferFrame(std::unique_ptr<Frame> frame, 48 const MacAddress& destination); 49 bool ackFrame(FrameInfo& info, bool success); 50 51 std::chrono::steady_clock::time_point getTimeout() const; 52 void onTimeout(std::chrono::steady_clock::time_point now); 53 54 private: 55 using Timestamp = std::chrono::steady_clock::time_point; 56 57 Result registerReceiver(); 58 static int staticOnMessage(struct nl_msg* msg, void* context); 59 static int staticOnAck(struct nl_msg* msg, void* context); 60 static int staticOnError(struct sockaddr_nl* addr, 61 struct nlmsgerr* error, 62 void* context); 63 int onMessage(struct nl_msg* msg); 64 int onFrame(struct nl_msg* msg); 65 std::unique_ptr<Frame> parseFrame(struct nlmsghdr* hdr); 66 67 int onAck(struct nl_msg* msg); 68 int onError(struct sockaddr_nl* addr, struct nlmsgerr* error); 69 bool sendFrameOnNetlink(const Frame& frame, const MacAddress& dest); 70 71 OnFrameCallback mOnFrameCallback; 72 OnAckCallback mOnAckCallback; 73 OnErrorCallback mOnErrorCallback; 74 75 NetlinkSocket mNetlinkSocket; 76 int mNetlinkFamily = -1; 77 78 // [cookie,transmitter] -> frame. 79 Cache<FrameId, std::unique_ptr<Frame>> mPendingFrames; 80 // sequence number -> [cookie,transmitter] 81 Cache<uint32_t, FrameId> mSequenceNumberCookies; 82 83 Timestamp mLastCacheTimeUpdate; 84 Timestamp mLastCacheExpiration; 85 86 // A queue (using an ordered map) with the next timeout mapping to the 87 // cookie and transmitter of the frame to retry. This way we can easily 88 // determine when the next deadline is by looking at the first entry and we 89 // can quickly determine which frames to retry by starting at the beginning. 90 std::priority_queue<std::pair<Timestamp, FrameId>> mRetryQueue; 91 }; 92 93