1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "sensor_hdi_dump.h"
17 #include "osal_mem.h"
18 #include <securec.h>
19 #include <unordered_map>
20 #include "sensor_uhdf_log.h"
21 
22 #define HDF_LOG_TAG uhdf_sensor_hdi_dump
23 
24 constexpr int32_t GET_SENSORINFO = 0;
25 constexpr int32_t DATA_LEN = 256;
26 
27 namespace OHOS {
28 namespace HDI {
29 namespace Sensor {
30 namespace V2_0 {
31 
32 static const char *SENSOR_HELP =
33     " Sensor manager dump options:\n"
34     "     -h: [sensor command help]\n"
35     "     -l: [show sensor list]\n"
36     "     -d: [The data information is displayed 10 times]\n"
37     "     -c: [show sensor client information]\n";
38 
SensorHdiDump()39 SensorHdiDump::SensorHdiDump()
40 {}
41 
~SensorHdiDump()42 SensorHdiDump::~SensorHdiDump()
43 {}
44 
SensorShowList(struct HdfSBuf * reply)45 int32_t SensorHdiDump::SensorShowList(struct HdfSBuf *reply)
46 {
47     std::vector<HdfSensorInformation> sensorInfoList;
48 
49     SensorClientsManager::GetInstance()->CopySensorInfo(sensorInfoList, GET_SENSORINFO);
50 
51     if (sensorInfoList.empty()) {
52         HDF_LOGE("%{public}s: no sensor info in list", __func__);
53         return HDF_FAILURE;
54     }
55 
56     for (const auto &it : sensorInfoList) {
57         std::string st = {0};
58         st = "sensorName:  " + it.sensorName + "\n" +
59              "sensorId:  " + std::to_string(it.sensorId) + "\n" +
60              "sensorTypeId:  " + std::to_string(it.sensorTypeId) + "\n" +
61              "maxRange:  " + std::to_string(it.maxRange) + "\n" +
62              "accuracy:  " + std::to_string(it.accuracy) + "\n" +
63              "power:  " + std::to_string(it.power) + "\n" +
64              "minDelay:  " + std::to_string(it.minDelay) + "\n" +
65              "maxDelay:  " + std::to_string(it.maxDelay) + "\n" +
66              "fifoMaxEventCount:  " + std::to_string(it.fifoMaxEventCount) + "\n" +
67              "============================================\n";
68             (void)HdfSbufWriteString(reply, st.c_str());
69     }
70     return HDF_SUCCESS;
71 }
72 
SensorInfoDataToString(const float * data,const int64_t timesTamp,const int32_t dataDimension,const int32_t sensorId)73 std::string SensorHdiDump::SensorInfoDataToString(const float *data,
74                                                   const int64_t timesTamp,
75                                                   const int32_t dataDimension,
76                                                   const int32_t sensorId)
77 {
78     std::string dataStr = {0};
79     std::string st = {0};
80     char arrayStr[DATA_LEN] = {0};
81 
82     for (int32_t i = 0; i < dataDimension; i++) {
83         if (sprintf_s(arrayStr + strlen(arrayStr), DATA_LEN, "[%f]", data[i]) < 0) {
84             HDF_LOGE("%{public}s: sprintf_s failed", __func__);
85             return st;
86         }
87     }
88 
89     dataStr = arrayStr;
90     st = "sensor id: " + std::to_string(sensorId) + ", ts = " +
91         std::to_string(timesTamp / 1e9) + ", data = " + dataStr + "\n";
92 
93     return st;
94 }
95 
ShowData(const float * data,const int64_t timesTamp,const int32_t dataDimension,const int32_t sensorId,struct HdfSBuf * reply)96 int32_t SensorHdiDump::ShowData(const float *data,
97                                 const int64_t timesTamp,
98                                 const int32_t dataDimension,
99                                 const int32_t sensorId,
100                                 struct HdfSBuf *reply)
101 {
102     std::string sensorInfoData = {0};
103 
104     switch (dataDimension) {
105         case MEM_X:
106         case MEM_XY:
107         case MEM_XYZ:
108         case MEM_UNCALIBRATED:
109         case MEM_POSTURE:
110         case MEM_SPE_RGB:
111             sensorInfoData = SensorInfoDataToString(data, timesTamp, dataDimension, sensorId);
112             break;
113         default:
114             HDF_LOGE("%{public}s: unsupported dimension, dimension is %{public}d", __func__, dataDimension);
115             break;
116     }
117 
118     if (sensorInfoData.empty()) {
119         HDF_LOGE("%{public}s: sensor infomation data is empty!", __func__);
120         return HDF_FAILURE;
121     }
122 
123     (void)HdfSbufWriteString(reply, sensorInfoData.c_str());
124     return HDF_SUCCESS;
125 }
126 
SensorShowData(struct HdfSBuf * reply)127 int32_t SensorHdiDump::SensorShowData(struct HdfSBuf *reply)
128 {
129     struct SensorsDataPack eventDumpList;
130     uint8_t *eventData = nullptr;
131 
132     SensorClientsManager::GetInstance()->GetEventData(eventDumpList);
133 
134     (void)HdfSbufWriteString(reply, "============== The last 10 data records ==============\n");
135 
136     for (int32_t i = 0; i < eventDumpList.count; i++) {
137         int32_t index = static_cast<const uint32_t>(eventDumpList.pos + i) < MAX_DUMP_DATA_SIZE ?
138             (eventDumpList.pos + i) : (eventDumpList.pos + i - MAX_DUMP_DATA_SIZE);
139         uint32_t dataLen = eventDumpList.listDumpArray[index].dataLen;
140         eventData = static_cast<uint8_t*>(OsalMemCalloc(dataLen));
141         if (eventData == nullptr) {
142             HDF_LOGE("%{public}s: malloc failed!", __func__);
143             return HDF_FAILURE;
144         }
145 
146         std::copy(eventDumpList.listDumpArray[index].data.begin(),
147                   eventDumpList.listDumpArray[index].data.end(), eventData);
148         float *data = reinterpret_cast<float*>(eventData);
149 
150         int32_t dataDimension = static_cast<int32_t>(dataLen / sizeof(float));
151 
152         int32_t ret = ShowData(data, eventDumpList.listDumpArray[index].timestamp, dataDimension,
153                                eventDumpList.listDumpArray[index].sensorId, reply);
154         if (ret != HDF_SUCCESS) {
155             OsalMemFree(eventData);
156             HDF_LOGE("%{public}s: print sensor infomation data failed!", __func__);
157             return HDF_FAILURE;
158         }
159 
160         OsalMemFree(eventData);
161         eventData = nullptr;
162     }
163 
164     return HDF_SUCCESS;
165 }
166 
SensorShowClient(struct HdfSBuf * reply)167 int32_t SensorHdiDump::SensorShowClient(struct HdfSBuf *reply)
168 {
169     std::unordered_map<int, SensorClientInfo> sensorClientInfoMap;
170     if (!SensorClientsManager::GetInstance()->GetClients(HDF_TRADITIONAL_SENSOR_TYPE, sensorClientInfoMap)) {
171         HDF_LOGD("%{public}s groupId %{public}d is not used by anyone", __func__, HDF_TRADITIONAL_SENSOR_TYPE);
172         return HDF_FAILURE;
173     }
174     std::unordered_map<int32_t, struct BestSensorConfig> bestSensorConfigMap;
175     (void)SensorClientsManager::GetInstance()->GetBestSensorConfigMap(bestSensorConfigMap);
176     std::unordered_map<int, std::set<int>> sensorEnabled = SensorClientsManager::GetInstance()->GetSensorUsed();
177     (void)HdfSbufWriteString(reply, "============== all clients information ==============\n\n");
178     std::string sensorInfoData = "";
179     sensorInfoData += "bestSensorConfigMap={\n";
180     for (const auto &entry2 : bestSensorConfigMap) {
181         auto sensorId = entry2.first;
182         auto bestSensorConfig = entry2.second;
183         sensorInfoData += "{sensorId=" + std::to_string(sensorId) + ",";
184         sensorInfoData += "bestSensorConfig={";
185         sensorInfoData += "samplingInterval=" + std::to_string(bestSensorConfig.samplingInterval) + ",";
186         sensorInfoData += "reportInterval=" + std::to_string(bestSensorConfig.reportInterval);
187         sensorInfoData += "}}\n";
188     }
189     sensorInfoData += "}\n\n";
190     for (const auto &entry : sensorClientInfoMap) {
191         auto serviceId = entry.first;
192         auto sensorClientInfo = entry.second;
193         sensorInfoData += "serviceId=" + std::to_string(serviceId) + " ";
194         sensorInfoData += "sensorConfigMap_={\n";
195         for (const auto &entry2 : sensorClientInfo.sensorConfigMap_) {
196             auto sensorId = entry2.first;
197             auto sensorConfig = entry2.second;
198             sensorInfoData += "{sensorId=" + std::to_string(sensorId) + ",";
199             sensorInfoData += "sensorConfig={";
200             sensorInfoData += "samplingInterval=" + std::to_string(sensorConfig.samplingInterval) + ",";
201             sensorInfoData += "reportInterval=" + std::to_string(sensorConfig.reportInterval) + ",";
202             sensorInfoData += "curCount/periodCount=" + std::to_string(sensorClientInfo.curCountMap_[sensorId]) + "/" +
203                     std::to_string(sensorClientInfo.periodCountMap_[sensorId]) + ",";
204             if (sensorEnabled.find(sensorId) != sensorEnabled.end() &&
205                 sensorEnabled.find(sensorId)->second.find(serviceId) != sensorEnabled.find(sensorId)->second.end()) {
206                 sensorInfoData += "enable";
207             }
208             sensorInfoData += "}}\n";
209         }
210         sensorInfoData += "}\n\n";
211     }
212     (void)HdfSbufWriteString(reply, sensorInfoData.c_str());
213     return HDF_SUCCESS;
214 }
215 
DevHostSensorHdiDump(struct HdfSBuf * data,struct HdfSBuf * reply)216 int32_t SensorHdiDump::DevHostSensorHdiDump(struct HdfSBuf *data, struct HdfSBuf *reply)
217 {
218     uint32_t argc = 0;
219 
220     if (data == nullptr || reply == nullptr) {
221         HDF_LOGE("%{public}s: data or reply is nullptr", __func__);
222         return HDF_FAILURE;
223     }
224 
225     if (!HdfSbufReadUint32(data, &argc)) {
226         HDF_LOGE("%{public}s: read &argc failed", __func__);
227         return HDF_FAILURE;
228     }
229 
230     if (argc == 0) {
231         (void)HdfSbufWriteString(reply, SENSOR_HELP);
232         return HDF_SUCCESS;
233     }
234 
235     for (uint32_t i = 0; i < argc; i++) {
236         const char *value = HdfSbufReadString(data);
237         if (value == nullptr) {
238             HDF_LOGE("%{public}s: arg is invalid", __func__);
239             return HDF_FAILURE;
240         }
241         if (strcmp(value, "-h") == 0) {
242             (void)HdfSbufWriteString(reply, SENSOR_HELP);
243             return HDF_SUCCESS;
244         } else if (strcmp(value, "-l") == 0) {
245             SensorShowList(reply);
246             return HDF_SUCCESS;
247         } else if (strcmp(value, "-d") == 0) {
248             SensorShowData(reply);
249             return HDF_SUCCESS;
250         } else if (strcmp(value, "-c") == 0) {
251             SensorShowClient(reply);
252             return HDF_SUCCESS;
253         }
254     }
255 
256     return HDF_SUCCESS;
257 }
258 
GetSensorDump(struct HdfSBuf * data,struct HdfSBuf * reply)259 int32_t GetSensorDump(struct HdfSBuf *data, struct HdfSBuf *reply)
260 {
261     SensorHdiDump::DevHostSensorHdiDump(data, reply);
262     return HDF_SUCCESS;
263 }
264 
265 } // V2_0
266 } // Sensor
267 } // HDI
268 } // OHOS