• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2025 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 <condition_variable>
20 #include <deque>
21 #include <functional>
22 #include <future>
23 #include <mutex>
24 #include <optional>
25 #include <string_view>
26 #include <thread>
27 #include <variant>
28 #include <vector>
29 
30 #include <android-base/unique_fd.h>
31 
32 #include "AtResponse.h"
33 
34 namespace aidl {
35 namespace android {
36 namespace hardware {
37 namespace radio {
38 namespace implementation {
39 using ::android::base::unique_fd;
40 
41 struct AtChannel {
42     using HostChannelFactory = std::function<unique_fd()>;
43 
44     struct RequestPipe {
RequestPipeAtChannel::RequestPipe45         explicit RequestPipe(int fd) : mFd(fd) {}
46 
47         bool operator()(std::string_view request) const;
48 
49         RequestPipe(const RequestPipe&) = default;
50         RequestPipe& operator=(const RequestPipe&) = default;
51 
52     private:
53         int mFd;
54     };
55 
56     struct Conversation {
57         using FilterFunc = std::function<bool(const AtResponse&)>;
58         using Duration = std::chrono::steady_clock::duration;
59 
60         AtResponsePtr operator()(RequestPipe, std::string_view request,
61                                  const FilterFunc& filter, Duration timeout);
62         AtResponsePtr operator()(RequestPipe, std::string_view request,
63                                  const FilterFunc& filter);
64 
65         bool send(const AtResponsePtr& response);
66 
67     private:
68         const FilterFunc* mFilter = nullptr;
69         std::promise<AtResponsePtr> mSink;
70         mutable std::mutex mMtx;
71     };
72 
73     using InitSequence = std::function<bool(RequestPipe, Conversation&)>;
74     using Requester = std::function<bool(RequestPipe)>;
75     using ResponseSink = std::function<bool(const AtResponsePtr&)>;
76 
77     AtChannel(HostChannelFactory hostChannelFactory,
78               InitSequence initSequence);
79     ~AtChannel();
80 
81     void queueRequester(Requester);
82     void addResponseSink(ResponseSink);
83 
84 private:
85     void requestLoop();
86     void readingLoop(int fd);
87     Requester getRequester();
88     void broadcastResponse(const AtResponsePtr&);
89 
90     RequestPipe getHostChannelPipe();
91     bool receiveResponses(int hostChannel, std::vector<char>* unconsumed);
92     bool receiveResponsesImpl(const char* begin, const char* end,
93                               std::vector<char>* unconsumed);
94     const char* receiveOneResponse(const char* begin, const char* end);
95 
96     const HostChannelFactory mHostChannelFactory;
97     const InitSequence mInitSequence;
98     Conversation mConversation;
99     unique_fd mHostChannel;
100     std::deque<Requester> mRequesterQueue;
101     std::condition_variable mRequesterAvailable;
102     std::vector<ResponseSink> mResponseSinks;
103     std::vector<char> mResponseBuf;
104     std::thread mRequestThread;
105     std::thread mReaderThread;
106     mutable std::mutex mRequestQueueMtx;
107     mutable std::mutex mResponseSinksMtx;
108 };
109 
110 }  // namespace implementation
111 }  // namespace radio
112 }  // namespace hardware
113 }  // namespace android
114 }  // namespace aidl
115