Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#
# SPDX-License-Identifier: BSD-3-Clause

cmake_minimum_required(VERSION 3.2.0)
cmake_minimum_required(VERSION 3.2...3.31)
project(vcontrold C)

if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
Expand Down
2 changes: 1 addition & 1 deletion doc/man/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
# Generate classic *roff manual pages from ReStructuredText.
# This requires Python's Docutils (http://docutils.sourceforge.net/)

cmake_minimum_required(VERSION 3.2.0)
cmake_minimum_required(VERSION 3.2...3.31)

set(RST2MAN_OPTS)

Expand Down
189 changes: 162 additions & 27 deletions src/unit.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,32 +67,94 @@ int getErrState(enumPtr ePtr, char *recv, int len, char *result);
int getSysTime(char *recv, int len, char *result);
int setSysTime(char *input, char *sendBuf);

int getCycleTime(char *recv, int len, char *result)
static int parseCycleTimeToken(const char *token, unsigned char emptyValue, unsigned char *value)
{
int i;
char string[80];
unsigned int hour, min;
char tail;

if ((strcmp(token, "-") == 0) || (strcmp(token, "--") == 0)) {
*value = emptyValue;
return 1;
}

if (len % 2) {
sprintf(result, "Byte count not even");
if (strchr(token, ':') == NULL) {
return 0;
}

memset(string, 0, sizeof(string));
if (sscanf(token, "%u:%u%c", &hour, &min, &tail) != 2) {
return 0;
}

for (i = 0; i < len; i += 2) {
// TODO - vitoopen: Leave output in German.
// CHANGING THIS WOULD BREAK existing applications.
// => maybe we could enable english results later with a build option,
// but not for the default.
if (recv[i] == (char)0xff) {
snprintf(string, sizeof(string), "%d:An:-- Aus:--\n", (i / 2) + 1);
} else {
snprintf(string, sizeof(string), "%d:An:%02d:%02d Aus:%02d:%02d\n", (i / 2) + 1,
(recv[i] & 0xF8) >> 3, (recv[i] & 7) * 10,
(recv[i + 1] & 0xF8) >> 3, (recv[i + 1] & 7) * 10);
if ((hour > 24) || (min > 59) || ((min % 10) != 0)) {
return 0;
}

*value = ((hour << 3) + (min / 10)) & 0xff;

return 1;
}

int getCycleTime(char *recv, int len, char *result)
{
int i;
char string[256];
char onTime[8];
char offTime[8];

memset(string, 0, sizeof(string));
memset(onTime, 0, sizeof(onTime));
memset(offTime, 0, sizeof(offTime));

if(len == 8) {
for (i = 0; i < len; i += 2) {
// TODO - vitoopen: Leave output in German.
// CHANGING THIS WOULD BREAK existing applications.
// => maybe we could enable english results later with a build option,
// but not for the default.
if (recv[i] == (char)0xff) {
snprintf(string, sizeof(string), "%d:An:-- Aus:--\n", (i / 2) + 1);
} else {
snprintf(string, sizeof(string), "%d:An:%02d:%02d Aus:%02d:%02d\n", (i / 2) + 1,
(recv[i] & 0xF8) >> 3, (recv[i] & 7) * 10,
(recv[i + 1] & 0xF8) >> 3, (recv[i + 1] & 7) * 10);
}
strcat(result, string);
}
strcat(result, string);
} else if(len == 15) {
for (i = 0; i < len; i += 3) {
// TODO - vitoopen: Leave output in German.
// CHANGING THIS WOULD BREAK existing applications.
// => maybe we could enable english results later with a build option,
// but not for the default.
if ((recv[i] == (char)0x00) && (recv[i + 1] == (char)0x00)) {
snprintf(string, sizeof(string), "%d:An:-- Aus:-- Mod:--\n", (i / 3) + 1);
strcat(result, string);
continue;
}

if (recv[i] == (char)0x00) {
snprintf(onTime, sizeof(onTime), "--");
} else {
snprintf(onTime, sizeof(onTime), "%02d:%02d",
(recv[i] & 0xF8) >> 3, (recv[i] & 7) * 10);
}

if (recv[i + 1] == (char)0x00) {
snprintf(offTime, sizeof(offTime), "--");
} else {
snprintf(offTime, sizeof(offTime), "%02d:%02d",
(recv[i + 1] & 0xF8) >> 3, (recv[i + 1] & 7) * 10);
}

snprintf(string, sizeof(string), "%d:An:%-5s Aus:%-5s Mod:%02d\n", (i / 3) + 1,
onTime, offTime, (recv[i + 2] & 0x7F));
strcat(result, string);
}
} else {
sprintf(result, "Byte count not 8 or 15");
return 0;
}

result[strlen(result) - 1] = '\0'; // remove \n

return 1;
Expand All @@ -102,20 +164,85 @@ int setCycleTime(char *input, char *sendBuf)
{
char *sptr, *cptr;
char *bptr = sendBuf;
int hour, min;
char *tokens[16];
char *endptr;
long modeValue;
unsigned char timeValue;
int idx = 0;
int tokenCount = 0;
int count = 0;

// We split at the blank
sptr = strtok(input, " ");
cptr = NULL;

while ((sptr != NULL) && (tokenCount < 16)) {
tokens[tokenCount++] = sptr;
sptr = strtok(NULL, " ");
}

if (tokenCount == 15) {
memset(sendBuf, 0x00, 15);

for (count = 0; count < 15; count += 3) {
if (!parseCycleTimeToken(tokens[count], 0x00, &timeValue)) {
sprintf(sendBuf, "Wrong time format: %s", tokens[count]);
return 0;
}
sendBuf[count] = timeValue;
logIT(LOG_INFO, "Cycle Time: %s -> [%02X]", tokens[count], timeValue);

if (!parseCycleTimeToken(tokens[count + 1], 0x00, &timeValue)) {
sprintf(sendBuf, "Wrong time format: %s", tokens[count + 1]);
return 0;
}
sendBuf[count + 1] = timeValue;
logIT(LOG_INFO, "Cycle Time: %s -> [%02X]", tokens[count + 1], timeValue);

if ((sendBuf[count] == 0x00) && (sendBuf[count + 1] == 0x00)) {
if ((strcmp(tokens[count + 2], "-") != 0) && (strcmp(tokens[count + 2], "--") != 0)) {
sprintf(sendBuf, "Wrong empty block format: %s %s %s",
tokens[count], tokens[count + 1], tokens[count + 2]);
return 0;
}
sendBuf[count + 2] = 0x00;
logIT(LOG_INFO, "Cycle Mode: %s -> [%02X]", tokens[count + 2], sendBuf[count + 2]);
continue;
}

if ((strcmp(tokens[count + 2], "-") == 0) || (strcmp(tokens[count + 2], "--") == 0)) {
sprintf(sendBuf, "Wrong mode format: %s", tokens[count + 2]);
return 0;
}

errno = 0;
modeValue = strtol(tokens[count + 2], &endptr, 0);
if ((errno != 0) || (*tokens[count + 2] == '\0') || (*endptr != '\0') ||
(modeValue < 0) || (modeValue > 0xff)) {
sprintf(sendBuf, "Wrong mode format: %s", tokens[count + 2]);
return 0;
}
sendBuf[count + 2] = (unsigned char)modeValue;
logIT(LOG_INFO, "Cycle Mode: %s -> [%02X]", tokens[count + 2], sendBuf[count + 2]);
}

return 15;
}

// First, we fill the sendBuf with 8 x ff
for (count = 0; count < 8; sendBuf[count++] = 0xff);
count = 0;

do {
if (tokenCount == 0) {
return 8;
}

while (idx < tokenCount) {
sptr = tokens[idx];

if (sptr < cptr) {
// We already have been here (by double blanks)
idx++;
continue;
}

Expand All @@ -127,23 +254,31 @@ int setCycleTime(char *input, char *sendBuf)
// We skip the next time designation, as it also must be a "-"
bptr++;
count++;
sptr = strtok(NULL, " ");
idx++;
if (idx < tokenCount) {
cptr = tokens[idx];
} else {
cptr = sptr;
}
logIT(LOG_INFO, "Cycle Time: -- -- -> [%02X%02X]", 0xff, 0xff);
} else {
// Is the a : in the string?
if (! strchr(sptr, ':')) {
sprintf(sendBuf, "Wrong time format: %s", sptr);
return 0;
}
sscanf(sptr, "%u:%u", &hour, &min);
*bptr = ((hour << 3) + (min / 10)) & 0xff;
logIT(LOG_INFO, "Cycle Time: %02d:%02d -> [%02X]", hour, min, (unsigned char) *bptr);
if (!parseCycleTimeToken(sptr, 0xff, &timeValue)) {
sprintf(sendBuf, "Wrong time format: %s", sptr);
return 0;
}
*bptr = timeValue;
logIT(LOG_INFO, "Cycle Time: %s -> [%02X]", sptr, (unsigned char) *bptr);
cptr = sptr;
}
bptr++;
cptr = sptr;
count++;

} while ((sptr = strtok(NULL, " ")) != NULL);
idx++;
}

if ((count / 2) * 2 != count) {
logIT(LOG_WARNING, "Times count odd, ignoring %s", cptr);
Expand Down
Loading