1ec533e0f59b7e88bac734d538f596ab095bc74camukesh agrawal/*
2ec533e0f59b7e88bac734d538f596ab095bc74camukesh agrawal * Copyright (C) 2016 The Android Open Source Project
3ec533e0f59b7e88bac734d538f596ab095bc74camukesh agrawal *
4ec533e0f59b7e88bac734d538f596ab095bc74camukesh agrawal * Licensed under the Apache License, Version 2.0 (the "License");
5ec533e0f59b7e88bac734d538f596ab095bc74camukesh agrawal * you may not use this file except in compliance with the License.
6ec533e0f59b7e88bac734d538f596ab095bc74camukesh agrawal * You may obtain a copy of the License at
7ec533e0f59b7e88bac734d538f596ab095bc74camukesh agrawal *
8ec533e0f59b7e88bac734d538f596ab095bc74camukesh agrawal *      http://www.apache.org/licenses/LICENSE-2.0
9ec533e0f59b7e88bac734d538f596ab095bc74camukesh agrawal *
10ec533e0f59b7e88bac734d538f596ab095bc74camukesh agrawal * Unless required by applicable law or agreed to in writing, software
11ec533e0f59b7e88bac734d538f596ab095bc74camukesh agrawal * distributed under the License is distributed on an "AS IS" BASIS,
12ec533e0f59b7e88bac734d538f596ab095bc74camukesh agrawal * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ec533e0f59b7e88bac734d538f596ab095bc74camukesh agrawal * See the License for the specific language governing permissions and
14ec533e0f59b7e88bac734d538f596ab095bc74camukesh agrawal * limitations under the License.
15ec533e0f59b7e88bac734d538f596ab095bc74camukesh agrawal */
16ec533e0f59b7e88bac734d538f596ab095bc74camukesh agrawal
17ec533e0f59b7e88bac734d538f596ab095bc74camukesh agrawal#ifndef OS_H_
18ec533e0f59b7e88bac734d538f596ab095bc74camukesh agrawal#define OS_H_
19ec533e0f59b7e88bac734d538f596ab095bc74camukesh agrawal
20ec533e0f59b7e88bac734d538f596ab095bc74camukesh agrawal#include <time.h>
21ec533e0f59b7e88bac734d538f596ab095bc74camukesh agrawal
22ec533e0f59b7e88bac734d538f596ab095bc74camukesh agrawal#include <cstdint>
23ec533e0f59b7e88bac734d538f596ab095bc74camukesh agrawal#include <memory>
24a5bb08c1cf8a8d1ff097fa7a050d7787e9821c6amukesh agrawal#include <string>
25b8f8f6ab38fe147fa7aed5cdd9f9ce0e5a3a2e2fmukesh agrawal#include <tuple>
26ec533e0f59b7e88bac734d538f596ab095bc74camukesh agrawal#include <utility>
27ec533e0f59b7e88bac734d538f596ab095bc74camukesh agrawal
28ec533e0f59b7e88bac734d538f596ab095bc74camukesh agrawal#include "android-base/macros.h"
29ec533e0f59b7e88bac734d538f596ab095bc74camukesh agrawal
30d75fd9e9b73995a6303ae99977ab1baf9db9b42fmukesh agrawal#include "wifilogd/local_utils.h"
31ec533e0f59b7e88bac734d538f596ab095bc74camukesh agrawal#include "wifilogd/raw_os.h"
32ec533e0f59b7e88bac734d538f596ab095bc74camukesh agrawal
33ec533e0f59b7e88bac734d538f596ab095bc74camukesh agrawalnamespace android {
34ec533e0f59b7e88bac734d538f596ab095bc74camukesh agrawalnamespace wifilogd {
35ec533e0f59b7e88bac734d538f596ab095bc74camukesh agrawal
36ec533e0f59b7e88bac734d538f596ab095bc74camukesh agrawal// Abstracts operating system calls.
37ec533e0f59b7e88bac734d538f596ab095bc74camukesh agrawal//
38ec533e0f59b7e88bac734d538f596ab095bc74camukesh agrawal// There are three reasons we want to abstract OS calls:
39ec533e0f59b7e88bac734d538f596ab095bc74camukesh agrawal// 1. Allow tests to run hermetically.
40ec533e0f59b7e88bac734d538f596ab095bc74camukesh agrawal// 2. Verify that the application logic invokes the OS calls as expected.
41ec533e0f59b7e88bac734d538f596ab095bc74camukesh agrawal// 3. Provide interfaces that as easier to use, than the underlying OS calls.
42ec533e0f59b7e88bac734d538f596ab095bc74camukesh agrawalclass Os {
43ec533e0f59b7e88bac734d538f596ab095bc74camukesh agrawal public:
44b8f8f6ab38fe147fa7aed5cdd9f9ce0e5a3a2e2fmukesh agrawal  using Errno = int;
45b8f8f6ab38fe147fa7aed5cdd9f9ce0e5a3a2e2fmukesh agrawal
46ec533e0f59b7e88bac734d538f596ab095bc74camukesh agrawal  struct Timestamp {
47ec533e0f59b7e88bac734d538f596ab095bc74camukesh agrawal    uint32_t secs;  // Sufficient through 2100.
48ec533e0f59b7e88bac734d538f596ab095bc74camukesh agrawal    uint32_t nsecs;
49ec533e0f59b7e88bac734d538f596ab095bc74camukesh agrawal  };
50ec533e0f59b7e88bac734d538f596ab095bc74camukesh agrawal
51cc8458a847dafc8be2ce5de5a0e39a292780e6d5mukesh agrawal  static constexpr int kInvalidFd = -1;
52960c8a88c83c55c21a3286628591a41d2fb42231mukesh agrawal  static constexpr auto kMaxNanos = 999'999'999;
53cc8458a847dafc8be2ce5de5a0e39a292780e6d5mukesh agrawal
54ec533e0f59b7e88bac734d538f596ab095bc74camukesh agrawal  // Constructs an Os instance.
55ec533e0f59b7e88bac734d538f596ab095bc74camukesh agrawal  Os();
56ec533e0f59b7e88bac734d538f596ab095bc74camukesh agrawal
57ec533e0f59b7e88bac734d538f596ab095bc74camukesh agrawal  // Constructs an Os instance, with the caller-provided RawOs. This method
58ec533e0f59b7e88bac734d538f596ab095bc74camukesh agrawal  // allows tests to provide a MockRawOs.
59ec533e0f59b7e88bac734d538f596ab095bc74camukesh agrawal  explicit Os(std::unique_ptr<RawOs> raw_os);
60ec533e0f59b7e88bac734d538f596ab095bc74camukesh agrawal
61ec533e0f59b7e88bac734d538f596ab095bc74camukesh agrawal  virtual ~Os();
62ec533e0f59b7e88bac734d538f596ab095bc74camukesh agrawal
63a5bb08c1cf8a8d1ff097fa7a050d7787e9821c6amukesh agrawal  // Returns the Android control socket with name |socket_name|. If no such
64a5bb08c1cf8a8d1ff097fa7a050d7787e9821c6amukesh agrawal  // socket exists, or the init daemon has not provided this process with
65a5bb08c1cf8a8d1ff097fa7a050d7787e9821c6amukesh agrawal  // access to said socket, returns {kInvalidFd, errno}.
66a5bb08c1cf8a8d1ff097fa7a050d7787e9821c6amukesh agrawal  virtual std::tuple<int, Errno> GetControlSocket(
67a5bb08c1cf8a8d1ff097fa7a050d7787e9821c6amukesh agrawal      const std::string& socket_name);
68a5bb08c1cf8a8d1ff097fa7a050d7787e9821c6amukesh agrawal
69ec533e0f59b7e88bac734d538f596ab095bc74camukesh agrawal  // Returns the current time, as reported by the clock with |clock_id|.
70ec533e0f59b7e88bac734d538f596ab095bc74camukesh agrawal  virtual Timestamp GetTimestamp(clockid_t clock_id) const;
71ec533e0f59b7e88bac734d538f596ab095bc74camukesh agrawal
72960c8a88c83c55c21a3286628591a41d2fb42231mukesh agrawal  // Suspends execution of this process, for |sleep_time_nsec|. The passed
73960c8a88c83c55c21a3286628591a41d2fb42231mukesh agrawal  // value must not exceed kMaxNanos.
74960c8a88c83c55c21a3286628591a41d2fb42231mukesh agrawal  virtual void Nanosleep(uint32_t sleep_time_nsec);
75960c8a88c83c55c21a3286628591a41d2fb42231mukesh agrawal
76d75fd9e9b73995a6303ae99977ab1baf9db9b42fmukesh agrawal  // Receives a datagram of up to |buflen| from |fd|, writing the data to |buf|.
77d75fd9e9b73995a6303ae99977ab1baf9db9b42fmukesh agrawal  // Returns the size of the datagram, and the result of the operation (0 for
78d75fd9e9b73995a6303ae99977ab1baf9db9b42fmukesh agrawal  // success, |errno| otherwise).
79d75fd9e9b73995a6303ae99977ab1baf9db9b42fmukesh agrawal  //
80d75fd9e9b73995a6303ae99977ab1baf9db9b42fmukesh agrawal  // Notes:
81d75fd9e9b73995a6303ae99977ab1baf9db9b42fmukesh agrawal  // - |buflen| may not exceed the maximal value for ssize_t.
82d75fd9e9b73995a6303ae99977ab1baf9db9b42fmukesh agrawal  // - The call blocks until a datagram is available.
83d75fd9e9b73995a6303ae99977ab1baf9db9b42fmukesh agrawal  // - If the datagram is larger than |buflen|, only |buflen| bytes will
84d75fd9e9b73995a6303ae99977ab1baf9db9b42fmukesh agrawal  //   be received. The returned size_t will, however, reflect the full
85d75fd9e9b73995a6303ae99977ab1baf9db9b42fmukesh agrawal  //   length of the datagram.
86d75fd9e9b73995a6303ae99977ab1baf9db9b42fmukesh agrawal  virtual std::tuple<size_t, Errno> ReceiveDatagram(int fd, NONNULL void* buf,
87d75fd9e9b73995a6303ae99977ab1baf9db9b42fmukesh agrawal                                                    size_t buflen);
88d75fd9e9b73995a6303ae99977ab1baf9db9b42fmukesh agrawal
89b8f8f6ab38fe147fa7aed5cdd9f9ce0e5a3a2e2fmukesh agrawal  // Writes |buflen| bytes from |buf| to |fd|. Returns the number of bytes
90b8f8f6ab38fe147fa7aed5cdd9f9ce0e5a3a2e2fmukesh agrawal  // written, and the result of the operation (0 for success, |errno|
91b8f8f6ab38fe147fa7aed5cdd9f9ce0e5a3a2e2fmukesh agrawal  // otherwise).
92b8f8f6ab38fe147fa7aed5cdd9f9ce0e5a3a2e2fmukesh agrawal  //
93b8f8f6ab38fe147fa7aed5cdd9f9ce0e5a3a2e2fmukesh agrawal  // Notes:
94b8f8f6ab38fe147fa7aed5cdd9f9ce0e5a3a2e2fmukesh agrawal  // - |buflen| may not exceed the maximal value for ssize_t.
95b8f8f6ab38fe147fa7aed5cdd9f9ce0e5a3a2e2fmukesh agrawal  // - The returned size_t will not exceed |buflen|.
96d75fd9e9b73995a6303ae99977ab1baf9db9b42fmukesh agrawal  virtual std::tuple<size_t, Errno> Write(int fd, NONNULL const void* buf,
97b8f8f6ab38fe147fa7aed5cdd9f9ce0e5a3a2e2fmukesh agrawal                                          size_t buflen);
98b8f8f6ab38fe147fa7aed5cdd9f9ce0e5a3a2e2fmukesh agrawal
99ec533e0f59b7e88bac734d538f596ab095bc74camukesh agrawal private:
100ec533e0f59b7e88bac734d538f596ab095bc74camukesh agrawal  const std::unique_ptr<RawOs> raw_os_;
101ec533e0f59b7e88bac734d538f596ab095bc74camukesh agrawal
102ec533e0f59b7e88bac734d538f596ab095bc74camukesh agrawal  DISALLOW_COPY_AND_ASSIGN(Os);
103ec533e0f59b7e88bac734d538f596ab095bc74camukesh agrawal};
104ec533e0f59b7e88bac734d538f596ab095bc74camukesh agrawal
105ec533e0f59b7e88bac734d538f596ab095bc74camukesh agrawal}  // namespace wifilogd
106ec533e0f59b7e88bac734d538f596ab095bc74camukesh agrawal}  // namespace android
107ec533e0f59b7e88bac734d538f596ab095bc74camukesh agrawal
108ec533e0f59b7e88bac734d538f596ab095bc74camukesh agrawal#endif  // OS_H_
109