36 #include <sys/socket.h> 45 #ifndef CO_COMMAND_SDO_BUFFER_SIZE 46 #define CO_COMMAND_SDO_BUFFER_SIZE 100000 49 #define STRING_BUFFER_SIZE (CO_COMMAND_SDO_BUFFER_SIZE * 4 + 100) 50 #define LISTEN_BACKLOG 50 56 static void *command_thread(
void *arg);
57 static pthread_t command_thread_id;
58 static void command_process(
int fd,
char *command,
size_t commandLength);
60 static unsigned short comm_net = 1;
61 static uint8_t comm_node_default = 0xFF;
62 static uint16_t SDOtimeoutTime = 500;
63 static uint8_t blockTransferEnable = 0;
64 static volatile int endProgram = 0;
69 fprintf(stderr,
"canopend generic error: 0x%X\n", info);
74 struct sockaddr_un addr;
76 if (CO == NULL || CO->SDOclient == NULL) {
77 perror(
"CO_command_init - Wrong arguments");
82 fdSocket = socket(AF_UNIX, SOCK_STREAM, 0);
84 perror(
"CO_command_init - socket failed");
88 memset(&addr, 0,
sizeof(
struct sockaddr_un));
89 addr.sun_family = AF_UNIX;
92 if (bind(fdSocket, (
struct sockaddr *)&addr,
sizeof(
struct sockaddr_un)) == -1) {
94 perror(
"CO_command_init");
99 perror(
"CO_command_init - listen failed");
105 if (pthread_create(&command_thread_id, NULL, command_thread, NULL) != 0) {
106 perror(
"CO_command_init - thread creation failed");
115 static struct sockaddr_un addr;
121 fd = socket(AF_UNIX, SOCK_STREAM, 0);
126 memset(&addr, 0,
sizeof(
struct sockaddr_un));
127 addr.sun_family = AF_UNIX;
130 if (connect(fd, (
struct sockaddr *)&addr,
sizeof(
struct sockaddr_un)) == -1) {
137 if (pthread_join(command_thread_id, NULL) != 0) {
152 static void *command_thread(
void *arg) {
158 while (endProgram == 0) {
160 fd = accept(fdSocket, NULL, NULL);
166 while ((n = read(fd, buf,
sizeof(buf) - 1)) > 0) {
168 command_process(fd, buf, n);
176 if (close(fd) == -1) {
185 static void command_process(
int fd,
char *command,
size_t commandLength) {
205 if (token[0] !=
'[' || token[strlen(token) - 1] !=
']') {
207 if (token[0] ==
'#') {
212 token[strlen(token) - 1] =
'\0';
213 sequence =
getU32(token + 1, 0, 0xFFFFFFFF, &err);
220 for (i = 0; i < 3; i++) {
224 if (isdigit(token[0]) == 0) {
227 ui[i] =
getU32(token, 0, 0xFFFFFFFF, &err);
233 comm_node = comm_node_default;
236 if (ui[0] < 0 || ui[0] > 127) {
244 if (ui[0] < 1 || ui[0] > 1) {
247 }
else if (ui[1] < 0 || ui[1] > 127) {
264 if (strcmp(token,
"r") == 0 || strcmp(token,
"read") == 0) {
285 if (errTokDt == 0 && errDt != 0) {
291 if (err == 0 && (comm_node < 1 || comm_node > 127)) {
293 if (comm_node == 0xFF) {
312 blockTransferEnable);
321 if (SDOabortCode == 0) {
322 respLen = sprintf(resp,
"[%d] ", sequence);
324 if (datatype == NULL || (datatype->
length != 0 && datatype->
length != dataRxLen)) {
325 respLen +=
dtpHex(resp + respLen,
sizeof(resp) - respLen, (
char *)dataRx, dataRxLen);
328 resp + respLen,
sizeof(resp) - respLen, (
char *)dataRx, dataRxLen);
331 respLen = sprintf(resp,
"[%d] ERROR: 0x%08X", sequence, SDOabortCode);
337 else if (strcmp(token,
"w") == 0 || strcmp(token,
"write") == 0) {
361 dataTxLen = datatype->
dataTypeScan((
char *)dataTx,
sizeof(dataTx), token);
364 if ((datatype->
length != 0 && datatype->
length != dataTxLen) || dataTxLen == 0) {
371 if (err == 0 && (comm_node < 1 || comm_node > 127)) {
373 if (comm_node == 0xFF) {
391 blockTransferEnable);
400 if (SDOabortCode == 0) {
401 respLen = sprintf(resp,
"[%d] OK", sequence);
403 respLen = sprintf(resp,
"[%d] ERROR: 0x%08X", sequence, SDOabortCode);
409 else if (strcmp(token,
"start") == 0) {
411 if (err == 0 && comm_node > 127) {
416 err = CO_sendNMTcommand(CO, CO_NMT_ENTER_OPERATIONAL, comm_node) ? 1 : 0;
417 if (err == 0) respLen = sprintf(resp,
"[%d] OK", sequence);
422 else if (strcmp(token,
"stop") == 0) {
424 if (err == 0 && comm_node > 127) {
429 err = CO_sendNMTcommand(CO, CO_NMT_ENTER_STOPPED, comm_node) ? 1 : 0;
430 if (err == 0) respLen = sprintf(resp,
"[%d] OK", sequence);
435 else if (strcmp(token,
"preop") == 0 || strcmp(token,
"preoperational") == 0) {
437 if (err == 0 && comm_node > 127) {
442 err = CO_sendNMTcommand(CO, CO_NMT_ENTER_PRE_OPERATIONAL, comm_node) ? 1 : 0;
443 if (err == 0) respLen = sprintf(resp,
"[%d] OK", sequence);
448 else if (strcmp(token,
"reset") == 0) {
450 if (err == 0 && comm_node > 127) {
455 if (strcmp(token,
"node") == 0) {
458 err = CO_sendNMTcommand(CO, CO_NMT_RESET_NODE, comm_node) ? 1 : 0;
459 if (err == 0) respLen = sprintf(resp,
"[%d] OK", sequence);
461 }
else if (strcmp(token,
"comm") == 0 || strcmp(token,
"communication") == 0) {
464 err = CO_sendNMTcommand(CO, CO_NMT_RESET_COMMUNICATION, comm_node) ? 1 : 0;
465 if (err == 0) respLen = sprintf(resp,
"[%d] OK", sequence);
476 else if (strcmp(token,
"set") == 0) {
480 if (strcmp(token,
"sdo_timeout") == 0) {
490 SDOtimeoutTime = tmout;
491 respLen = sprintf(resp,
"[%d] OK", sequence);
496 else if (strcmp(token,
"sdo_block") == 0) {
506 blockTransferEnable = blk;
507 respLen = sprintf(resp,
"[%d] OK", sequence);
512 else if (strcmp(token,
"node") == 0) {
522 comm_node_default = node;
523 respLen = sprintf(resp,
"[%d] OK", sequence);
542 if (err != 0 && emptyLine == 0) {
546 respLen = sprintf(resp,
"[%d] ERROR: %d", sequence, respErrorCode);
550 resp[respLen++] =
'\r';
551 resp[respLen++] =
'\n';
552 resp[respLen++] =
'\0';
554 if (write(fd, resp, respLen) != respLen) {
579 if (token[0] !=
'[' || token[strlen(token) - 1] !=
']') {
581 if (token[0] ==
'#') {
586 token[strlen(token) - 1] =
'\0';
587 sequence =
getU32(token + 1, 0, 0xFFFFFFFF, &err);
594 for (i = 0; i < 3; i++) {
598 if (isdigit(token[0]) == 0) {
601 ui[i] =
getU32(token, 0, 0xFFFFFFFF, &err);
607 comm_node = comm_node_default;
610 if (ui[0] < 0 || ui[0] > 127) {
618 if (ui[0] < 1 || ui[0] > 1) {
621 }
else if (ui[1] < 0 || ui[1] > 127) {
639 if (strcmp(token,
"r") == 0 || strcmp(token,
"read") == 0) {
660 if (errTokDt == 0 && errDt != 0) {
666 if (err == 0 && (comm_node < 1 || comm_node > 127)) {
668 if (comm_node == 0xFF) {
687 blockTransferEnable);
696 if (SDOabortCode == 0) {
697 respLen = sprintf(resp,
"[%d] ", sequence);
699 if (datatype == NULL || (datatype->
length != 0 && datatype->
length != dataRxLen)) {
700 respLen +=
dtpHex(resp + respLen,
sizeof(resp) - respLen, (
char *)dataRx, dataRxLen);
703 resp + respLen,
sizeof(resp) - respLen, (
char *)dataRx, dataRxLen);
706 respLen = sprintf(resp,
"[%d] ERROR: 0x%08X", sequence, SDOabortCode);
712 else if (strcmp(token,
"w") == 0 || strcmp(token,
"write") == 0) {
736 dataTxLen = datatype->
dataTypeScan((
char *)dataTx,
sizeof(dataTx), token);
739 if ((datatype->
length != 0 && datatype->
length != dataTxLen) || dataTxLen == 0) {
746 if (err == 0 && (comm_node < 1 || comm_node > 127)) {
748 if (comm_node == 0xFF) {
766 blockTransferEnable);
775 if (SDOabortCode == 0) {
776 respLen = sprintf(resp,
"[%d] OK", sequence);
778 respLen = sprintf(resp,
"[%d] ERROR: 0x%08X", sequence, SDOabortCode);
784 else if (strcmp(token,
"start") == 0) {
786 if (err == 0 && comm_node > 127) {
791 err = CO_sendNMTcommand(CO, CO_NMT_ENTER_OPERATIONAL, comm_node) ? 1 : 0;
792 if (err == 0) respLen = sprintf(resp,
"[%d] OK", sequence);
797 else if (strcmp(token,
"stop") == 0) {
799 if (err == 0 && comm_node > 127) {
804 err = CO_sendNMTcommand(CO, CO_NMT_ENTER_STOPPED, comm_node) ? 1 : 0;
805 if (err == 0) respLen = sprintf(resp,
"[%d] OK", sequence);
810 else if (strcmp(token,
"preop") == 0 || strcmp(token,
"preoperational") == 0) {
812 if (err == 0 && comm_node > 127) {
817 err = CO_sendNMTcommand(CO, CO_NMT_ENTER_PRE_OPERATIONAL, comm_node) ? 1 : 0;
818 if (err == 0) respLen = sprintf(resp,
"[%d] OK", sequence);
823 else if (strcmp(token,
"reset") == 0) {
825 if (err == 0 && comm_node > 127) {
830 if (strcmp(token,
"node") == 0) {
833 err = CO_sendNMTcommand(CO, CO_NMT_RESET_NODE, comm_node) ? 1 : 0;
834 if (err == 0) respLen = sprintf(resp,
"[%d] OK", sequence);
836 }
else if (strcmp(token,
"comm") == 0 || strcmp(token,
"communication") == 0) {
839 err = CO_sendNMTcommand(CO, CO_NMT_RESET_COMMUNICATION, comm_node) ? 1 : 0;
840 if (err == 0) respLen = sprintf(resp,
"[%d] OK", sequence);
851 else if (strcmp(token,
"set") == 0) {
855 if (strcmp(token,
"sdo_timeout") == 0) {
865 SDOtimeoutTime = tmout;
866 respLen = sprintf(resp,
"[%d] OK", sequence);
871 else if (strcmp(token,
"sdo_block") == 0) {
881 blockTransferEnable = blk;
882 respLen = sprintf(resp,
"[%d] OK", sequence);
887 else if (strcmp(token,
"node") == 0) {
897 comm_node_default = node;
898 respLen = sprintf(resp,
"[%d] OK", sequence);
917 if (err != 0 && emptyLine == 0) {
921 respLen = sprintf(resp,
"[%d] ERROR: %d", sequence, respErrorCode);
925 resp[respLen++] =
'\r';
926 resp[respLen++] =
'\n';
927 resp[respLen++] =
'\0';
929 printf(
"RESPONSE: %s\n", resp);
uint32_t getU32(char *token, uint32_t min, uint32_t max, int *err)
char * getTok(char *initStr, const char *delim, int *err)
const dataType_t * getDataType(char *token, int *err)
void lastTok(char *initStr, const char *delim, int *err)
char * CO_command_socketPath
char ret[STRING_BUFFER_SIZE]
char buf[STRING_BUFFER_SIZE]
int CO_command_init(void)
int(* dataTypeScan)(char *bufSdo, int bufSdoSize, char *strin)
Data types structure - Defined in CANOpen Code.
int CO_command_clear(void)
int sdoClientDownload(CO_SDOclient_t *SDOclient, uint8_t nodeID, uint16_t idx, uint8_t subidx, uint8_t *dataTx, uint32_t dataTxLen, uint32_t *SDOabortCode, uint16_t SDOtimeoutTime, uint8_t blockTransferEnable)
int(* dataTypePrint)(char *strout, int stroutSize, char *bufSdo, int bufLen)
int dtpHex(char *strout, int stroutSize, char *bufSdo, int bufLen)
#define CO_COMMAND_SDO_BUFFER_SIZE
#define STRING_BUFFER_SIZE
int sdoClientUpload(CO_SDOclient_t *SDOclient, uint8_t nodeID, uint16_t idx, uint8_t subidx, uint8_t *dataRx, uint32_t dataRxSize, uint32_t *dataRxLen, uint32_t *SDOabortCode, uint16_t SDOtimeoutTime, uint8_t blockTransferEnable)
void cancomm_socketFree(char *command, char *ret)
void CO_errorR(const uint32_t info)