8000 Merge af8c69088317c8e5cd51bf92d11a3f6705781f80 into 72fbc5801c30e4be0… · networkupstools/nut@840d782 · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Commit 840d782

Browse files
authored
Merge af8c690 into 72fbc58
2 parents 72fbc58 + af8c690 commit 840d782

File tree

7 files changed

+4589
-50
lines changed

7 files changed

+4589
-50
lines changed

drivers/Makefile.am

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -387,12 +387,15 @@ nutdrv_qx_CFLAGS += -DQX_USB
387387
nutdrv_qx_SOURCES += $(LIBUSB_IMPL) usb-common.c
388388
nutdrv_qx_LDADD += $(LIBUSB_LIBS)
389389
endif WITH_USB
390-
NUTDRV_QX_SUBDRIVERS = nutdrv_qx_bestups.c nutdrv_qx_blazer-common.c \
390+
NUTDRV_QX_SUBDRIVERS = \
391+
nutdrv_qx_bestups.c nutdrv_qx_blazer-common.c \
391392
nutdrv_qx_innovart31.c \
392393
nutdrv_qx_masterguard.c \
393394
nutdrv_qx_mecer.c nutdrv_qx_megatec.c nutdrv_qx_megatec-old.c \
394-
nutdrv_qx_mustek.c nutdrv_qx_q1.c nutdrv_qx_q2.c nutdrv_qx_q6.c nutdrv_qx_voltronic.c \
395-
nutdrv_qx_voltronic-qs.c nutdrv_qx_voltronic-qs-hex.c nutdrv_qx_zinto.c \
395+
nutdrv_qx_mustek.c nutdrv_qx_q1.c nutdrv_qx_q2.c nutdrv_qx_q6.c \
396+
nutdrv_qx_voltronic.c common_voltronic-crc.c \
397+
nutdrv_qx_voltronic-axpert.c nutdrv_qx_voltronic-qs.c nutdrv_qx_voltronic-qs-hex.c \
398+
nutdrv_qx_zinto.c \
396399
nutdrv_qx_hunnox.c nutdrv_qx_ablerex.c nutdrv_qx_gtec.c
397400
nutdrv_qx_SOURCES += $(NUTDRV_QX_SUBDRIVERS)
398401

@@ -413,10 +416,13 @@ dist_noinst_HEADERS = \
413416
safenet.h serial.h sms_ser.h snmp-ups.h solis.h tripplite.h tripplite-hid.h \
414417
upshandler.h usb-common.h usbhid-ups.h powercom-hid.h compaq-mib.h idowell-hid.h \
415418
apcsmart.h apcsmart_tabs.h apcsmart-old.h apcupsd-ups.h cyberpower-mib.h riello.h openups-hid.h \
416-
delta_ups-mib.h nutdrv_qx.h nutdrv_qx_bestups.h nutdrv_qx_blazer-common.h \
419+
delta_ups-mib.h \
420+
nutdrv_qx_bestups.h nutdrv_qx_blazer-common.h \
417421
nutdrv_qx_gtec.h nutdrv_qx_innovart31.h nutdrv_qx_masterguard.h nutdrv_qx_mecer.h nutdrv_qx_ablerex.h \
418422
nutdrv_qx_megatec.h nutdrv_qx_megatec-old.h nutdrv_qx_mustek.h nutdrv_qx_q1.h nutdrv_qx_q2.h nutdrv_qx_q6.h nutdrv_qx_hunnox.h \
419-
nutdrv_qx_voltronic.h nutdrv_qx_voltronic-qs.h nutdrv_qx_voltronic-qs-hex.h nutdrv_qx_zinto.h \
423+
nutdrv_qx.h common_voltronic-crc.h nutdrv_qx_voltronic.h \
424+
nutdrv_qx_voltronic-axpert.h nutdrv_qx_voltronic-qs.h nutdrv_qx_voltronic-qs-hex.h \
425+
nutdrv_qx_zinto.h \
420426
upsdrvquery.h \
421427
xppc-mib.h huawei-mib.h eaton-ats16-nmc-mib.h eaton-ats16-nm2-mib.h apc-ats-mib.h raritan-px2-mib.h eaton-ats30-mib.h \
422428
apc-pdu-mib.h apc-epdu-mib.h ecoflow-hid.h ever-hid.h eaton-pdu-genesis2-mib.h eaton-pdu-marlin-mib.h eaton-pdu-marlin-helpers.h \

drivers/common_voltronic-crc.c

