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 #pragma once
16 
17 #include <cinttypes>
18 
19 #include <functional>
20 #include <map>
21 #include <memory>
22 #include <utility>
23 
24 #include "common/libs/fs/shared_fd.h"
25 #include "host/libs/audio_connector/buffers.h"
26 #include "host/libs/audio_connector/commands.h"
27 #include "host/libs/audio_connector/shm_layout.h"
28 
29 namespace cuttlefish {
30 
31 // Callbacks into objects implementing this interface will be made from the same
32 // thread that handles the connection fd. Implementations should make every
33 // effort to return immediately to avoid blocking the server's main loop.
34 class AudioServerExecutor {
35  public:
36   virtual ~AudioServerExecutor() = default;
37 
38   // Implementations must ensure each command is replied to before returning
39   // from these functions. Failure to do so causes the program to abort.
40   virtual void StreamsInfo(StreamInfoCommand& cmd) = 0;
41   virtual void SetStreamParameters(StreamSetParamsCommand& cmd) = 0;
42   virtual void PrepareStream(StreamControlCommand& cmd) = 0;
43   virtual void ReleaseStream(StreamControlCommand& cmd) = 0;
44   virtual void StartStream(StreamControlCommand& cmd) = 0;
45   virtual void StopStream(StreamControlCommand& cmd) = 0;
46   virtual void ChmapsInfo(ChmapInfoCommand& cmd) = 0;
47   virtual void JacksInfo(JackInfoCommand& cmd) = 0;
48 
49   // Implementations must call buffer.SendStatus() before destroying the buffer
50   // to notify the other side of the release of the buffer. Failure to do so
51   // will cause the program to abort.
52   virtual void OnPlaybackBuffer(TxBuffer buffer) = 0;
53   virtual void OnCaptureBuffer(RxBuffer buffer) = 0;
54 };
55 
56 class AudioClientConnection {
57  public:
58   static std::unique_ptr<AudioClientConnection> Create(
59       SharedFD client_socket, uint32_t num_streams, uint32_t num_jacks,
60       uint32_t num_chmaps, size_t tx_shm_len, size_t rx_shm_len);
61 
62   AudioClientConnection() = delete;
63   AudioClientConnection(const AudioClientConnection&) = delete;
64 
65   AudioClientConnection& operator=(const AudioClientConnection&) = delete;
66 
67   // Allows the caller to react to commands sent by the client.
68   bool ReceiveCommands(AudioServerExecutor& executor);
69   // Allows the caller to react to IO buffers sent by the client.
70   bool ReceivePlayback(AudioServerExecutor& executor);
71   bool ReceiveCapture(AudioServerExecutor& executor);
72 
73   bool SendEvent(/*TODO*/);
74 
75  private:
AudioClientConnection(ScopedMMap tx_shm,ScopedMMap rx_shm,SharedFD control_socket,SharedFD event_socket,SharedFD tx_socket,SharedFD rx_socket)76   AudioClientConnection(ScopedMMap tx_shm, ScopedMMap rx_shm,
77                         SharedFD control_socket, SharedFD event_socket,
78                         SharedFD tx_socket, SharedFD rx_socket)
79       : tx_shm_(std::move(tx_shm)),
80         rx_shm_(std::move(rx_shm)),
81         control_socket_(control_socket),
82         event_socket_(event_socket),
83         tx_socket_(tx_socket),
84         rx_socket_(rx_socket) {}
85 
86   bool CmdReply(AudioStatus status, const void* data = nullptr,
87                 size_t size = 0);
88   bool WithCommand(const virtio_snd_hdr* msg, size_t msg_len,
89                    AudioServerExecutor& executor);
90 
91   ssize_t ReceiveMsg(SharedFD socket, void* buffer, size_t size);
92 
93   ScopedMMap tx_shm_;
94   ScopedMMap rx_shm_;
95   SharedFD control_socket_;
96   SharedFD event_socket_;
97   SharedFD tx_socket_;
98   SharedFD rx_socket_;
99   // Hold the number of frames since START and when to log it for each stream.
100   std::map<uint32_t, std::pair<uint64_t, uint64_t>> frame_counters_;
101 };
102 
103 class AudioServer {
104  public:
AudioServer(SharedFD server_socket)105   AudioServer(SharedFD server_socket) : server_socket_(server_socket) {}
106 
107   std::unique_ptr<AudioClientConnection> AcceptClient(uint32_t num_streams,
108                                                       uint32_t num_jacks,
109                                                       uint32_t num_chmaps,
110                                                       size_t tx_shm_len,
111                                                       size_t rx_shm_len);
112 
113  private:
114   SharedFD server_socket_;
115 };
116 
117 }  // namespace cuttlefish
118