Skip to content

Commit a03adc9

Browse files
committed
Move command parsing into cmd.c
1 parent 4a165cb commit a03adc9

File tree

3 files changed

+207
-69
lines changed

3 files changed

+207
-69
lines changed

src/cmd.c

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
/**
2+
@file cmd.c
3+
@brief Network Command Parsing Module
4+
5+
This module handles parsing of commands received over network protocols
6+
(UDP/TCP) for the Process Watchdog application. It provides functions to
7+
parse and identify different types of network commands.
8+
9+
@date 2023-01-01
10+
@version 1.0
11+
@author by Eray Ozturk | [email protected]
12+
@url github.com/diffstorm
13+
@license GPL-3 License
14+
*/
15+
16+
#include "cmd.h"
17+
#include "log.h"
18+
#include "utils.h"
19+
20+
#include <stdio.h>
21+
#include <stdlib.h>
22+
#include <stdbool.h>
23+
#include <string.h>
24+
#include <limits.h>
25+
26+
//------------------------------------------------------------------
27+
// Public interface functions
28+
//------------------------------------------------------------------
29+
30+
net_command_t cmd_parse_network(const char* data, int length)
31+
{
32+
net_command_t cmd = {0};
33+
cmd.type = NET_CMD_UNKNOWN;
34+
cmd.pid = 0;
35+
cmd.app_name[0] = '\0';
36+
37+
if (!data || length <= 0) {
38+
return cmd;
39+
}
40+
41+
switch(data[0])
42+
{
43+
case 'p': // pid heartbeat : p<pid> ? p1234
44+
{
45+
int n = parse_number(data, length, NULL);
46+
LOGD("Heartbeat command received from pid %d : %s", n, data);
47+
48+
if(0 < n && INT32_MAX > n)
49+
{
50+
cmd.type = NET_CMD_HEARTBEAT;
51+
cmd.pid = n;
52+
}
53+
else
54+
{
55+
LOGE("Invalid pid received, pid %d : %s", n, data);
56+
cmd.type = NET_CMD_UNKNOWN;
57+
}
58+
}
59+
break;
60+
61+
case 'a': // stArt : a<name> ? aBot (currently disabled)
62+
{
63+
LOGD("Start command received: %s", data);
64+
cmd.type = NET_CMD_START;
65+
strncpy(cmd.app_name, &data[1], MAX_APP_NAME_LENGTH - 1);
66+
cmd.app_name[MAX_APP_NAME_LENGTH - 1] = '\0';
67+
}
68+
break;
69+
70+
case 'o': // stOp : o<name> ? oBot (currently disabled)
71+
{
72+
LOGD("Stop command received: %s", data);
73+
cmd.type = NET_CMD_STOP;
74+
strncpy(cmd.app_name, &data[1], MAX_APP_NAME_LENGTH - 1);
75+
cmd.app_name[MAX_APP_NAME_LENGTH - 1] = '\0';
76+
}
77+
break;
78+
79+
case 'r': // Restart : r<name> ? rBot (currently disabled)
80+
{
81+
LOGD("Restart command received: %s", data);
82+
cmd.type = NET_CMD_RESTART;
83+
strncpy(cmd.app_name, &data[1], MAX_APP_NAME_LENGTH - 1);
84+
cmd.app_name[MAX_APP_NAME_LENGTH - 1] = '\0';
85+
}
86+
break;
87+
88+
default:
89+
{
90+
const int max_bytes = MAX_APP_NAME_LENGTH;
91+
const int max_length = max_bytes * 3;
92+
char hexStr[max_length];
93+
memset(hexStr, 0, sizeof(hexStr));
94+
95+
int safe_length = length;
96+
if (safe_length > max_bytes) {
97+
safe_length = max_bytes;
98+
}
99+
100+
for (int i = 0; i < safe_length; i++) {
101+
snprintf(&hexStr[i * 3], sizeof(hexStr) - (i * 3), "%02X ", data[i]);
102+
}
103+
104+
char printableStr[max_bytes + 1];
105+
memset(printableStr, 0, sizeof(printableStr));
106+
for (int i = 0; i < safe_length; i++) {
107+
printableStr[i] = (data[i] >= 32 && data[i] < 127) ? data[i] : '.';
108+
}
109+
110+
LOGE("Unknown command received : %s | %s", printableStr, hexStr);
111+
cmd.type = NET_CMD_UNKNOWN;
112+
}
113+
break;
114+
}
115+
116+
return cmd;
117+
}

