Raspberry Pi RS232 read RFID Transponder - c

I want to open my door with a RFID Transponder. For this I use a Raspberry Pi and an 125Khz RFID Reader with UART. So now I have written a little C programm, wich sets up the RS232 ('ttyAMA0'). This works all fine, and I can read the Transponder, but it reads some sh**
Here is my Code:
char read_rfid(char* rfid_num)
{
fd_set input_fdset;
ssize_t length;
while(1)
{
FD_ZERO(&input_fdset);
FD_SET(fd,&input_fdset);
if(select(fd+1 ,&input_fdset, NULL,NULL,NULL)==-1)
perror("Terminal select() failed");
if(FD_ISSET(fd,&input_fdset))
{
if((length = read(fd,rfid_num,14)) ==-1)
perror("Terminal: read() failed");
else
{
write(STDOUT_FILENO,rfid_num,length);
return;
}
}
}
}
int setupRS232()
{
struct termios term_attr;
if((fd = open(RFID,O_RDWR)) == -1)
{
perror("Can't open Device");
return(1);
}
if(tcgetattr(fd,&term_attr) != 0)
{
perror("terminal: tcgetattr() failed");
return(1);
}
term_attr.c_cflag = BAUD|CS8|CRTSCTS|CLOCAL|CREAD;
term_attr.c_iflag = 0;
term_attr.c_oflag = 0;
term_attr.c_lflag = 0;
if(tcsetattr(fd,TCSAFLUSH,&term_attr) != 0)
{
perror("terminal: tcsetattr() failed");
return(1);
}
}
int main(int argc, char** argv)
{
MYSQL *mysql = NULL;
char rfid_num[14];
int i;
if(init_mysql(mysql) == 1)
return(1);
if(setupRS232() == 1)
return(1);
puts("Warte auf Transponder...");
read_rfid(rfid_num);
for(i=0;i<20;i++)
{
printf("%x\n",rfid_num[i]);
}
}
PS: Sorry for my bad English

Minimal approach to buffering. You should probably check the contents of the buffer before returning valid (is there a final \n ? )
char read_rfid(char* rfid_num) {
fd_set input_fdset;
ssize_t length;
int done;
for(done=0; done < 14; ) {
FD_ZERO(&input_fdset);
FD_SET(fd,&input_fdset);
if(select(fd+1 ,&input_fdset, NULL,NULL,NULL) == -1) {
if (errno == EAGAIN) continue;
perror("Terminal select() failed");
return -1;
}
if(FD_ISSET(fd,&input_fdset)) {
if((length = read(fd,rfid_num+done,14-done)) == -1) {
if (errno == EAGAIN) continue;
perror("Terminal: read() failed");
return -1;
}
write(STDOUT_FILENO,rfid_num+done,length);
done += length;
}
}
return 0;
}
Note: I don't understand why this function returns char.

Related

Bad address in my file I/O operation function

I am learning Linux file I/O operation functions and trying to write a program that could creat a new file, read or write it as well as change the permissions and attributes of a file. When I try to use function "open(pathname, O_RDWR);" to get a file descriptor and use "read()" function to read current file, there is always "bad address" error. However, when I use "open(pathname, O_RDWR|O_CREATE,S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)" before write, the file will be writen currectly.
Here are the source code when I using that two function.
//the welcome function is a function that serve as a function nemu bar
void Create()
{
char filepath[8];
int fd;
printf("请输入要创建的文件所在的目录及其名称:\n");
scanf("%s",&filepath);
fd = open(filepath, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH );//总是以默认的方式创建文件
if(fd == -1)
{
printf("创建失败,请重新输入文件名及其所在目录创建\n");
sleep(5);
Create();
}
else
{
char is;
printf("创建成功!是否对新创建的文件进行写操作?");
scanf("%s",&is);
if(is == 'y'||is == 'Y')
Write(fd,filepath);
else if(is == 'n'||is == 'N')
{
close(fd);
welcome();
}
else
{
printf("您的输入有误,回到欢迎界面中…\n");
close(fd);
sleep(5);
welcome();
}
}
}
void Write(int fd, char *path)
{
volatile int len;
if(fd == -1)
{
len = 0;
char filepath[8];
printf("请输入要写的文件的完整路径及其名称:");
scanf("%s",&filepath);
fd = open(filepath, O_RDWR);
if(fd == -1)
{
perror("open during write");
Write(-1, "");
}
char w1[BUFFERSIZE], *w;
printf("请输入要写入文件的内容,以回车结束:\n");
scanf("%s",&w1);
w = w1;
//用于写入的模块
int n = 1;
while(n > 0)
{
if(n = write(fd, w+len, (strlen(w)-len))<0)
{
perror("write");
return;
}
len += n;
}
char is;
printf("是否查看写入的内容?");
scanf("%s",&is);
if(is == 'Y'||is == 'y')
{
close(fd);
Read(filepath,strlen(w));
}
else
{
close(fd);
welcome();
}
}
else
{
printf("请输入要写入文件的数据:\n");
char w1[BUFFERSIZE];
char *w;
scanf("%s",&w1);
w = w1;
len = 0;
int n = 1;
while(n > 0)
{
n = write(fd, w+len, (strlen(w)-len));
len += n;
}
char is;
printf("是否查看写入的内容?");
scanf("%s",&is);
if(is == 'Y'||is == 'y')
{
close(fd);
Read(path,strlen(w));
}
else
{
close(fd);
welcome();
}
}
};
Could you please help me solve this question? I would be highly appreciated if you could help me!

