commit 3cdfc00cde4b68971b98c5bf31ab8dfea7e92a8b
Author: Dominik Schmidt <das1993@hotmail.com>
Date: Mon, 10 Dec 2012 00:00:04 +0100
Initial Commit
Diffstat:
Makefile | | | 10 | ++++++++++ |
cmd.c | | | 147 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
cmd.h | | | 29 | +++++++++++++++++++++++++++++ |
com.c | | | 85 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
com.h | | | 7 | +++++++ |
ctrl.c | | | 96 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
dev.c | | | 95 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
dev.h | | | 6 | ++++++ |
log.c | | | 31 | +++++++++++++++++++++++++++++++ |
log.h | | | 19 | +++++++++++++++++++ |
main.c | | | 0 | |
11 files changed, 525 insertions(+), 0 deletions(-)
diff --git a/Makefile b/Makefile
@@ -0,0 +1,10 @@
+CC = /usr/bin/gcc
+CFLAGS = -O2 -I.
+TARGET = ctrl
+LIBS = cmd.o dev.o log.o com.o
+.PHONY: $(TARGET)
+$(TARGET): $(LIBS)
+ $(CC) $(CFLAGS) $(TARGET).c -o $@ $(LIBS)
+
+%.o: %.c
+ $(CC) -c $(CFLAGS) -o $@ $<
diff --git a/cmd.c b/cmd.c
@@ -0,0 +1,147 @@
+#include <cmd.h>
+#include <log.h>
+#include <com.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+char COMMAND_TYPE_names[COMMAND_COUNT][COMMAND_TYPE_names_length]={"Status","Reset","Board-Reset","Board-power","Reset-line","Rescue-clock"};
+
+int cmd_board_reset(struct command *cmd,int fd){
+ if(sendMagicPacket(fd,'r')<0){
+ do_log("cmd_board_reset","Couldn't send reset packet", LOG_LEVEL_ERROR, LOG_TYPE_NORMAL);
+ return -1;
+ }
+ int ret=0;
+ char *buf=readString(fd,3);
+ if(parseMagicPacket(buf)=='r'){
+ ret=-2;
+ }
+ free(buf);
+ return ret;
+}
+int cmd_reset(struct command *cmd, int fd){
+ if(sendString(fd,"@main reset")<0){
+ do_log("cmd_reset","Couldn't send reset string", LOG_LEVEL_ERROR, LOG_TYPE_NORMAL);
+ return -1;
+ }
+ char *ret=readString(fd, 0);
+ if(checkIfOk(ret)){
+ do_log("cmd_reset","Couldn't reset device", LOG_LEVEL_ERROR, LOG_TYPE_NORMAL);
+ free(ret);
+ return -2;
+ }
+ free(ret);
+ return 0;
+}
+int cmd_status(struct command *cmd, int fd){
+ if(sendMagicPacket(fd,'i')<0){
+ do_log("cmd_board_reset","Couldn't send status request packet", LOG_LEVEL_ERROR, LOG_TYPE_NORMAL);
+ return -1;
+ }
+ char *ret=readString(fd, 3);
+ char c=parseMagicPacket(ret);
+ do_log("cmd_status", &c, LOG_LEVEL_INFO, LOG_TYPE_NORMAL);
+ free(ret);
+ return 0;
+}
+int cmd_reset_line(struct command *cmd, int fd){
+ char c=0;
+ if(*(char*)cmd->data!='1'&&*(char*)cmd->data!='0'){
+ do_log("cmd_reset_line","Value must be either 1 or 0",LOG_LEVEL_ERROR,LOG_TYPE_NORMAL);
+ return -1;
+ }
+ char str[]={'@','l','i','n','e','s',' ','r','s','t',' ',c};
+ if(sendString(fd,str)<0){
+ do_log("cmd_reset_line","Couldn't send power string", LOG_LEVEL_ERROR, LOG_TYPE_NORMAL);
+ return -2;
+ }
+ char *r=readString(fd,0);
+ printf("%s\n",r);
+ if(!checkIfOk(r)){
+ do_log("cmd_reset_line","Couldn't set reset line", LOG_LEVEL_ERROR, LOG_TYPE_NORMAL);
+ free(r);
+ return -3;
+ }
+ free(r);
+ return 0;
+}
+int cmd_board_power(struct command *cmd, int fd){
+ char c=0;
+ if(*(char*)cmd->data=='1'){
+ c='+';
+ }
+ else if(*(char*)cmd->data=='0'){
+ c='-';
+ }
+ else{
+ do_log("cmd_board_power","Value must be either 1 or 0",LOG_LEVEL_ERROR,LOG_TYPE_NORMAL);
+ return -1;
+ }
+ if(sendMagicPacket(fd,c)<0){
+ do_log("cmd_board_reset","Couldn't send power string", LOG_LEVEL_ERROR, LOG_TYPE_NORMAL);
+ return -2;
+ }
+ char r=readMagicPacket(fd);
+ if(r!=c){
+ return -3;
+ }
+ return 0;
+}
+int executeCommand(struct command *cmd, int fd){
+ int (*func)(struct command *, int)=NULL;
+ switch(cmd->type){
+ case COMMAND_BOARD_RESET:
+ func=&cmd_board_reset;
+ break;
+ case COMMAND_RESET:
+ func=&cmd_reset;
+ break;
+ case COMMAND_STATUS:
+ func=&cmd_status;
+ break;
+ case COMMAND_BOARD_POWER:
+ func=&cmd_board_power;
+ break;
+ case COMMAND_RESET_LINE:
+ func=&cmd_reset_line;
+ break;
+ default:
+ do_log("executeCommand", "Commandtype unknown", LOG_LEVEL_ERROR, LOG_TYPE_NORMAL);
+ return -1;
+ break;
+ }
+ if(func(cmd,fd)<0){
+ do_log("executeCommand","Couldn't execute command",LOG_LEVEL_ERROR,LOG_TYPE_NORMAL);
+ }
+ else{
+ do_log("executeCommand","Executing successfull",LOG_LEVEL_DEBUG,LOG_TYPE_NORMAL);
+ }
+ return 0;
+}
+int processCommands(struct command **cmdlist, int fd){
+ unsigned int i=0;
+ char *str=malloc(strlen("Executing command %s failed")+COMMAND_TYPE_names_length);
+ while(cmdlist[i]!=NULL){
+ sprintf(str,"Executing command %s",COMMAND_TYPE_names[cmdlist[i]->type]);
+ do_log("processCommands",str,LOG_LEVEL_DEBUG,LOG_TYPE_NORMAL);
+ if(executeCommand(cmdlist[i], fd)<0){
+ sprintf(str,"Executing command %s failed",COMMAND_TYPE_names[cmdlist[i]->type]);
+ do_log("processCommands",str,LOG_LEVEL_ERROR,LOG_TYPE_NORMAL);
+ }
+ i++;
+ }
+ return 0;
+}
+struct command *newCommand(unsigned short type){
+ struct command *cmd;
+ unsigned int i=0;
+ if(type>COMMAND_TYPEARGS_00){
+ i=1;
+ }
+ else if(type>COMMAND_TYPEARGS_01){
+ i=2;
+ }
+ cmd=(struct command *)malloc(sizeof(struct command)-1+i);
+ cmd->type=type;
+ return cmd;
+}
diff --git a/cmd.h b/cmd.h
@@ -0,0 +1,29 @@
+#pragma once
+
+enum COMMAND_TYPE{
+ COMMAND_STATUS=0,
+ COMMAND_RESET,
+ COMMAND_BOARD_RESET,
+ COMMAND_TYPEARGS_00=COMMAND_BOARD_RESET,
+ COMMAND_BOARD_POWER,
+ COMMAND_RESET_LINE,
+ COMMAND_RESCUE_CLOCK,
+ COMMAND_TYPEARGS_01=COMMAND_RESCUE_CLOCK,
+ COMMAND_TYPEARGS_02=COMMAND_TYPEARGS_01,
+ COMMAND_COUNT
+};
+#define COMMAND_TYPE_names_length 18
+struct command{
+ unsigned short type;
+ void *data;
+};
+extern char COMMAND_TYPE_names[COMMAND_COUNT][COMMAND_TYPE_names_length];
+
+
+extern int cmd_board_reset(struct command *cmd,int fd);
+extern int cmd_reset(struct command *cmd, int fd);
+extern int cmd_status(struct command *cmd, int fd);
+extern int cmd_board_power(struct command *cmd, int fd);
+extern int executeCommand(struct command *cmd, int fd);
+extern int processCommands(struct command **cmdlist, int fd);
+extern struct command *newCommand(unsigned short type);
diff --git a/com.c b/com.c
@@ -0,0 +1,85 @@
+#include <com.h>
+#include <log.h>
+#include <stdlib.h>
+#include <cmd.h>
+#include <string.h>
+#include <stdio.h>
+char *readString(int fd, unsigned int length){
+ unsigned int size=10;
+ char *str=malloc(size);
+
+ unsigned int i=0;
+ char c;
+ int ret;
+ while((ret=read(fd,&c,sizeof(char)))){
+ if(ret<=0){
+ do_log("readString","Read Error",LOG_LEVEL_ERROR,LOG_TYPE_SIGNAL);
+ free(str);
+ return NULL;
+ }
+ if(i+1>=size){
+ size+=10;
+ str=realloc((void *)str,size);
+ }
+ if(length!=0&&i>=length){
+ str[i]='\0';
+ break;
+ }
+ if(c==0x0A){
+ str[i]='\0';
+ }
+ else if(c==0){
+ continue;
+ }
+ else{
+ str[i]=c;
+ }
+ i++;
+ }
+ return str;
+}
+char readMagicPacket(int fd){
+ int ret;
+ char c,r;
+ r=0;
+ unsigned int i=0;
+ while((ret=read(fd,&c,sizeof(char)))){
+ if(ret<=0){
+ do_log("readString","Read Error",LOG_LEVEL_ERROR,LOG_TYPE_SIGNAL);
+ return 0;
+ }
+ if(c==0x0A){
+ break;
+ }
+ else if((c>='a'&&c<='z')||c=='+'||c=='-'){
+ r=c;
+ }
+ }
+ return r;
+}
+int sendRawString(int fd, const char *str){
+ return write(fd,str,strlen(str));
+}
+int sendString(int fd, const char *str){
+ unsigned int length=strlen(str);
+ char *newstr=malloc(length+1);
+ strcpy(newstr,str);
+ newstr[length]=0xA;
+ return write(fd,newstr,length+1);
+}
+int sendMagicPacket(int fd, char c){
+ char magic[]={0xE6,0xB5,0xBA,0xB9,0xB2,0xB3,0xA9,c};
+ return sendRawString(fd,magic);
+}
+char parseMagicPacket(char *str){
+ unsigned int i=0;
+ for(i=0; i<strlen(str);i++){
+ if((str[i]>='a'&&str[i]<='z')||str[i]=='+'||str[i]=='-'){
+ return str[i];
+ }
+ }
+ return 0;
+}
+int checkIfOk(char *str){
+ return (str[0]=='o'&&str[1]=='k');
+}
diff --git a/com.h b/com.h
@@ -0,0 +1,7 @@
+#pragma once
+extern char *readString(int fd, unsigned int length);
+extern int sendRawString(int fd, const char *str);
+extern int sendString(int fd, const char *str);
+extern int sendMagicPacket(int fd, char c);
+extern int checkIfOk(char *str);
+char parseMagicPacket(char *str);
diff --git a/ctrl.c b/ctrl.c
@@ -0,0 +1,96 @@
+#include <stdio.h>
+#include <log.h>
+#include <cmd.h>
+#include <stdlib.h>
+#include <termios.h>
+#include <com.h>
+
+struct conf{
+ struct command **cmdlist;
+ unsigned short int need_mymode;
+ char oldmode;
+};
+struct conf config;
+
+char *filename;
+unsigned short int log_level=LOG_LEVEL_DEBUG;
+
+int parseArguments(int argc, char **argv, struct conf *config){
+ unsigned int i=0;
+ unsigned int cmdcnt=0;
+ unsigned int alloc=10;
+ config->cmdlist=(struct command **)malloc(alloc*sizeof(struct command **));
+ struct command *newcmd;
+
+ for(i=0;i<argc;i++){
+ newcmd=NULL;
+ if(strcmp(argv[i],"-R")==0){
+ newcmd=newCommand(COMMAND_RESET);
+ config->need_mymode=1;
+ }
+ else if(strcmp(argv[i],"-r")==0){
+ newcmd=newCommand(COMMAND_BOARD_RESET);
+ }
+ else if(strcmp("-s", argv[i])==0){
+ newcmd=newCommand(COMMAND_STATUS);
+ }
+ else if(strcmp("-p", argv[i])==0){
+ newcmd=newCommand(COMMAND_BOARD_POWER);
+ newcmd->data=argv[++i];
+ }
+ else if(strcmp("-rL", argv[i])==0){
+ newcmd=newCommand(COMMAND_RESET_LINE);
+ newcmd->data=argv[++i];
+ config->need_mymode=1;
+ }
+
+ if(newcmd!=NULL){
+ if(cmdcnt+1>alloc){
+ alloc+=10;
+ config->cmdlist=realloc((void *)config->cmdlist, alloc*sizeof(struct command **));
+ }
+ config->cmdlist[cmdcnt]=newcmd;
+ cmdcnt++;
+ }
+ }
+ config->cmdlist[cmdcnt]=NULL;
+ return 0;
+}
+int prepareCommandExecution(int fd, struct conf *config){
+ config->oldmode=0;
+ if(config->need_mymode){
+ sendMagicPacket(fd,'i');
+ config->oldmode=readMagicPacket(fd);
+ if(config->oldmode!='m'){
+ sendMagicPacket(fd,'m');
+ setBaudRate(fd,B500000);
+ if(readMagicPacket(fd)!='m'){
+ do_log("prepareCommandExecution","Couldn't switch to mymode",LOG_LEVEL_ERROR,LOG_TYPE_NORMAL);
+ return -1;
+ }
+ }
+
+ }
+ return 0;
+}
+int finishCommandExecution(int fd, struct conf *config){
+ if(config->oldmode>0){
+ sendMagicPacket(fd,config->oldmode);
+ }
+}
+int main(int argc, char **argv){
+ filename=argv[0];
+ parseArguments(argc-1, &argv[1],&config);
+
+ int fd=openDevice("/dev/ttyUSB0");
+ if(fd<0){
+ do_log("main","Couldn't open device",LOG_LEVEL_FATAL,LOG_TYPE_NORMAL);
+ return 1;
+ }
+ prepareCommandExecution(fd, &config);
+ processCommands(config.cmdlist,fd);
+ finishCommandExecution(fd, &config);
+
+ closeDevice(fd);
+ return 0;
+}
diff --git a/dev.c b/dev.c
@@ -0,0 +1,95 @@
+#include <dev.h>
+#include <termios.h>
+#include <log.h>
+#include <cmd.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <stdlib.h>
+#include <com.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+int closeDevice(int dev){
+ fsync(dev);
+ return close(dev);
+}
+int autoConfigBaud(int fd){
+ speed_t speed[3]={B500000, B115200, B19200};
+ unsigned int i=0;
+ struct command query;
+ query.type=COMMAND_STATUS;
+ for(i=0;i<=3; i++){
+ sendMagicPacket(fd,'i');
+ char c=readMagicPacket(fd);
+ if(c!=0){
+ break;
+ }
+
+ if(i==3){
+ do_log("autoConfigBaud","Couldn't evaluate correct baudrate", LOG_LEVEL_FATAL,LOG_TYPE_NORMAL);
+ return -1;
+ }
+ if(setBaudRate(fd,speed[i])<0){
+ do_log("autoConfigBaud","Couldn't set baudrate", LOG_LEVEL_FATAL,LOG_TYPE_NORMAL);
+ return -2;
+ }
+ }
+
+ return 0;
+}
+int setBaudRate(int fd, speed_t baud){
+ struct termios options;
+ if(tcgetattr(fd, &options)<0){
+ do_log("setBaudRate","Couldn't load Options",LOG_LEVEL_ERROR,LOG_TYPE_SIGNAL);
+ return -1;
+ }
+ if(cfsetispeed(&options, baud)<0){
+ do_log("setBaudRate","Couldn't set InputSpeed",LOG_LEVEL_ERROR,LOG_TYPE_SIGNAL);
+ closeDevice(fd);
+ return -2;
+ }
+ if(cfsetospeed(&options, baud)<0){
+ do_log("setBaudRate","Couldn't set OutputSpeed",LOG_LEVEL_ERROR,LOG_TYPE_SIGNAL);
+ closeDevice(fd);
+ return -3;
+ }
+ if(tcsetattr(fd, TCSANOW, &options)<0){
+ do_log("setBaudRate","Couldn't set Options",LOG_LEVEL_ERROR,LOG_TYPE_SIGNAL);
+ closeDevice(fd);
+ return -4;
+ }
+ return 0;
+
+}
+int openDevice(char *dev){
+ int fd = open(dev, O_RDWR | O_NOCTTY );
+ if(fd<0){
+ do_log("openDevice", "Couldn't open Device", LOG_LEVEL_FATAL,LOG_TYPE_SIGNAL);
+ return -1;
+ }
+ ioctl(fd, TIOCEXCL);
+ struct termios options;
+ tcgetattr(fd, &options);
+
+ options.c_cflag|=(CLOCAL | CREAD);
+ options.c_cflag&=~CSIZE;
+ options.c_cflag|=CS8;
+ options.c_cflag&=~PARENB;
+ options.c_cflag&=~CSTOPB;
+ options.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN | ISIG);
+ options.c_iflag &= ~(IXON | IXOFF | IXANY );
+ options.c_oflag &= ~(OCRNL | ONLCR | ONLRET |ONOCR | OFILL | OLCUC | OPOST);
+
+ options.c_cc[VTIME]=5;
+ options.c_cc[VMIN]=0;
+
+ if(tcsetattr(fd, TCSANOW, &options)<0){
+ do_log("openDevice","Couldn't set Options",LOG_LEVEL_FATAL,LOG_TYPE_SIGNAL);
+ closeDevice(fd);
+ return -4;
+ }
+ if(autoConfigBaud(fd)<0){
+ return -5;
+ }
+ return fd;
+}
diff --git a/dev.h b/dev.h
@@ -0,0 +1,6 @@
+#pragma once
+#include <termios.h>
+extern int closeDevice(int dev);
+extern int autoConfigBaud(int fd);
+extern int openDevice(char *dev);
+extern int setBaudRate(int fd, speed_t baud);
diff --git a/log.c b/log.c
@@ -0,0 +1,31 @@
+#include <log.h>
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+char LOG_LEVEL_names[LOG_LEVEL_COUNT][8]={"DEBUG","INFO","WARNING","ERROR","FATAL"};
+void log_string(char *str, unsigned short int level){
+ FILE *stream;
+ if(level>=LOG_LEVEL_WARNING){
+ stream=stderr;
+ }
+ else{
+ stream=stdout;
+ }
+ fprintf(stream,"%s\n",str);
+}
+void do_log(char *src, char *msg, unsigned short int level, unsigned short int type){
+ int error=errno;
+ char *str=malloc(strlen("%s[%s]: %s (%s)")+strlen(src)+strlen(msg)+strlen(LOG_LEVEL_names[level])+strlen(strerror(error)));
+ if(type==LOG_TYPE_SIGNAL){
+ sprintf(str,"%s[%s]: %s (%s)",LOG_LEVEL_names[level],src,msg,strerror(error));
+ }
+ else if(type==LOG_TYPE_RESULT){
+ sprintf(str,"%s",msg);
+ }
+ else{
+ sprintf(str,"%s[%s]: %s",LOG_LEVEL_names[level],src,msg);
+ }
+ log_string(str,level);
+ free(str);
+}
diff --git a/log.h b/log.h
@@ -0,0 +1,19 @@
+#pragma once
+enum LOG_TYPE{
+ LOG_TYPE_RESULT,
+ LOG_TYPE_NORMAL,
+ LOG_TYPE_SIGNAL
+};
+enum LOG_LEVEL{
+ LOG_LEVEL_DEBUG,
+ LOG_LEVEL_INFO,
+ LOG_LEVEL_WARNING,
+ LOG_LEVEL_ERROR,
+ LOG_LEVEL_FATAL,
+ LOG_LEVEL_COUNT
+};
+
+extern void log_string(char *str, unsigned short int level);
+extern void do_log(char *src, char *msg, unsigned short int level, unsigned short int type);
+#define LOG_LEVEL_names_length 8
+extern char LOG_LEVEL_names[LOG_LEVEL_COUNT][LOG_LEVEL_names_length];
diff --git a/main.c b/main.c