src/cmd.h

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/**
2+
@file cmd.h
3+
@brief Network Command Parsing Module
4+
5+
This module handles parsing of commands received over network protocols
6+
(UDP/TCP) for the Process Watchdog application. It provides functions to
7+
parse and identify different types of network commands.
8+
9+
@date 2023-01-01
10+
@version 1.0
11+
@author by Eray Ozturk | [email protected]
12+
@url github.com/diffstorm
13+
@license GPL-3 License
14+
*/
15+
16+
#ifndef CMD_H
17+
#define CMD_H
18+
19+
#include <stdbool.h>
20+
21+
// Include apps.h for MAX_APP_NAME_LENGTH constant
22+
#include "apps.h"
23+
24+
/**
25+
@enum net_command_type_t
26+
@brief Enumeration of network command types.
27+
*/
28+
typedef enum {
29+
NET_CMD_HEARTBEAT, /**< Heartbeat command: p<pid> */
30+
NET_CMD_START, /**< Start command: a<name> (future) */
31+
NET_CMD_STOP, /**< Stop command: o<name> (future) */
32+
NET_CMD_RESTART, /**< Restart command: r<name> (future) */
33+
NET_CMD_UNKNOWN /**< Unknown or invalid command */
34+
} net_command_type_t;
35+
36+
/**
37+
@struct net_command_t
38+
@brief Structure representing a parsed network command.
39+
*/
40+
typedef struct {
41+
net_command_type_t type; /**< Type of the command */
42+
int pid; /**< Process ID for heartbeat commands */
43+
char app_name[MAX_APP_NAME_LENGTH]; /**< Application name for control commands */
44+
} net_command_t;
45+
46+
/**
47+
@brief Parses network command data and returns a structured command.
48+
49+
This function parses raw command data received over network protocols
50+
and returns a structured representation of the command.
51+
52+
@param data Pointer to the command data.
53+
@param length Length of the command data.
54+
@return Parsed network command structure.
55+
*/
56+
net_command_t cmd_parse_network(const char* data, int length);
57+
58+
#endif // CMD_H

src/main.c

Lines changed: 32 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "filecmd.h"
2424
#include "stats.h"
2525
#include "test.h"
26+
#include "cmd.h"
2627
#include "log.h"
2728
#include "utils.h"
2829

@@ -38,56 +39,46 @@
3839