Lines changed: 291 additions & 0 deletions
< 10000 td data-grid-cell-id="diff-cfcaa8dd3705d59ca49f39e947a95c222109f68e85a8cb92f022d2da22a4bce8-empty-136-0" data-selected="false" role="gridcell" style="background-color:var(--diffBlob-additionNum-bgColor, var(--diffBlob-addition-bgColor-num));text-align:center" tabindex="-1" valign="top" class="focusable-grid-cell diff-line-number position-relative left-side">
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,291 @@
1+
/* common_voltronic-crc.c - Common CRC routines for Voltronic Power devices
2+
*
3+
* Copyright (C)
4+
* 2014 Daniele Pezzini <hyouko@gmail.com>
5+
*
6+
* This program is free software; you can redistribute it and/or modify
7+
* it under the terms of the GNU General Public License as published by
8+
* the Free Software Foundation; either version 2 of the License, or
9+
* (at your option) any later version.
10+
*
11+
* This program is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU General Public License
17+
* along with this program; if not, write to the Free Software
18+
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19+
*
20+
*/
21+
22+
#include "common_voltronic-crc.h"
23+
24+
/* CRC table - filled at runtime by common_voltronic_crc_init() */
25+
static unsigned short crc_table[256];
26+
27+
/* Flag (0/1) just to be sure all is properly initialized */
28+
static int initialized = 0;
29+
30+
/* Fill CRC table: this function MUST be called before anything else that needs to perform CRC operations */
31+
static void common_voltronic_crc_init(void)
32+
{
33+
unsigned short dividend;
34+
35+
/* Already been here */
36+
if (initialized)
37+
return;
38+
39+
/* Compute remainder of each possible dividend */
40+
for (dividend = 0; dividend < 256; dividend++) {
41+
42+
unsigned short bit;
43+
/* Start with dividend followed by zeros */
44+
unsigned long remainder = dividend << 8;
45+
46+
/* Modulo 2 division, a bit at a time */
47+
for (bit = 0; bit < 8; bit++)
48+
/* Try to divide the current data bit */
49+
if (remainder & 0x8000)
50+
remainder = (remainder << 1) ^ 0x1021;
51+
else
52+
remainder <<= 1;
53+
54+
/* Store the result into the table */
55+
crc_table[dividend] = remainder & 0xffff;
56+
57+
}
58+
59+
/* Ready, now */
60+
initialized = 1;
61+
}
62+
63+
/* See header file for details */
64+
unsigned short common_voltronic_crc_compute(const char *input, const size_t len)
65+
{
66+
unsigned short crc, crc_MSB, crc_LSB;
67+
unsigned long remainder = 0;
68+
size_t byte;
69+
70+
/* Make sure all is ready */
71+
if (!initialized)
72+
common_voltronic_crc_init();
73+
74+
/* Divide *input* by the polynomial, a byte at a time */
75+
for (byte = 0; byte < len; byte++)
76+
remainder = (remainder << 8) ^ crc_table[(input[byte] ^ (remainder >> 8)) & 0xff];
77+
78+
/* The final remainder is the CRC */
79+
crc = remainder & 0xffff;
80+
81+
/* Escape characters with a special meaning */
82+
83+
crc_MSB = (crc >> 8) & 0xff;
84+
if (
85+
crc_MSB == 10 || /* LF */
86+
crc_MSB == 13 || /* CR */
87+
crc_MSB == 40 /* ( */
88+
)
89+
crc_MSB++;
90+
91+
crc_LSB = crc & 0xff;
92+
if (
93+
crc_LSB == 10 || /* LF */
94+
crc_LSB == 13 || /* CR */
95+
crc_LSB == 40 /* ( */
96+
)
97+
crc_LSB++;
98+
99+
crc = ((crc_MSB & 0xff) << 8) + crc_LSB;
100+
101+
return crc;
102+
}
103+
104+
/* See header file for details */
105+
unsigned short common_voltronic_crc_calc(const char *input, const size_t inputlen)
106+
{
107+
size_t len;
108+
char *cr = memchr(input, '\r', inputlen);
109+
110+
/* No CR, fall back to string length (and hope *input* doesn't contain inner '\0's) */
111+
if (cr == NULL)
112+
len = strlen(input);
113+
else
114+
len = cr - input;
115+
116+
/* At least 1 byte expected */
117+
if (!len)
118+
return -1;
119+
120+
/* Compute (and return) CRC */
121+
return common_voltronic_crc_compute(input, len);
122+
}
123+
124+
/* See header file for details */
125+
int common_voltronic_crc_calc_and_add(const char *input, const size_t inputlen, char *output, const size_t outputlen)
126+
{
127+
unsigned short crc, crc_MSB, crc_LSB;
128+
size_t len;
129+
char *cr = memchr(input, '\r', inputlen);
130+
131+
/* No CR, fall back to string length (and hope *input* doesn't contain inner '\0's) */
132+
if (cr == NULL)
133+
len = strlen(input);
134+
else
135+
len = cr - input;
136+
137+
/* At least 1 byte expected */
138+
if (!len)
139+
return -1;
140+
141+
/* To accomodate CRC, *output* must have space for at least 2 bytes more than the actually used size of *input*.
142+
* Also, pretend that *input* is a valid null-terminated string and so reserve the final byte in *output* for the terminating '\0'. */
143+
if (
144+
(cr == NULL && outputlen < len + 3) || /* 2-bytes CRC + 1 byte for terminating '\0' */
145+
(cr != NULL && outputlen < len + 4) /* 2-bytes CRC + 1 byte for trailing CR + 1 byte for terminating '\0' */
146+
)
147+
return -1;
148+
149+
/* Compute CRC */
150+
crc = common_voltronic_crc_compute(input, len);
151+
crc_MSB = (crc >> 8) & 0xff;
152+
crc_LSB = crc & 0xff;
153+
154+
/* Clear *output* */
155+
memset(output, 0, outputlen);
156+
157+
/* Copy *input* to *output* */
158+
memcpy(output, input, len);
159+
160+
/* Write CRC to *output* */
161+
output[len++] = crc_MSB;
162+
output[len++] = crc_LSB;
163+
164+
/* Reinstate the trailing CR in *output*, if appropriate */
165+
if (cr != NULL)
166+
output[len++] = '\r';
167+
168+
return (int)len;
169+
}
170+
171+
/* See header file for details */
172+
int common_voltronic_crc_calc_and_add_m(char *input, const size_t inputlen)
173+
{
174+
int len;
175+
char buf[inputlen];
176+
177+
/* Compute CRC and copy *input*, with CRC added to it, to buf */
178+
len = common_voltronic_crc_calc_and_add(input, inputlen, buf, inputlen);
179+
180+
/* Failed */
181+
if (len == -1)
182+
return -1;
183+
184+
/* Successfully computed CRC and copied *input*, with CRC added to it, to buf */
185+
186+
/* Clear *input* */
187+
memset(input, 0, inputlen);
188+
189+
/* Copy back buf to *input* */
190+
memcpy(input, buf, len);
191+
192+
return len;
193+
}
194+
195+
/* See header file for details */
196+
int common_voltronic_crc_check(const char *input, const size_t inputlen)
197+
{
198+
unsigned short crc, crc_MSB, crc_LSB;
199+
char *cr = memchr(input, '\r', inputlen);
200+
size_t len;
201+
202+
/* No CR, fall back to string length (and hope *input* doesn't contain inner '\0's) */
203+
if (cr == NULL)
204+
len = strlen(input);
205+
else
206+
len = cr - input;
207+
208+
/* Minimum length: 1 byte + 2 bytes CRC -> 3 */
209+
if (len < 3)
210+
return -1;
211+
212+
/* Compute CRC */
213+
crc = common_voltronic_crc_compute(input, len - 2);
214+
crc_MSB = (crc >> 8) & 0xff;
215+
crc_LSB = crc & 0xff;
216+
217+
/* Fail */
218+
if (
219+
crc_MSB != (unsigned char)input[len - 2] ||
220+
crc_LSB != (unsigned char)input[len - 1]
221+
)
222+
return -1;
223+
224+
/* Success */
225+
return 0;
226+
}
227+
228+
/* See header file for details */
229+
int common_voltronic_crc_check_and_remove(const char *input, const size_t inputlen, char *output, const size_t outputlen)
230+
{
231+
char *cr;
232+
size_t len;
233+
234+
/* Failed to check *input* CRC */
235+
if (common_voltronic_crc_check(input, inputlen))
236+
return -1;
237+
238+
/* *input* successfully validated -> remove CRC bytes */
239+
240+
cr = memchr(input, '\r', inputlen);
241+
/* No CR, fall back to string length */
242+
if (cr == NULL)
243+
len = strlen(input);
244+
else
245+
len = cr - input;
246+
247+
/* *output* must have space for at least 2 bytes less than the actually used size of *input*.
248+
* Also, pretend that *input* is a valid null-terminated string and so reserve the final byte in *output* for the terminating '\0'. */
249+
len -= 2; /* Consider 2-bytes CRC length */
250+
if (
251+
(cr == NULL && outputlen < len + 1) || /* 1 byte for terminating '\0' */
252+
(cr != NULL && outputlen < len + 2) /* 1 byte for terminating '\0' + 1 byte for trailing CR; 2-byte CRC */
253+
)
254+
return -1;
255+
256+
/* Clear *output* */
257+
memset(output, 0, outputlen);
258+
259+
/* Copy *input* to *output* */
260+
memcpy(output, input, len);
261+
262+
/* Reinstate the trailing CR in *output*, if appropriate */
263+
if (cr != NULL)
264+
output[len++] = '\r';
265+
266+
return (int)len;
267+
}
268+
269+
/* See header file for details */
270+
int common_voltronic_crc_check_and_remove_m(char *input, const size_t inputlen)
271+
{
272+
int len;
273+
char buf[inputlen];
274+
275+
/* Check CRC and copy *input*, purged of the CRC, to buf */
276+
len = common_voltronic_crc_check_and_remove(input, inputlen, buf, inputlen);
277+
278+
/* Failed */
279+
if (len == -1)
280+
return -1;
281+
282+
/* Successfully checked CRC and copied *input*, purged of the CRC, to buf */
283+
284+
/* Clear *input* */
285+
memset(input, 0, inputlen);
286+
287+
/* Copy back buf to *input* */
288+
memcpy(input, buf, len);
289+
290+
return len;
291+
}

0 commit comments

Comments
 (0)
0