1 /*
2 * Copyright Samsung Electronics Co.,LTD.
3 * Copyright (C) 2017 The Android Open Source Project
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 #include <cstring>
18
19 #include <sys/types.h>
20 #include <sys/stat.h>
21 #include <fcntl.h>
22 #include <sys/ioctl.h>
23
24 #include <log/log.h>
25
26 #include "acrylic_internal.h"
27 #include "acrylic_device.h"
28
AcrylicDevice(const char * devpath)29 AcrylicDevice::AcrylicDevice(const char *devpath)
30 : mDevPath(devpath), mDevFD(-1)
31 {
32 }
33
~AcrylicDevice()34 AcrylicDevice::~AcrylicDevice()
35 {
36 if (mDevFD >= 0)
37 ::close(mDevFD);
38 }
39
open()40 bool AcrylicDevice::open()
41 {
42 if (mDevFD >= 0)
43 return true;
44
45 mDevFD = ::open(mDevPath.c_str(), O_RDWR);
46 if (mDevFD < 0) {
47 ALOGERR("Failed to open %s", mDevPath.c_str());
48 return false;
49 }
50
51 ALOGD_TEST("Opened %s on fd %d", mDevPath.c_str(), mDevFD);
52
53 return true;
54 }
55
ioctl(int cmd,void * arg)56 int AcrylicDevice::ioctl(int cmd, void *arg)
57 {
58 if (!open())
59 return -1;
60
61 return ::ioctl(mDevFD, cmd, arg);
62 }
63
AcrylicRedundantDevice(const char * devpath)64 AcrylicRedundantDevice::AcrylicRedundantDevice(const char *devpath)
65 : mDevPath(devpath), mDevFd{-1, -1, -1}, mFdIdx(0)
66 {
67 mDevPath = devpath;
68 }
69
~AcrylicRedundantDevice()70 AcrylicRedundantDevice::~AcrylicRedundantDevice()
71 {
72 for (int i = 0; i < MAX_DEVICE_FD; i++)
73 ::close(mDevFd[i]);
74 }
75
open()76 bool AcrylicRedundantDevice::open()
77 {
78 if (mDevFd[0] >= 0)
79 return true;
80
81 for (int i = 0; i < MAX_DEVICE_FD; i++) {
82 if (mDevFd[i] < 0) {
83 mDevFd[i] = ::open(mDevPath.c_str(), O_RDWR);
84 if (mDevFd[i] < 0) {
85 ALOGERR("Failed to open %s for devfd[%d]", mDevPath.c_str(), i);
86 while (i-- > 0) {
87 ::close(mDevFd[i]);
88 mDevFd[i] = -1;
89 }
90 return false;
91 }
92
93 ALOGD_TEST("Opened %s on devfd[%d] %d", mDevPath.c_str(), i, mDevFd[i]);
94 }
95 }
96
97 return true;
98 }
99
ioctl_unique(int cmd,void * arg)100 int AcrylicRedundantDevice::ioctl_unique(int cmd, void *arg)
101 {
102 if (!open())
103 return -1;
104
105 return ::ioctl(mDevFd[0], cmd, arg);
106 }
107
ioctl_current(int cmd,void * arg)108 int AcrylicRedundantDevice::ioctl_current(int cmd, void *arg)
109 {
110 if (!open())
111 return -1;
112
113 return ::ioctl(mDevFd[mFdIdx], cmd, arg);
114 }
115
ioctl_broadcast(int cmd,void * arg)116 int AcrylicRedundantDevice::ioctl_broadcast(int cmd, void *arg) {
117 if (!open())
118 return -1;
119
120 for (int i = 0; i < MAX_DEVICE_FD; i++) {
121 int ret = ::ioctl(mDevFd[i], cmd, arg);
122 if (ret < 0)
123 return ret;
124 }
125
126 return 0;
127 }
128