SELKIELogger  1.0.0
DWTypes.c
1 /*
2  * Copyright (C) 2023 Swansea University
3  *
4  * This file is part of the SELKIELogger suite of tools.
5  *
6  * SELKIELogger is free software: you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License as published by the Free
8  * Software Foundation, either version 3 of the License, or (at your option)
9  * any later version.
10  *
11  * SELKIELogger is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14  * more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with this SELKIELogger product.
18  * If not, see <http://www.gnu.org/licenses/>.
19 */
20 
21 #include <stddef.h>
22 #include <unistd.h>
23 
24 #include "DWTypes.h"
25 
34 bool hexpair_to_uint(const char *in, uint8_t *out) {
35  if (in == NULL || out == NULL) { return false; }
36 
37  uint8_t v = 0;
38  for (int i = 0; i < 2; i++) {
39  switch (in[i]) {
40  case '0':
41  case '1':
42  case '2':
43  case '3':
44  case '4':
45  case '5':
46  case '6':
47  case '7':
48  case '8':
49  case '9':
50  v += (in[i] - '0') << (4 * (1 - i));
51  break;
52  case 'a':
53  case 'b':
54  case 'c':
55  case 'd':
56  case 'e':
57  case 'f':
58  v += (in[i] - 'a' + 10) << (4 * (1 - i));
59  break;
60  case 'A':
61  case 'B':
62  case 'C':
63  case 'D':
64  case 'E':
65  case 'F':
66  v += (in[i] - 'A' + 10) << (4 * (1 - i));
67  break;
68  default:
69  (*out) = 0;
70  return false;
71  }
72  }
73  (*out) = v;
74  return true;
75 }
76 
92 bool dw_string_hxv(const char *in, size_t *end, dw_hxv *out) {
93  if (in == NULL || out == NULL || (*end) < 25) { return false; }
94 
95  ssize_t le = -1; // Line end
96  for (unsigned int i = 0; i < (*end); ++i) {
97  if (in[i] == '\r') {
98  le = i;
99  break;
100  }
101  }
102  if (le < 0) { return false; }
103 
104  // Work backwards from the carriage return
105  bool ret = true;
106  ret &= hexpair_to_uint(&(in[le - 24]), &(out->status));
107  ret &= hexpair_to_uint(&(in[le - 22]), &(out->lines));
108  ret &= hexpair_to_uint(&(in[le - 19]), &(out->data[0]));
109  ret &= hexpair_to_uint(&(in[le - 17]), &(out->data[1]));
110  ret &= hexpair_to_uint(&(in[le - 14]), &(out->data[2]));
111  ret &= hexpair_to_uint(&(in[le - 12]), &(out->data[3]));
112  ret &= hexpair_to_uint(&(in[le - 9]), &(out->data[4]));
113  ret &= hexpair_to_uint(&(in[le - 7]), &(out->data[5]));
114  ret &= hexpair_to_uint(&(in[le - 4]), &(out->data[6]));
115  ret &= hexpair_to_uint(&(in[le - 2]), &(out->data[7]));
116 
117  (*end) = ++le;
118  return ret;
119 }
bool hexpair_to_uint(const char *in, uint8_t *out)
Convert a string of hexadecimal characters to corresponding value.
Definition: DWTypes.c:34
bool dw_string_hxv(const char *in, size_t *end, dw_hxv *out)
Read a line of HXV data from string and convert.
Definition: DWTypes.c:92
Internal representation of a Datawell HXV message.
Definition: DWTypes.h:99
uint8_t data[8]
8 bytes of data
Definition: DWTypes.h:102
uint8_t status
Error count. 0 or 1 OK, 2+ error.
Definition: DWTypes.h:100
uint8_t lines
Transmitted line number.
Definition: DWTypes.h:101