1 /******************************************************************************
2  *
3  *  Copyright (C) 2022 Google, Inc.
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at:
8  *
9  *  http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  ******************************************************************************/
18 
19 #include "hal/snoop_logger_socket_thread.h"
20 
21 #include <arpa/inet.h>
22 #include <bluetooth/log.h>
23 #include <fcntl.h>
24 #include <netinet/in.h>
25 #include <pthread.h>
26 #include <stdbool.h>
27 #include <string.h>
28 #include <sys/prctl.h>
29 #include <sys/socket.h>
30 #include <sys/types.h>
31 #include <sys/un.h>
32 #include <unistd.h>
33 
34 #include "hal/snoop_logger_common.h"
35 
36 namespace bluetooth {
37 namespace hal {
38 
SnoopLoggerSocketThread(std::unique_ptr<SnoopLoggerSocket> && socket)39 SnoopLoggerSocketThread::SnoopLoggerSocketThread(std::unique_ptr<SnoopLoggerSocket>&& socket) {
40   socket_ = std::move(socket);
41   stop_thread_ = false;
42   listen_thread_running_ = false;
43 }
44 
~SnoopLoggerSocketThread()45 SnoopLoggerSocketThread::~SnoopLoggerSocketThread() { Stop(); }
46 
Start()47 std::future<bool> SnoopLoggerSocketThread::Start() {
48   log::debug("");
49   std::promise<bool> thread_started;
50   auto future = thread_started.get_future();
51   listen_thread_ = std::make_unique<std::thread>(&SnoopLoggerSocketThread::Run, this,
52                                                  std::move(thread_started));
53   stop_thread_ = false;
54   return future;
55 }
56 
Stop()57 void SnoopLoggerSocketThread::Stop() {
58   log::debug("");
59 
60   stop_thread_ = true;
61   socket_->NotifySocketListener();
62 
63   if (listen_thread_ && listen_thread_->joinable()) {
64     listen_thread_->join();
65     listen_thread_.reset();
66   }
67 }
68 
Write(const void * data,size_t length)69 void SnoopLoggerSocketThread::Write(const void* data, size_t length) {
70   socket_->Write(data, length);
71 }
72 
ThreadIsRunning() const73 bool SnoopLoggerSocketThread::ThreadIsRunning() const { return listen_thread_running_; }
74 
GetSocket()75 SnoopLoggerSocket* SnoopLoggerSocketThread::GetSocket() { return socket_.get(); }
76 
Run(std::promise<bool> thread_started)77 void SnoopLoggerSocketThread::Run(std::promise<bool> thread_started) {
78   log::debug("");
79 
80   if (socket_->InitializeCommunications() != 0) {
81     thread_started.set_value(false);
82     return;
83   }
84 
85   thread_started.set_value(true);
86 
87   while (!stop_thread_ && socket_->ProcessIncomingRequest()) {
88   }
89 
90   socket_->Cleanup();
91   listen_thread_running_ = false;
92 }
93 
94 }  // namespace hal
95 }  // namespace bluetooth
96