1 /* Copyright 2023 Unionman Technology Co., Ltd.
2 *
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
17 #include <cstdio>
18 #include <unistd.h>
19 #include <cstring>
20 #include <string>
21 #include <sys/epoll.h>
22 #include <sys/select.h>
23 #include "serial_uart.h"
24 #include "hilog/log.h"
25 #include "napi/native_api.h"
26 #include "napi/native_node_api.h"
27
28 constexpr int baud_rate = 9600;
29 static int fd = -1;
30 static int epfd = -1;
31 static int init_flag = 0;
32 constexpr int OPENERR = -1;
33 constexpr int INITERR = -2;
34 constexpr int FRAME_LEN = 4;
35 const char UART_TTL_NAME[] = "/dev/ttyS1";
36
uart_init_napi(napi_env env,napi_callback_info info)37 static napi_value uart_init_napi(napi_env env, napi_callback_info info)
38 {
39 napi_value ret = nullptr;
40 NAPI_CALL(env, napi_create_int32(env, 0, &ret));
41 if (init_flag) {
42 HILOG_INFO(LOG_CORE, "already init");
43 return ret;
44 }
45
46 const char *uart_dev = UART_TTL_NAME;
47 fd = open(uart_dev, O_RDWR);
48 if (fd == -1) {
49 HILOG_DEBUG(LOG_CORE, "open file error");
50 NAPI_CALL(env, napi_create_int32(env, OPENERR, &ret));
51 return ret;
52 }
53 if ((uart_init(fd, baud_rate)) == -1) {
54 close(fd);
55 fd = -1;
56 HILOG_DEBUG(LOG_CORE, "uart init error");
57 NAPI_CALL(env, napi_create_int32(env, INITERR, &ret));
58 return ret;
59 }
60
61 struct epoll_event ev;
62 ev.events = EPOLLIN;
63 ev.data.fd = fd;
64 epfd = epoll_create(1);
65 epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev);
66
67 init_flag = 1;
68
69 return ret;
70 }
71
uart_close_napi(napi_env env,napi_callback_info info)72 static napi_value uart_close_napi(napi_env env, napi_callback_info info)
73 {
74 napi_value ret = nullptr;
75 NAPI_CALL(env, napi_create_int32(env, 0, &ret));
76 if (!init_flag) {
77 HILOG_INFO(LOG_CORE, "Not initialized yet");
78 return ret;
79 }
80 close(epfd);
81 epfd = -1;
82 close(fd);
83 fd = -1;
84 init_flag = 0;
85 return ret;
86 }
87
dataProcecc(int data)88 static std::string dataProcecc(int data)
89 {
90 std::string sensor_respond;
91 switch (data) {
92 case 0x01:
93 sensor_respond="手势识别为向右";
94 break;
95 case 0x02:
96 sensor_respond="手势识别为向左";
97 break;
98 case 0x03:
99 sensor_respond="手势识别为向后";
100 break;
101 case 0x04:
102 sensor_respond="手势识别为向前";
103 break;
104 case 0x05:
105 sensor_respond="手势识别为上拉";
106 break;
107 case 0x06:
108 sensor_respond="手势识别为下压";
109 break;
110 case 0x07:
111 sensor_respond="手势识别为上拉下压后松开";
112 break;
113 case 0x21:
114 sensor_respond="触摸点1";
115 break;
116 case 0x22:
117 sensor_respond="触摸点2";
118 break;
119 case 0x23:
120 sensor_respond="触摸点3";
121 break;
122 case 0x24:
123 sensor_respond="触摸点4";
124 break;
125 case 0x25:
126 sensor_respond="触摸点5";
127 break;
128 default:
129 sensor_respond="数据错误";
130 break;
131 }
132 return sensor_respond;
133 }
134
dataRec(int * data)135 static bool dataRec(int *data)
136 {
137 for (int i = 0; i < FRAME_LEN; i++) {
138 if ((read(fd, (data + i), 1)) == -1) {
139 HILOG_DEBUG(LOG_CORE, "Read err, read() failed");
140 return false;
141 }
142 }
143 return true;
144 }
145
146
uart_read_napi(napi_env env,napi_callback_info info)147 static napi_value uart_read_napi(napi_env env, napi_callback_info info)
148 {
149 napi_value respond_napi = nullptr;
150 std::string sensor_respond;
151 if (!init_flag) {
152 HILOG_DEBUG(LOG_CORE, "Read error, uart not initialized");
153 sensor_respond="notinit";
154 NAPI_CALL(env, napi_create_string_utf8(env, sensor_respond.c_str(), sensor_respond.length(),
155 &respond_napi));
156 return respond_napi;
157 }
158 struct epoll_event event_list[1];
159 int nfds = 0; // number of file descriptors
160 int recv[4] = {0};
161 sensor_respond="nodata";
162 NAPI_CALL(env, napi_create_string_utf8(env, sensor_respond.c_str(), sensor_respond.length(), &respond_napi));
163 if ((nfds = epoll_wait(epfd, event_list, FRAME_LEN, 0))) {
164 for (int i = 0; i < nfds; i++) {
165 bzero(recv, sizeof(recv));
166 if (!dataRec(recv)) {
167 return respond_napi;
168 }
169 }
170 sensor_respond = dataProcecc(recv[1]);
171 NAPI_CALL(env, napi_create_string_utf8(env, sensor_respond.c_str(), sensor_respond.length(), &respond_napi));
172 return respond_napi;
173 }
174 return respond_napi; // 没拿到数据返回"nodata"
175 }
176
registerUartnapi(napi_env env,napi_value exports)177 static napi_value registerUartnapi(napi_env env, napi_value exports)
178 {
179 napi_property_descriptor desc[] = {
180 DECLARE_NAPI_FUNCTION("uart_init_napi", uart_init_napi),
181 DECLARE_NAPI_FUNCTION("uart_close_napi", uart_close_napi),
182 DECLARE_NAPI_FUNCTION("uart_read_napi", uart_read_napi)
183 };
184 NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));
185 return exports;
186 }
187
188 /*
189 * 模块定义
190 */
191 static napi_module uartnapiModule = {
192 .nm_version = 1,
193 .nm_flags = 0,
194 .nm_filename = nullptr,
195 .nm_register_func = registerUartnapi,
196 .nm_modname = "uart_napi", // 模块名
197 .nm_priv = ((void *) 0),
198 .reserved = {0},
199 };
200
201 /*
202 * 注册模块 __attribute__标记用于在加载库时自动注册
203 */
RegisterUartnapiModule(void)204 extern "C" __attribute__((constructor)) void RegisterUartnapiModule(void)
205 {
206 napi_module_register(&uartnapiModule); // 接口注册函数
207 }