1/*
2 * Copyright (c) 2023 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_dump.h"
17#include <inttypes.h>
18#include "devhost_dump_reg.h"
19#include "sensor_uhdf_log.h"
20#include "sensor_channel.h"
21#include "sensor_controller.h"
22#include "sensor_manager.h"
23
24#define HDF_LOG_TAG    uhdf_sensor_service
25#define STRING_LEN    2048
26
27static const char *g_helpComment =
28    " Sensor manager dump options:\n"
29    "     -h: [sensor command help]\n"
30    "     -l: [show sensor list]\n"
31    "     -d: [The data information is displayed 10 times]\n";
32
33struct SensorDevelopmentList {
34    int32_t sensorTypeId;
35    char sensorName[SENSOR_NAME_MAX_LEN];
36    int32_t dataDimension;
37};
38
39struct SensorDevelopmentList g_sensorList[] = {
40    { SENSOR_TYPE_NONE, "sensor_test", DATA_X },
41    { SENSOR_TYPE_ACCELEROMETER, "accelerometer", DATA_XYZ },
42    { SENSOR_TYPE_PEDOMETER, "pedometer", DATA_X },
43    { SENSOR_TYPE_PROXIMITY, "proximity", DATA_X },
44    { SENSOR_TYPE_HALL, "hallrometer", DATA_X },
45    { SENSOR_TYPE_BAROMETER, "barometer", DATA_XY },
46    { SENSOR_TYPE_AMBIENT_LIGHT, "als", DATA_X },
47    { SENSOR_TYPE_MAGNETIC_FIELD, "magnetometer", DATA_XYZ },
48    { SENSOR_TYPE_GYROSCOPE, "gyroscope", DATA_XYZ },
49    { SENSOR_TYPE_GRAVITY, "gravity", DATA_XYZ }
50};
51
52int32_t SensorShowList(struct HdfSBuf *reply)
53{
54    int32_t index = -1;
55    int32_t ret = 0;
56    int32_t *sensorStatus = NULL;
57    struct SensorDevManager *sensorList = NULL;
58    char sensorInfoDate[STRING_LEN] = { 0 };
59
60    sensorList = GetSensorDevManager();
61    if ((sensorList == NULL) || (sensorList->sensorInfoEntry == NULL) || (sensorList->sensorSum == 0)) {
62        HDF_LOGE("%{publuc}s: sensorList is failed\n", __func__);
63        return DUMP_NULL_PTR;
64    }
65
66    sensorStatus = GetSensorStatus();
67    if (sensorStatus == NULL) {
68        HDF_LOGE("%{publuc}s: sensorStatus is failed\n", __func__);
69        return DUMP_NULL_PTR;
70    }
71
72    for (index = 0; index < sensorList->sensorSum; index++) {
73        ret = memset_s(sensorInfoDate, STRING_LEN, 0, STRING_LEN);
74        if (ret != DUMP_SUCCESS) {
75            HDF_LOGE("%{publuc}s: memset sensorInfoList is failed\n", __func__);
76            return DUMP_FAILURE;
77        }
78
79        ret = sprintf_s(sensorInfoDate, STRING_LEN,
80            "=================================================\n\r \
81            sensorName: %s \n\r \
82            sensorId: %d \n\r \
83            sensorStatus: %d \n\r \
84            maxRange: %f \n\r \
85            accuracy: %f \n\r \
86            power:    %f \n\r \
87            minDelay: %" PRId64 "\n\r \
88            maxDelay: %" PRId64 "\n\r \
89            fifoMaxEventCount: %u \n\r",
90            sensorList->sensorInfoEntry[index].sensorName,
91            sensorList->sensorInfoEntry[index].sensorId,
92            sensorStatus[sensorList->sensorInfoEntry[index].sensorId],
93            sensorList->sensorInfoEntry[index].maxRange,
94            sensorList->sensorInfoEntry[index].accuracy,
95            sensorList->sensorInfoEntry[index].power,
96            sensorList->sensorInfoEntry[index].minDelay,
97            sensorList->sensorInfoEntry[index].maxDelay,
98            sensorList->sensorInfoEntry[index].fifoMaxEventCount);
99        if (ret < DUMP_SUCCESS) {
100            HDF_LOGE("%{publuc}s: sprintf sensorList is failed\n", __func__);
101            return DUMP_FAILURE;
102        }
103
104        (void)HdfSbufWriteString(reply, sensorInfoDate);
105    }
106
107    return DUMP_SUCCESS;
108}
109
110static void ShowData(const float *data, int64_t timesTamp, const struct SensorDevelopmentList sensorNode,
111    struct HdfSBuf *reply)
112{
113    int32_t ret = 0;
114    char sensorInfoDate[STRING_LEN] = { 0 };
115
116    if (sensorNode.dataDimension == DATA_X) {
117        ret = sprintf_s(sensorInfoDate, STRING_LEN,
118            "sensor name :[%s], sensor id :[%d], ts=[%0.9f], data= [%f]\n\r",
119            sensorNode.sensorName, sensorNode.sensorTypeId, timesTamp / 1e9, *(data));
120        if (ret < DUMP_SUCCESS) {
121            HDF_LOGE("%{publuc}s: sprintf sensorInfoDate is failed\n", __func__);
122            return;
123        }
124    } else {
125        ret = sprintf_s(sensorInfoDate, STRING_LEN,
126            "sensor name :[%s], sensor id :[%d], ts=[%0.9f], data= [%f], [%f], [%f]\n\r",
127            sensorNode.sensorName, sensorNode.sensorTypeId, timesTamp / 1e9, *(data), *(data + DATA_X),
128            *(data + DATA_XY));
129        if (ret < DUMP_SUCCESS) {
130            HDF_LOGE("%{publuc}s: sprintf ShowData is failed\n", __func__);
131            return;
132        }
133    }
134    (void)HdfSbufWriteString(reply, sensorInfoDate);
135}
136
137int32_t SensorShowData(struct HdfSBuf *reply)
138{
139    int32_t len;
140    int32_t ret = 0;
141    struct SensorDatePack *eventDumpList;
142    char sensorInfoDate[STRING_LEN] = { 0 };
143
144    eventDumpList = GetEventData();
145
146    ret = sprintf_s(sensorInfoDate, STRING_LEN, "======The last 10 data records======\n\r");
147    if (ret < DUMP_SUCCESS) {
148        HDF_LOGE("%{publuc}s: sprintf SensorShowData is failed\n", __func__);
149        return DUMP_NULL_PTR;
150    }
151    (void)HdfSbufWriteString(reply, sensorInfoDate);
152
153    if (eventDumpList->count < MAX_DUMP_DATA_SIZE) {
154        for (len = 0; len < eventDumpList->count; len++) {
155            float *data = (float *)(eventDumpList->listDumpArr[len].data);
156            ShowData(data, eventDumpList->listDumpArr[len].timestamp,
157                g_sensorList[eventDumpList->listDumpArr[len].sensorId], reply);
158        }
159    } else {
160        int32_t pos = eventDumpList->pos;
161        for (len = 0; len < eventDumpList->count; len++) {
162            pos = pos + 1 > MAX_DUMP_DATA_SIZE ? 1 : pos + 1;
163            float *data = (float *)(eventDumpList->listDumpArr[pos - 1].data);
164            ShowData(data, eventDumpList->listDumpArr[pos - 1].timestamp,
165                g_sensorList[eventDumpList->listDumpArr[pos - 1].sensorId], reply);
166        }
167    }
168
169    return DUMP_SUCCESS;
170}
171
172static int32_t DevHostSensorDump(struct HdfSBuf *data, struct HdfSBuf *reply)
173{
174    uint32_t argv = 0;
175
176    if (data == NULL || reply == NULL) {
177        HDF_LOGE("%{public}s data or reply is invalid", __func__);
178        return HDF_FAILURE;
179    }
180
181    if (!HdfSbufReadUint32(data, &argv)) {
182        HDF_LOGE("%{public}s: read &argv failed!", __func__);
183        return DUMP_FAILURE;
184    }
185
186    if (argv == 0) {
187        (void)HdfSbufWriteString(reply, g_helpComment);
188        return HDF_SUCCESS;
189    }
190
191    for (uint32_t i = 0; i < argv; i++) {
192        const char *value = HdfSbufReadString(data);
193        if (value == NULL) {
194            HDF_LOGE("%{public}s value is invalid", __func__);
195            return HDF_FAILURE;
196        }
197        if (strcmp(value, "-h") == 0) {
198            (void)HdfSbufWriteString(reply, g_helpComment);
199            return HDF_SUCCESS;
200        } else if (strcmp(value, "-l") == 0) {
201            SensorShowList(reply);
202            return HDF_SUCCESS;
203        } else if (strcmp(value, "-d") == 0) {
204            SensorShowData(reply);
205            return HDF_SUCCESS;
206        }
207    }
208
209    return HDF_SUCCESS;
210}
211
212void SensorDevRegisterDump(void)
213{
214    DevHostRegisterDumpHost(DevHostSensorDump);
215}
216