C TCP sockets: read () on socket returns Resourse temporarily unavailable

The system I realize consists of a ring of tokens (each token is a ckient-server process).
I tested it runnimy two processes.
In function serverMessageProcessor() I call readMessage() function, in which I use read() to read all parts of a message from an (in)socket and (after processes it) write another message on (out)socket.
The first time I do it, it works well, the second time, one of the read() function in my readMessage() function, gives read: Success (I use perror to catch read error) and read: Resourse temporarily unavailable on the other process.
There are some prints for debugging in the code.
I hope you can help me.
Thanks a lot in advance.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h> //per le funzioni sui socket.
#include <arpa/inet.h> //per la funzione inet_aton().
#include <netinet/in.h> //per la struct sockaddr.
#include <sys/wait.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/time.h>
#include <ctype.h> //per la funzione isdigit().
#include <fcntl.h> //per rendere il socket bloccante o no.
#include <sys/select.h>
/* Error hendler */
void sys_error (const char *message) {
perror (message);
}
/* Connessione in ingresso */
int setUpConnectionIn(int port, int *sock_fd){
int sock_in;
struct sockaddr_in addr;
addr.sin_family = AF_INET; //Internet Address Family.
addr.sin_port=htons(port); //Local port.
addr.sin_addr.s_addr = htonl(INADDR_ANY); //Any incoming interface.
//Create socket for incoming connections.
if((sock_in = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
stampaStr("Errore: Creazione socket non riuscita.", 1);
return -1;
}
//Bind to the local address.
if(bind(sock_in, (struct sockaddr *) &addr, sizeof(addr)) < 0){
sys_error("Errore: impossibile assegnare l'indirizzo al socket.");
close(sock_in);
return -1;
}
//Mark the socket so it will listen for incoming connections.
if(listen(sock_in,5) < 0) {
sys_error("Errore: listen non riuscita.");
close(sock_in);
return -1;
}
*sock_fd = sock_in;
return 0;
}
/* Interfaccia Connessione in ingresso */
int setUpConnectionIn_2 (int sock_fd){
int connection_in;
if ((connection_in = accept(sock_fd, NULL, NULL)) < 0) {
sys_error ("Errore in funzione setUpConnectionIn_2");
return -1;
}
return connection_in;
}
/* Connessione in uscita */
int setUpConnectionOut (int *sock_fd, int connection_port, char *conn_addr){
int check;
struct sockaddr_in addr_out;
int sock_out;
addr_out.sin_family = AF_INET;
addr_out.sin_port = htons(connection_port);
if (inet_aton(conn_addr, &addr_out.sin_addr) < 0) {
sys_error ("Errore: inet_aton");
return -1;
}
if((sock_out = socket(PF_INET, SOCK_STREAM, 0))<0) {
sys_error("Errore: Creazione socket non riuscita.");
return -1;
}
stampaStr("In attesa di connessione alla stazione successiva..\n", 1);
while(connect(sock_out, (struct sockaddr *)&addr_out, sizeof(addr_out)) < 0);
*sock_fd = sock_out;
return 0;
}
int closed_ring = 0;
int readMessage (int *fd, unsigned char *cod, int *size, char **content) {
char *content_msg;
unsigned char cod_msg;
int size_msg;
int retval = fcntl(*fd, F_SETFL, fcntl(*fd, F_GETFL) | O_NONBLOCK);
printf ("readMessage - prima read\n");
if (read(*fd, &cod_msg, 1) == 0) {
sys_error ("read - cod_msg");
return -1;
}
if (read(*fd, &size_msg, 4) == 0) {
sys_error ("read - size_msg");
return -1;
}
*content = (char *)malloc((size_msg+1)*sizeof(char));
(*content)[size_msg+1] = '\0';
if (read(*fd, *content, size_msg) == 0) {
sys_error ("read - content_msg");
return -1;
}
retval = fcntl(*fd, F_SETFL, (fcntl(*fd, F_GETFL) | O_NONBLOCK) & (~O_NONBLOCK));
printf ("readMessage - dopo read\n");
printf ("(readMessage)cod: %c - size: %d - msg: %s\n", cod_msg, size_msg, *content);
*cod = cod_msg;
*size = size_msg;
//content = (char *)malloc(size_msg*sizeof(char));
//memcpy(content, content_msg, strlen(content_msg));
//content = content_msg;
printf ("content: %s\n", *content);
return 0;
}
int buildMessage (char **new_msg, unsigned char cod, int size, char *content) {
int msg_len = size+6;
*new_msg = (char *)malloc(msg_len*sizeof(char));
(*new_msg)[0] = cod;
memcpy (((*new_msg)+1), &size, 4);
memcpy (((*new_msg)+5), content, size);
(*new_msg)[msg_len] = '\0';
//new_msg = msg;
return strlen (*new_msg);
}
int serverMessageProcessor (int *fd_in, int *out_fds) {
char *new_msg;
char *content_msg;
unsigned char cod_msg = 100;
int size_msg;
int msg_length;
char *tmp_PID_str;
uint64_t myPID;
uint64_t tempPID;
int fd;
if (readMessage (fd_in, &cod_msg, &size_msg, &content_msg) < 0) {
sys_error ("readMessage");
return -1;
}
printf ("(serverMessageProcessor) cod: %c - size: %d - msg: %s\n", cod_msg, size_msg, content_msg);
printf ("serverMessageProcessor - prima switch\n");
switch (cod_msg) {
case ('1'): {
fd = 0;
if ((myPID = getpid()) < 0) {
sys_error ("getpid");
return -1;
}
tmp_PID_str = (char *)malloc((size_msg+1)*sizeof(char));
tmp_PID_str[size_msg+1] = '\0';
printf ("serverMessageProcessor - prima memcpy(myPID) PID: %ld\n", myPID);
memcpy (tmp_PID_str, &myPID, sizeof(uint64_t));
printf ("serverMessageProcessor - dopo memcpy(myPID)\n");
if (strcmp (content_msg, tmp_PID_str) == 0) {
printf ("serverMessageProcessor - dopo strcmp TRUE (myPID, tempPID)\n");
closed_ring = 1;
} else {
//new_msg = (char *)malloc(size_msg+6)*sizeof(char));
printf ("serverMessageProcessor - dopo strcmp FALSE (myPID, tempPID)\n");
//msg_length = buildMessage (&new_msg, cod_msg, size_msg, content_msg);
msg_length = size_msg+6;
new_msg = (char *)malloc(msg_length*sizeof(char));
new_msg[0] = cod_msg;
memcpy (new_msg+1, &size_msg, 4);
memcpy (new_msg+5, content_msg, size_msg);
new_msg[msg_length] = '\0';
printf ("serverMessageProcessor - dopo buildMessage: %s\n", new_msg);
printf ("(serverMessageProcessor) cod: %c - size: %d - msg: %s\n", cod_msg, size_msg, content_msg);
if (write (out_fds[fd], &cod_msg, 1) < 0) {
sys_error ("write");
return -1;
}
if (write (out_fds[fd], &size_msg, 4) < 0) {
sys_error ("write");
return -1;
}
if (write (out_fds[fd], content_msg, size_msg) < 0) {
sys_error ("write");
return -1;
}
printf ("serverMessageProcessor - dopo write\n");
}
printf ("serverMessageProcessor - fuori if strcmp(myPID, tempPID)\n");
}
}
}
int main (int argc, char *argv[]) {
int listen_port, connection_port;
int connection;
int check = -1;
char *conn_addr;
char inter_lv = 'a';
int sock_in; //socket descriptor for reading.
int sock_out; //socket descriptor for writing.
struct sockaddr_in addr_in;
struct sockaddr_in addr_out;
int connection_flag = 0;
int out_fds[3];
/********************* VARIABILI GESTIONE MESSAGGI ************************/
char *new_msg = NULL;
char *content_msg = NULL;
unsigned char cod_msg;
int size_msg;
int msg_len;
uint64_t tempPID;
uint64_t myPID;
/**************************************************************************/
/********************** VARIABILI GESTIONE SOTTOPROCESSI ******************/
int pipe_IN[2];
int pipe_OUT[2];
int pipe_CLIENT[2];
int pid_client;
/**************************************************************************/
/***************************** VARIABILI PER SELECT SYSCALL ***************/
fd_set rfds;
struct timeval tv;
int retval;
/**************************************************************************/
if(readIntFromString(0, &listen_port, argv[1]) < 0){
printf("Invalid value of listen_port\n");
return -1;
}
if(listen_port >= 0 && listen_port <= 1023){
printf("Insert a port in range 0-1023\n");
return -1;
}
if(listen_port >= 49152){
printf("Insert a port not higher than 49152\n");
return -1;
}
if(readIntFromString(0, &connection_port, argv[2]) < 0){
printf("Invalid value of connection_port\n");
return -1;
}
if(connection_port >= 0 && connection_port <= 1023){
printf("Insert a port in range 0-1023\n");
return -1;
}
if(connection_port >= 49152){
printf("Insert a port not higher than 49152\n");
return -1;
}
conn_addr = argv[3];
if((toupper(argv[4][0]) == 'S' || toupper(argv[4][0]) == 'N') && argv[4][1] == '\0'){
inter_lv = toupper(argv[4][0]);
}else{
printf("Invalid Interactivity Level\n");
return -1;
}
/*********************** Circuit Building **************************/
if(setUpConnectionIn(listen_port, &sock_in) < 0) {
sys_error ("Errore in funzione: setUpConnectionIn");
return -1;
}
if (setUpConnectionOut (&sock_out, connection_port, conn_addr) < 0) {
sys_error ("Errore in funzione setUpConnectionOut");
return -1;
}
printf ("-------------out-connected-------------\n");
if ((connection = setUpConnectionIn_2 (sock_in)) < 0) {
sys_error ("Errore in funzione setUpConnectionIn_2");
return -1;
}
printf ("-------------in-connected--------------\n");
/**********************************************************************/
/* Controlla connection (socket in entrata) per vedere se è pronto per operazioni di I/O */
//retval = fcntl(connection, F_SETFL, fcntl(connection, F_GETFL) | O_NONBLOCK);
FD_ZERO(&rfds);
FD_SET(connection, &rfds);
out_fds[0] = sock_out;
/* Attende 5 secondi */
tv.tv_sec = 5;
tv.tv_usec = 0;
while (closed_ring == 0) {
if (connection_flag == 0) {
if ((myPID = getpid()) < 0) {
sys_error ("getpid");
return -1;
}
size_msg = sizeof(uint64_t);
msg_len = size_msg+6;
new_msg = (char*)malloc(msg_len*sizeof(char));
new_msg[0] = '1';
memcpy(new_msg+1, &size_msg, 4);
memcpy(new_msg+5, &myPID, size_msg);
new_msg[msg_len] = '\0';
printf ("(MAIN) myPID: %ld - cod: %c - size: %d - msg: %s\n", myPID, new_msg[0], size_msg, &(new_msg[5]));
if (write (out_fds[0], new_msg, msg_len) < 0) {
sys_error ("write");
return -1;
}
printf ("Message 1 (ring closing) sent: %s\n", new_msg);
connection_flag = 1;
}
retval = select(connection+1, &rfds, NULL, NULL, &tv);
if (retval == -1) {
sys_error ("select");
return -1;
} else if (retval) {
stampaStr("Available data on (in)socket\n", 1); /* FD_ISSET(0, &rfds) avrà valore TRUE */
/*************** DEBUG ************************
if (read (connection, &cod_msg, 1) == 0) {
sys_error ("read - main");
return -1;
} else {
printf ("read - main: %c\n", cod_msg);
}
**********************************************/
if (serverMessageProcessor (&connection, out_fds) < 0) {
sys_error ("serverMessageProcessor");
return -1;
}
} else {
stampaStr("None message in entry\n", 1);
char c = getchar();
fflush(stdin);
}
}
/* Creazione sottoprocesso per gestione connessioni con Client per iscrizione auto */
if (pipe(pipe_CLIENT) < 0) {
sys_error ("pipe_client");
return -1;
}
if ((pid_client = fork()) < 0) {
sys_error ("fork_client");
return -1;
} else if (pid_client == 0) { /* Processo figlio - accetta connessioni da Client */
printf("Subprocess to manage client(s) connection\n");
//while (1);
} else { /* Processo Padre */
printf("Parent process\n");
}
return 0;
}
When read() returns 0, it means the socket has been closed by the other end, it's not an error, so you shouldn't call sys_error(). An error is indicated by read() returning -1. That's why you're getting Success as the error message.
However, you've set the socket to be non-blocking, so read() will also return -1 when there's nothing available to be read. It will set errno = EAGAIN in this case, and the message for this is Resource temporarily Available.
You need to test for this and go back to your loop that waits for data with select(). This is normal for non-blocking sockets, so you shouldn't report it as an error.
So the code should be like:
if (read(*fd, &cod_msg, 1) == -1) {
if (errno == EAGAIN) {
return -2;
} else {
sys_error ("read - cod_msg");
return -1;
}
}
I've changed this to return -2 in the EAGAIN case, you'll need to change the caller to check for this so it doesn't call sys_error either.

Inappropriate ioctl (EVIOCGRAB) for 'keyboard' device

I am trying to debug evmuxd tool (physical keyboard multiplexer with switching support) from following github source.I installed bluez library and successfully compiled source code. However when I try to run as man page suggest I am getting following error:
sudo evmuxd /dev/input/event7
Could not grab keyboard for exclusive use: Inappropriate ioctl for device
From code below you can see that ioctl (fd, EVIOCGRAB, 1) returns error
#include <linux/input.h>
#include <linux/uinput.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#define UINPUT "/dev/uinput"
static int
open_uinput (const char *name)
{
int fd;
struct uinput_user_dev dev = { 0, };
int i;
fd = open (UINPUT, O_WRONLY | O_NDELAY);
if (fd == -1) {
perror (UINPUT);
return -1;
}
if (ioctl(fd, UI_SET_EVBIT, EV_KEY) == -1) {
perror ("Could not enable key events");
goto fail;
}
for (i = 0; i < KEY_CNT; i++) {
if (ioctl(fd, UI_SET_KEYBIT, i) == -1) {
perror ("Could not enable a key event");
goto fail;
}
}
if (ioctl(fd, UI_SET_EVBIT, EV_REP) == -1) {
perror ("Could not enable autorepeat events");
goto fail;
}
strncpy (dev.name, name, UINPUT_MAX_NAME_SIZE);
dev.id.bustype = BUS_VIRTUAL;
dev.id.vendor = 0x0666;
dev.id.product = 0x8086;
dev.id.version = 1;
if (write (fd, &dev, sizeof (dev)) != sizeof (dev)) {
perror (UINPUT);
goto fail;
}
if (ioctl(fd, UI_DEV_CREATE) == -1) {
perror ("Could not create the virtual keyboard");
goto fail;
}
return fd;
fail:
close (fd);
return -1;
}
static int
open_input (char *dev)
{
int version;
int features;
int fd;
int norepeat[2] = { 0, 0 };
fd = open (dev, O_RDWR);
if (fd == -1) {
perror (dev);
return -1;
}
if (ioctl (fd, EVIOCGVERSION, &version) == -1) {
perror ("Could not read input protocol version");
goto fail;
}
if (version >> 16 != EV_VERSION >> 16) {
fprintf (stderr, "Bad input subsystem version");
goto fail;
}
if (ioctl (fd, EVIOCGBIT(0, EV_MAX), &features) == -1) {
perror ("Could query device for supported features");
goto fail;
}
if (!(features & EV_KEY)) {
fprintf (stderr, "Device not capable of producing key press event.");
goto fail;
}
if (ioctl (fd, EVIOCGRAB, 1) == -1) {
perror ("Could not grab keyboard for exclusive use");
goto fail;
}
if (ioctl (fd, EVIOCSREP, norepeat) == -1) {
perror ("Could not disable autorepeat");
goto fail;
}
return fd;
fail:
close (fd);
return -1;
}
int
main (int argc, char *argv[])
{
int uinput[2], input;
struct input_event event;
int active = 0;
int switching = 0;
if (argc != 2) {
fprintf (stderr, "Usage: %s /dev/input/event<n>\n", argv[0]);
return 1;
}
input = open_input (argv[1]);
if (input == -1)
return 1;
uinput[0] = open_uinput ("evmuxd primary");
if (uinput[0] == -1)
return 1;
uinput[1] = open_uinput ("evmuxd secondary");
if (uinput[1] == -1)
return 1;
while (1) {
switch (read (input, &event, sizeof(event))) {
case -1:
perror ("Error reading from event device");
return 1;
case sizeof(event):
break;
default:
fprintf (stderr, "Short read from the event device.\n");
return 1;
}
switch (write (uinput[active], &event, sizeof(event))) {
case -1:
perror ("Error forwarding the event");
return 1;
case sizeof(event):
break;
default:
fprintf (stderr, "Short write forwarding the event.\n");
return 1;
}
if (event.type == EV_KEY
&& event.code == KEY_SCROLLLOCK
&& event.value == 0) {
switching = 1;
}
if (event.type == EV_SYN && switching) {
switching = 0;
active = !active;
}
}
return 0;
}
So what is the problem and how I can fix it?

c-code for parallax rfid reader on raspberry pi

I've searched for quite some time now for a solution to my problem.
I'd like to read RFID tags on my Raspberry, but I want to do it in C-code, as the rest of my project is written in C.
I have a few questions to the following C-code I found here on stackoverflow.com:
What .h includes do I need for the code below?
Where is the interface setup, that I'm using? (/dev/ttyAMA0)
Please help me to get this code snippet working right, as it's been holding me up for a few days already.
char read_rfid(char* rfid_num) {
fd_set input_fdset;
ssize_t length;
int done;
for(done=0; done < 14; ) {
FD_ZERO(&input_fdset);
FD_SET(fd,&input_fdset);
if(select(fd+1 ,&input_fdset, NULL,NULL,NULL) == -1) {
if (errno == EAGAIN) continue;
perror("Terminal select() failed");
return -1;
}
if(FD_ISSET(fd,&input_fdset)) {
if((length = read(fd,rfid_num+done,14-done)) == -1) {
if (errno == EAGAIN) continue;
perror("Terminal: read() failed");
return -1;
}
write(STDOUT_FILENO,rfid_num+done,length);
done += length;
}
}
return 0;
}
int setupRS232()
{
struct termios term_attr;
if((fd = open(RFID,O_RDWR)) == -1)
{
perror("Can't open Device");
return(1);
}
if(tcgetattr(fd,&term_attr) != 0)
{
perror("terminal: tcgetattr() failed");
return(1);
}
term_attr.c_cflag = BAUD|CS8|CRTSCTS|CLOCAL|CREAD;
term_attr.c_iflag = 0;
term_attr.c_oflag = 0;
term_attr.c_lflag = 0;
if(tcsetattr(fd,TCSAFLUSH,&term_attr) != 0)
{
perror("terminal: tcsetattr() failed");
return(1);
}
}
int main(int argc, char** argv)
{
char rfid_num[14];
int i;
if(setupRS232() == 1)
return(1);
puts("Waiting for transponder...");
read_rfid(rfid_num);
for(i=0;i<20;i++)
{
printf("%x\n",rfid_num[i]);
}
}
#include <unistd.h> // for read & write functions
#include <sys/select.h> // fd_set functions
#include <stdio.h> // for perror & printf family
#include <sys/types.h> // for open related function
#include <sys/stat.h> // for open related function
#include <fcntl.h> // for open related function
#include <termios.h> // for terminal functions
#include <errno.h> // for error code
#define RFID "path_to_rfid" // FIXME <- you should set this properly
char read_rfid(char* rfid_num, int fd)
{
fd_set input_fdset;
ssize_t length;
int done;
for(done=0; done < 14; ) {
FD_ZERO(&input_fdset);
FD_SET(fd,&input_fdset);
if(select(fd+1 ,&input_fdset, NULL,NULL,NULL) == -1) {
perror("Terminal select() failed");
return -1;
}
if(FD_ISSET(fd,&input_fdset)) {
if((length = read(fd,rfid_num+done,14-done)) == -1) {
perror("Terminal: read() failed");
return -1;
}
write(STDOUT_FILENO,rfid_num+done,length);
done += length;
}
}
return 0;
}
int setupRS232()
{
struct termios term_attr;
int fd = 0;
if((fd = open(RFID,O_RDWR)) == -1) {
perror("Can't open Device");
return(-1);
}
if(tcgetattr(fd,&term_attr) != 0)
{
perror("terminal: tcgetattr() failed");
close(fd);
return(-1);
}
term_attr.c_cflag = CBAUD|CS8|CRTSCTS|CLOCAL|CREAD;
term_attr.c_iflag = 0;
term_attr.c_oflag = 0;
term_attr.c_lflag = 0;
if(tcsetattr(fd,TCSAFLUSH,&term_attr) != 0) {
perror("terminal: tcsetattr() failed");
close(fd);
return(-1);
}
return (fd);
}
int main(int argc, char** argv)
{
char rfid_num[14];
int i;
int fd;
if((fd = setupRS232()) == -1) {
return(-1);
}
puts("Waiting for transponder...");
read_rfid(rfid_num, fd);
for(i=0;i<20;i++) {
printf("%x\n",rfid_num[i]);
}
return 0;
}
Now your code is ready to be compiled, at least in my machine I could compile with no errors.

Creating my own redirect and duplicate pipe functions

I am making a small shell and I am having some problems with two of my functions.
They are kind of out of context but I hope you can understand what I am trying to do so I don't have to post my whole code.
My dupPipe function:
I want to duplicate a pipe to a std I/O file descriptor and close both of the pipe ends. It looks like this: int dupPipe(int pip[2], int end, int destinfd);. Where end tells which pipe to duplicate, either READ_END or WRITE_END and destinfd tells which std I/O file descriptor to replace.
My Redirect function:
It's supposed to redirect a std I/O file descriptor to a file.
It looks like this, int redirect(char *file, int flag, int destinfd);.
Where flag indicate if the file should be read from or written to and destinfd is the std I/O file descriptor I want to redirect.
What I have done:
int dupPipe(int pip[2], int end, int destinfd)
{
if(end == READ_END)
{
dup2(pip[0], destinfd);
close(pip[0]);
}
else if(end == WRITE_END)
{
dup2(pip[1], destinfd);
close(pip[1]);
}
return destinfd;
}
Second function:
int redirect(char *filename, int flags, int destinfd)
{
if(flags == 0)
{
return destinfd;
}
else if(flags == 1)
{
FILE *f = fopen(filename, "w");
if(! f)
{
perror(filename);
return -1;
}
}
else if(flags == 2)
{
FILE *f = fopen(filename, "r");
if(! f)
{
perror(filename);
return -1;
}
}
return destinfd;
}
I appreciate any help given, what have I done wrong or haven't done with the function that I wrote wanted to? Thanks.
The redirect function doesn't appear to be doing what you want. You're opening a file using fopen, but you're not linking it to destinfd in any way. You probably want to use open instead, then use dup2 to move the file descriptor to where you want.
int redirect(char *filename, int flags, int destinfd)
{
int newfd;
if(flags == 0) {
return -1;
} else if(flags == 1) {
newfd = open(filename, O_WRONLY);
if (newfd == -1) {
perror("open for write failed");
return -1;
}
} else if(flags == 2) {
newfd = open(filename, O_RDONLY);
if (newfd == -1) {
perror("open for read failed");
return -1;
}
} else {
return -1;
}
if (dup2(newfd, destinfd) == -1) {
perror("dup2 failed");
close(newfd);
return -1;
}
close(newfd);
return destinfd;
}

Resources