#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <getopt.h>
#include <termios.h> //set baud rate
#include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>
#include <errno.h>
#include <sys/stat.h>
#define MAXLINEN 10
#define MAXDEVICE 6
#define CHARARRAY(LEN) (char*)calloc(LEN, sizeof(char))
#define DEVICENUMARRAY(LEN) (DeviceNumP)calloc(LEN, sizeof(DeviceNum))
#define buffLen 1024
#define rcvTimeOut 200
typedef
struct
deviceNum{
char
Name[30];
int
Num;
}DeviceNum, *DeviceNumP;
static
char
* configName =
"status"
;
char
* PASSWDSTR[MAXLINEN] = {NULL};
DeviceNumP DEVICEN[MAXDEVICE] = {NULL};
static
int
BPS;
static
char
DEVNAME[50];
static
const
struct
option long_option[] = {
{
"send"
, required_argument, NULL,
's'
},
{NULL, 0, NULL, 0}
};
int
autoMaticAddressing(
char
** passwd);
int
setSerialOpt(
int
fdSerial,
int
pbs);
int
checkDevice(
int
fdSerial,
char
* send,
char
* receive);
void
DEBUG(
int
fdSerial);
void
putBaudrate();
void
getConfigFile();
void
freeCharArray(
char
** array);
void
freeDeviceNumArray(DeviceNum** array);
void
delChangeLineChar(
char
* Line);
int
openPort(
char
* devName)
{
int
fd = 0;
fd = open(devName, O_RDWR | O_NOCTTY | O_NDELAY);
if
(-1 == fd)
{
return
(0);
}
if
(fcntl(fd, F_SETFL, 0)<0)
{
}
else
{
fcntl(fd, F_SETFL, 0);
}
strcpy
(DEVNAME, devName);
return
fd;
}
int
setOpt(
int
fd,
int
nSpeed,
int
nBits,
char
nEvent,
int
nStop)
{
struct
termios newtio, oldtio;
if
(tcgetattr(fd, &oldtio) != 0)
{
return
-1;
}
bzero(&newtio,
sizeof
(newtio));
newtio.c_cflag |= CLOCAL | CREAD;
newtio.c_cflag &= ~CSIZE;
switch
(nBits)
{
case
7:
newtio.c_cflag |= CS7;
break
;
case
8:
newtio.c_cflag |= CS8;
break
;
}
switch
(nEvent)
{
case
'O'
:
newtio.c_cflag |= PARENB;
newtio.c_cflag |= PARODD;
newtio.c_iflag |= (INPCK | ISTRIP);
break
;
case
'E'
:
newtio.c_iflag |= (INPCK | ISTRIP);
newtio.c_cflag |= PARENB;
newtio.c_cflag &= ~PARODD;
break
;
case
'N'
:
newtio.c_cflag &= ~PARENB;
break
;
}
switch
(nSpeed)
{
case
38400:
cfsetispeed(&newtio, B38400);
cfsetospeed(&newtio, B38400);
BPS = 38400;
break
;
case
921600:
cfsetispeed(&newtio, B921600);
cfsetospeed(&newtio, B921600);
BPS = 921600;
break
;
case
115200:
BPS = 115200;
cfsetispeed(&newtio, B115200);
cfsetospeed(&newtio, B115200);
break
;
default
:
BPS = 38400;
cfsetispeed(&newtio, B38400);
cfsetospeed(&newtio, B38400);
break
;
}
if
(nStop == 1)
{
newtio.c_cflag &= ~CSTOPB;
}
else
if
(nStop == 2)
{
newtio.c_cflag |= CSTOPB;
}
newtio.c_cc[VTIME] = 0;
newtio.c_cc[VMIN] = 0;
tcflush(fd, TCIFLUSH);
if
((tcsetattr(fd, TCSANOW, &newtio)) != 0)
{
return
-1;
}
return
0;
}
int
readDataTty(
int
fd,
char
*rcv_buf,
int
TimeOut,
int
Len)
{
int
retval;
fd_set rfds;
struct
timeval tv;
int
ret, pos;
tv.tv_sec = TimeOut / 1000;
tv.tv_usec = TimeOut % 1000 * 1000;
pos = 0;
while
(1)
{
FD_ZERO(&rfds);
FD_SET(fd, &rfds);
retval = select(fd + 1, &rfds, NULL, NULL, &tv);
if
(retval == -1)
{
break
;
}
else
if
(retval)
{
ret = read(fd, rcv_buf + pos, 1);
if
(-1 == ret)
{
break
;
}
pos++;
if
(Len <= pos)
{
break
;
}
}
else
{
break
;
}
}
return
pos;
}
int
sendDataTty(
int
fd,
char
*send_buf,
int
Len)
{
ssize_t ret;
ret = write(fd, send_buf, Len);
if
(ret == -1)
{
printf
(
"write device error\n"
);
return
-1;
}
return
1;
}
int
main(
int
argc,
char
** argv)
{
char
argvSend[30] =
""
;
int
opt = 0;
while
((opt = getopt_long(argc, argv,
"s:"
, long_option, NULL)) != -1){
switch
(opt){
case
0:
break
;
case
's'
:
strcpy
(argvSend, optarg);
}
}
int
fdSerial = 0;
getConfigFile();
char
send[20] =
""
;
char
receive[20] =
""
;
char
* passwd[2] = {send, receive};
send[0] = PASSWDSTR[0][0];
receive[0] = PASSWDSTR[0][1];
if
((fdSerial = autoMaticAddressing(passwd)) == 0)
{
printf
(
"Failed to connect to serial device!\n"
);
freeCharArray(PASSWDSTR);
freeDeviceNumArray(DEVICEN);
return
1;
}
tcflush(fdSerial, TCIOFLUSH);
fcntl(fdSerial, F_SETFL, 0);
char
buffRcvData[buffLen];
sendDataTty(fdSerial, argvSend,
sizeof
(argvSend));
int
readDataNum = 0;
readDataNum = readDataTty(fdSerial, buffRcvData, rcvTimeOut, buffLen);
close(fdSerial);
freeCharArray(PASSWDSTR);
freeDeviceNumArray(DEVICEN);
return
0;
}
int
autoMaticAddressing(
char
** config){
int
fdSerial = 0;
char
devName[50];
int
max = 5;
int
i = 0;
int
devIndex = 0;
int
res = 0;
for
(devIndex = 0; devIndex < MAXDEVICE; devIndex++){
if
(!DEVICEN[devIndex] ||
strlen
(DEVICEN[devIndex]->Name) < 2 ){
continue
;
}
for
(i = 0; i < DEVICEN[devIndex]->Num; i++){
sprintf
(devName,
"%s%d"
, DEVICEN[devIndex]->Name, i);
fdSerial = openPort(devName);
if
(fdSerial != 0){
if
(setSerialOpt(fdSerial, 38400) > 0 &&
checkDevice(fdSerial, config[0], config[1])){
res = 1;
break
;
}
else
if
(setSerialOpt(fdSerial, 921600) > 0 &&
checkDevice(fdSerial, config[0], config[1])){
res = 1;
break
;
}
}
}
if
(res){
break
;
}
}
if
(res){
putBaudrate();
}
else
{
fdSerial = 0;
}
return
fdSerial;
}
int
setSerialOpt(
int
fdSerial,
int
pbs){
if
(setOpt(fdSerial, pbs, 8,
'N'
, 1) < 0)
{
return
0;
}
return
1;
}
int
checkDevice(
int
fdSerial,
char
* send,
char
* receive){
char
receiveData[buffLen] =
""
;
int
readDataNum = 0;
sendDataTty(fdSerial, send,
sizeof
(send));
readDataNum = readDataTty(fdSerial, receiveData, rcvTimeOut, buffLen);
if
(readDataNum == 1){
if
(receive[0] == receiveData[0]){
return
1;
}
}
else
if
(readDataNum > 1){
if
(
strcmp
(receiveData, receive) == 0){
return
1;
}
else
{
return
0;
}
}
else
{
return
0;
}
}
void
putBaudrate(){
printf
(
"--------------------\n"
);
printf
(
"Device = %s\n"
, DEVNAME);
printf
(
"Baudrate = %d\n"
, BPS);
printf
(
"--------------------\n"
);
}
void
getConfigFile(){
FILE
* fp = NULL;
fp =
fopen
(configName,
"r"
);
int
maxChar = 20;
int
line = 0;
int
line_1 = 0;
DeviceNumP dev;
do
{
if
(line == 0){
PASSWDSTR[line] = CHARARRAY(maxChar);
fgets
(PASSWDSTR[line], maxChar, fp);
delChangeLineChar(PASSWDSTR[line]);
}
else
{
line_1 = line - 1;
DEVICEN[line_1] = DEVICENUMARRAY(1);
dev = DEVICEN[line_1];
fscanf
(fp,
"%s %d"
, dev->Name, &dev->Num);
}
if
(
feof
(fp)){
break
;
}
}
while
( ++line < MAXLINEN);
fclose
(fp);
}
void
DEBUG(
int
fdSerial){
char
buffRcvData[buffLen] = { 0 };
unsigned
int
readDataNum = 0;
char
c[10] =
""
;
int
sendNum = 10;
while
(1){
scanf
(
"%s"
, c);
printf
(
"send: %s\n"
, c);
sendDataTty(fdSerial, c, sendNum);
printf
(
"rec: %s\n"
, buffRcvData);
readDataNum = 0;
readDataNum = readDataTty(fdSerial, buffRcvData, rcvTimeOut, buffLen);
printf
(
"recevie %d -----\n"
, readDataNum);
}
}
void
freeCharArray(
char
** array){
char
* line = NULL;
int
n = 0;
for
(n = 0; n < MAXLINEN; line = array[n], n++){
if
(!line){
continue
;
}
free
(line);
}
}
void
freeDeviceNumArray(DeviceNum** array){
DeviceNumP line = NULL;
int
n = 0;
for
(n = 0; n < MAXDEVICE; line = array[n], n++){
if
(!line){
continue
;
}
free
(line);
}
}
void
delChangeLineChar(
char
* Line){
int
Len =
strlen
(Line);
int
n = 0;
for
(n = 0; n < Len; n++){
if
(Line[n] == 10 || Line[n] == 13){
Line[n] =
'\0'
;
break
;
}
}
}