3940
void parse_commands(char *data, int length)
4041
{
41-
switch(data[0])
42+
// Use command module to parse the network command
43+
net_command_t cmd = cmd_parse_network(data, length);
44+
45+
// Handle the parsed command based on its type
46+
switch(cmd.type)
4247
{
43-
case 'p': // pid heartbeat : p<pid> ? p1234
48+
case NET_CMD_HEARTBEAT:
4449
{
45-
int n = parse_number(data, length, NULL);
46-
LOGD("Heartbeat command received from pid %d : %s", n, data);
50+
int i = find_pid(cmd.pid);
4751

48-
if(0 < n && INT32_MAX > n)
52+
if(i >= 0)
4953
{
50-
int i = find_pid(n);
54+
time_t t = get_heartbeat_time(i);
5155

52-
if(i >= 0)
56+
if(get_first_heartbeat(i))
5357
{
54-
time_t t = get_heartbeat_time(i);
55-
56-
if(get_first_heartbeat(i))
57-
{
58-
if(t >= 0)
59-
{
60-
LOGD("%s heartbeat after %d seconds", get_app_name(i), t);
61-
stats_update_heartbeat_time(i, t);
62-
}
63-
}
64-
else
58+
if(t >= 0)
6559
{
66-
LOGD("%s first heartbeat after %d seconds", get_app_name(i), t);
67-
stats_update_first_heartbeat_time(i, t);
68-
set_first_heartbeat(i);
60+
LOGD("%s heartbeat after %d seconds", get_app_name(i), t);
61+
stats_update_heartbeat_time(i, t);
6962
}
70-
71-
update_heartbeat_time(i);
7263
}
73-
}
74-
else
75-
{
76-
LOGE("Invalid pid received, pid %d : %s", n, data);
64+
else
65+
{
66+
LOGD("%s first heartbeat after %d seconds", get_app_name(i), t);
67+
stats_update_first_heartbeat_time(i, t);
68+
set_first_heartbeat(i);
69+
}
70+
71+
update_heartbeat_time(i);
7772
}
7873
}
7974
break;
80-
#if 0 // feature disabled
8175

82-
case 'a': // stArt : a<name> ? aBot
76+
#if 0 // feature disabled
77+
case NET_CMD_START:
8378
{
84-
LOGD("Start command received: %s", data);
85-
char name[MAX_APP_NAME_LENGTH];
86-
strncpy(name, &data[1], MAX_APP_NAME_LENGTH - 1);
87-
8879
for(int i = 0; i < get_app_count(); i++)
8980
{
90-
if(0 == strncmp(get_app_name(i), name, MAX_APP_NAME_LENGTH - 1))
81+
if(0 == strncmp(get_app_name(i), cmd.app_name, MAX_APP_NAME_LENGTH - 1))
9182
{
9283
if(!is_application_started(i))
9384
{
@@ -99,15 +90,11 @@ void parse_commands(char *data, int length)
9990
}
10091
break;
10192

102-
case 'o': // stOp : o<name> ? oBot
93+
case NET_CMD_STOP:
10394
{
104-
LOGD("Stop command received: %s", data);
105-
char name[MAX_APP_NAME_LENGTH];
106-
strncpy(name, &data[1], MAX_APP_NAME_LENGTH - 1);
107-
10895
for(int i = 0; i < get_app_count(); i++)
10996
{
110-
if(0 == strncmp(get_app_name(i), name, MAX_APP_NAME_LENGTH - 1))
97+
if(0 == strncmp(get_app_name(i), cmd.app_name, MAX_APP_NAME_LENGTH - 1))
11198
{
11299
if(is_application_running(i))
113100
{
@@ -119,15 +106,11 @@ void parse_commands(char *data, int length)
119106
}
120107
break;
121108

122-
case 'r': // Restart : r<name> ? rBot
109+
case NET_CMD_RESTART:
123110
{
124-
LOGD("Restart command received: %s", data);
125-
char name[MAX_APP_NAME_LENGTH];
126-
strncpy(name, &data[1], MAX_APP_NAME_LENGTH - 1);
127-
128111
for(int i = 0; i < get_app_count(); i++)
129112
{
130-
if(0 == strncmp(get_app_name(i), name, MAX_APP_NAME_LENGTH - 1))
113+
if(0 == strncmp(get_app_name(i), cmd.app_name, MAX_APP_NAME_LENGTH - 1))
131114
{
132115
restart_application(i);
133116
filecmd_remove_restart(i);
@@ -137,30 +120,10 @@ void parse_commands(char *data, int length)
137120
break;
138121
#endif
139122

123+
case NET_CMD_UNKNOWN:
140124
default:
141-
{
142-
const int max_bytes = MAX_APP_NAME_LENGTH;
143-
const int max_length = max_bytes * 3;
144-
char hexStr[max_length];
145-
memset(hexStr, 0, sizeof(hexStr));
146-
147-
if (length > max_bytes) {
148-
length = max_bytes;
149-
}
150-
151-
for (int i = 0; i < length; i++) {
152-
snprintf(&hexStr[i * 3], sizeof(hexStr) - (i * 3), "%02X ", data[i]);
153-
}
154-
155-
char printableStr[max_bytes + 1];
156-
memset(printableStr, 0, sizeof(printableStr));
157-
for (int i = 0; i < length; i++) {
158-
printableStr[i] = (data[i] >= 32 && data[i] < 127) ? data[i] : '.';
159-
}
160-
161-
LOGE("Unknown command received : %s | %s", printableStr, hexStr);
162-
}
163-
break;
125+
// Error logging is already handled in cmd_parse_network
126+
break;
164127
}
165128
}
166129

0 commit comments

Comments
 (0)