I'm trying to read the GPS data from a serial port, at the moment i can read the data. But im trying to get only the data from "$GPRMC" line only.
I have this code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
#include <sys/ioctl.h>
int main(int argc, char** argv) {
int sfd = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY);
if (sfd == -1) {
printf("Error no is : %d\n", errno);
printf("Error description is : %s\n", strerror(errno));
return (-1);
};
struct termios options;
tcgetattr(sfd, &options);
cfsetspeed(&options, B9600);
cfmakeraw(&options);
//options.c_cc[VTIME]=1;
//options.c_cc[VMIN]=100;
//tcflush(sfd, TCIFLUSH);
tcsetattr(sfd, TCSANOW, &options);
usleep(100000);
char serialBuffer[500];
int bytes;
int count;
ioctl(sfd, FIONREAD, &bytes);
int i =0;
char *ret;
char *sepa;
char sepa2[500];
int compare;
for(;;){
if(bytes!=0){
count = read(sfd, serialBuffer, sizeof(serialBuffer));
}
if (count == -1){
printf("ERROR");
break;
}
else if(count == 0){
printf("NODATA");
break;
}
else{
serialBuffer[count] = '\0';
//strcpy(serialBuffer2, serialBuffer);
//printf("%s,", serialBuffer);
sepa = strtok(serialBuffer, "\n");
while(sepa != NULL){
//printf("%s", sepa);
//strcpy(serialBuffer2, sepa);
sepa = strtok(NULL, "\n");
ret = strstr(sepa, "$GPRMC");
if (NULL != ret) {
printf("The substring is: %s\n", ret);
}
}
}
}
close(sfd);
return (EXIT_SUCCESS);
}
This script is always returning me "Segmentation Faul(Core Dumped)", and i dont know why. Im new at c, can any one help me on this?
Thanks
Related
I need to read an eeprom in an embedded device.
So far this "almost" worked:
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <fcntl.h>
#include <linux/i2c-dev.h>
#define READ_SIZE (256)
#define NB_PAGES (128)
void dump_to_file(const char *output_file_path,
const uint8_t *buffer, const int buffer_length)
{
int output_file = open(output_file_path, O_RDWR|O_APPEND|O_CREAT);
if (output_file < 0) {
printf("Failed opening output file %s\n", output_file_path);
return;
}
write(output_file, buffer, buffer_length);
}
int main(int argc, char *argv[])
{
/* got these values from i2cdetect */
const char *i2c_device = "/dev/i2c-4";
const int device_address = 0x50;
/* open the i2c device file */
int file = open(i2c_device, O_RDWR);
if (file < 0) {
printf("Failed opening %s\n", i2c_device);
return 1;
}
if (ioctl(file, I2C_SLAVE, device_address) < 0) {
printf("Failed addressing device at %02X\n", device_address);
close(file);
return 1;
}
int i = 0;
for (i = 0; i < NB_PAGES; i++) {
char buf[READ_SIZE] = {0};
if (read(file, buf, READ_SIZE) != READ_SIZE) {
printf("Failed reading\n");
close(file);
return 1;
}
dump_to_file(argv[1], buf, READ_SIZE);
}
close(file);
return 0;
}
By "almost" I mean that it dumps the full eeprom but the START depends on the last block read..
It's not always the same.
If I read 10 blocks. then run the program again I read the next ones and not the first 10.
How to set the starting address?
Update:
if I do:
i2cset -y 4 0x50 0x00 0x00
and the run the above code, it works.
so how can I put the equivalent of the i2cset command in the code?
Done!
It wasn't easy because I could not find documentations anywhere.. but I thought that since the eeprom is 32K, maybe it was "like" a 24c256. But even in that case I found nothing in userspace until I decided to go by instinct.
I studied i2cset source, understood what it did and put it in the code.
Here is the result, which dumps a full i2c 32k eprom from userspace.
Note a full backup and restore utility can be found here:
https://gist.github.com/Zibri/cf8ac0b311301aeeaa8910c7da824bff
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/i2c-dev.h>
#define READ_SIZE (256)
#define NB_PAGES (128)
void dump_to_file(const char *output_file_path,
const uint8_t *buffer, const int buffer_length)
{
int output_file = open(output_file_path, O_RDWR|O_APPEND|O_CREAT);
if (output_file < 0) {
printf("Failed opening output file %s\n", output_file_path);
return;
}
write(output_file, buffer, buffer_length);
}
int main(int argc, char *argv[])
{
const char *i2c_device = "/dev/i2c-4";
const int device_address = 0x50;
int file = open(i2c_device, O_RDWR);
if (file < 0) {
printf("Failed opening %s\n", i2c_device);
return 1;
}
if (ioctl(file, I2C_SLAVE, device_address) < 0) {
printf("Failed addressing device at %02X\n", device_address);
close(file);
return 1;
}
int i = 0;
write(file,'\x00\x00',2); // ADDRESS
for (i = 0; i < NB_PAGES; i++) {
char buf[READ_SIZE] = {0};
if (read(file, buf, READ_SIZE) != READ_SIZE) {
printf("Failed reading\n");
close(file);
return 1;
}
dump_to_file(argv[1], buf, READ_SIZE);
}
close(file);
return 0;
}
Teh function below causes a segmentation fault when it gets to the RSA_verify() part. I'm a c-beginner so it's hard for me to find the reason for the problem. Maybe someone can point out what I'm doing wrong. It would be very helpful, thanks in advance.
Here's the Code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <openssl/sha.h>
#include <openssl/dsa.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/rsa.h>
#include <openssl/bio.h>
#define BUF 20000
#define DSS 20
int matchCipherToSign(unsigned char *signPath, char *cipherPath) {
unsigned char *bufCipher = malloc(BUF);
unsigned char *sha = malloc(SHA_DIGEST_LENGTH);
unsigned char *bufSign = malloc(BUF);
unsigned int retSign;
int ret=0;
int retCipher;
FILE *key;
RSA *rsa = RSA_new();
EVP_MD_CTX ctx;
key = fopen("key.bin", "rb");
if (key == NULL){
printf("Couldn't open file key.bin.\n");
exit(EXIT_FAILURE);
}
retSign = readFile(signPath, bufSign);
if (retSign == 0){
printf("Couldn't read file %s.\n", signPath);
exit(EXIT_FAILURE);
}
retCipher = readFile(cipherPath, bufCipher);
if (retCipher == 0){
printf("Couldn't open file %s.\n", cipherPath);
exit(EXIT_FAILURE);
}
rsa = PEM_read_RSA_PUBKEY(key, &rsa, NULL, NULL);
fclose(key);
if (1!=EVP_DigestInit(&ctx, EVP_sha1())) {
printf("EVP_DigestInit Error.\n");
exit(EXIT_FAILURE);
}
if (1!=EVP_DigestUpdate(&ctx, bufCipher, retCipher)) {
printf("VP_DigestUpdate Error.\n");
exit(EXIT_FAILURE);
}
if (1!=EVP_DigestFinal(&ctx, sha, NULL)) {
printf("EVP_DigestFinal Error.\n");
exit(EXIT_FAILURE);
}
ret = RSA_verify(NID_sha1, sha, SHA_DIGEST_LENGTH, bufSign, sizeof(bufSign), rsa);
RSA_free(rsa);
free(bufCipher);
free(bufSign);
free(sha);
return ret;
}
Thanks for your help!
I'm new with PulseAudio. I'm trying to make simple programs. One would record the sound and save it in baniry file, and the other one should open it and play. Here is my code for recording:
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <pulse/simple.h>
#include <pulse/error.h>
#define BUFSIZE 32
int main(int argc, char*argv[])
{
/* The Sample format to use */
static const pa_sample_spec ss = {
.format = PA_SAMPLE_S16LE, //16bit iqneba agwerili tito sample
.rate = 44100, //number of samples played in each second
.channels = 2
};
pa_simple *s_in = NULL;
int ret = 1;
int error;
int siri =0;
//file info
FILE* pFile;
char* yourFilePath = "xma.bin";
pFile = fopen(yourFilePath,"wb");
if (!(s_in = pa_simple_new(NULL, argv[0], PA_STREAM_RECORD, NULL, "record", &ss, NULL, NULL, &error)))
{
fprintf(stderr, __FILE__": pa_simple_new() failed: %s\n", pa_strerror(error));
goto finish;
}
for (;siri<10000;siri+=1)
{
uint8_t buf[BUFSIZE];
ssize_t r;
int yorBufferSize = strlen(buf) + 1;
/* Write your buffer to disk. */
if (pa_simple_read(s_in, buf, sizeof(buf), &error) < 0)
{
fprintf(stderr, __FILE__": read() failed: %s\n", strerror(errno));
goto finish;
}
if (pFile)
{
fwrite(buf, yorBufferSize, 1, pFile);
puts("Wrote to file!");
}
else
{
puts("Something wrong writing to File.");
}
}
ret = 0;
finish:
if (s_in)
pa_simple_free(s_in);
return ret;
fclose(pFile);
}
And here is my recording program:
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <pulse/simple.h>
#include <pulse/error.h>
#define BUFSIZE 32
int main(int argc, char*argv[])
{
/* The Sample format to use */
static const pa_sample_spec ss = {
.format = PA_SAMPLE_S16LE, //16bit iqneba agwerili tito sample
.rate = 44100, //number of samples played in each second
.channels = 2
};
pa_simple *s_out = NULL;
int ret = 1;
int error;
//file info
FILE* pFile;
char* yourFilePath = "xma.bin";
pFile = fopen(yourFilePath, "rb");
/* Create a new playback stream */
if (!(s_out = pa_simple_new(NULL, argv[0], PA_STREAM_PLAYBACK, NULL, "playback", &ss, NULL, NULL, &error)))
{
fprintf(stderr, __FILE__": pa_simple_new() failed: %s\n", pa_strerror(error));
goto finish;
}
for (;;)
{
uint8_t buf[BUFSIZE];
fread(buf, sizeof(buf), 1, pFile);
ssize_t r;
if(feof(pFile))
{
break;
}
printf("%x", buf);
/* ... and play it */
if (pa_simple_write(s_out, buf, sizeof(buf), &error) < 0)
{
fprintf(stderr, __FILE__": pa_simple_write() failed: %s\n", pa_strerror(error));
goto finish;
}
}
/* Make sure that every single sample was played */
if (pa_simple_drain(s_out, &error) < 0)
{
fprintf(stderr, __FILE__": pa_simple_drain() failed: %s\n", pa_strerror(error));
goto finish;
}
ret = 0;
finish:
if (s_out)
pa_simple_free(s_out);
return ret;
fclose(pFile);
}
For loop in record program is just for time to record something(could not figure out how to set a timer) and I know that I should not use gotos but its for educational purposes(example provided on PulseAudio website). I tried hexdump of xma.bin and it gave me totally different ouput
than printf("%x", buf); Basically printf only gives back bf9fe15c repeatedly and it make annoying sound. Hope you can help. thanks.
I deleted pa_simple_drain() (it was my mistake that i used this function in recording program)function from record program and now it works. But in printf("%x", buf) it still gives me back same hex value over and over again. But programs work great. Can someone exmplain why does it print same value?
I am in the middle of writing a user level C program, that reads a SPI device and translate the results to a keyboard event.
I am now trying to pass emulate key event to /dev/uinput. A weird thing is happening, file operation is failing.
my_kbd.c
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <errno.h>
#include <linux/input.h>
#include <linux/uinput.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <fcntl.h>
#define PROG_NAME "c2h2_spi_kbd"
int fire_key(__u16);
int setup_uinputfd(const char *);
int close_uinputfd();
void write_uinput(__u16, __u16, __s32);
/*fd for uinput, we do need kernel to support uinput */
static int uinputfd = -1;
int main(int argc, char **argv){
puts("Welcome to use SPI keyboard program v0.1!");
uinputfd = setup_uinputfd(PROG_NAME);
if(uinputfd != -1){
fire_key(KEY_A);
}else{
puts("where is uinput ? do you have permission?\n");
}
close_uinputfd();
exit(0);
}
int fire_key(__u16 key){
write_uinput(EV_KEY, key, 1);
return 0;
}
void write_uinput(__u16 type, __u16 code, __s32 value){
struct input_event ie;
sleep(1);
memset(&ie, 0, sizeof(ie));
ie.type = type;
ie.code = code;
ie.value = value;
if(write(uinputfd, &ie, sizeof(ie)) != sizeof(ie)) puts("ERR1");
memset(&ie, 0, sizeof(ie));
ie.type = EV_SYN;
ie.code = SYN_REPORT;
ie.value = 0;
if(write(uinputfd, &ie, sizeof(ie)) != sizeof(ie)) puts("ERR2");
}
int close_uinputfd(){
close(uinputfd);
return 0;
}
int setup_uinputfd(const char *name){
int fd;
int key;
struct uinput_user_dev dev;
fd = open("/dev/input/uinput", O_RDWR);
if (fd == -1) {
fd = open("/dev/uinput", O_RDWR);
if (fd == -1) {
fd = open("/dev/misc/uinput", O_RDWR);
if (fd == -1) {
fprintf(stderr, "could not open %s\n", "uinput");
perror(NULL);
return -1;
}
}
}
memset(&dev, 0, sizeof(dev));
strncpy(dev.name, name, sizeof(dev.name));
dev.name[sizeof(dev.name) - 1] = 0;
if (write(fd, &dev, sizeof(dev)) != sizeof(dev) ||
ioctl(fd, UI_SET_EVBIT, EV_KEY) != 0
|| ioctl(fd, UI_SET_EVBIT, EV_REP) != 0) {
goto setup_error;
}
for (key = KEY_RESERVED; key <= KEY_UNKNOWN; key++) {
if (ioctl(fd, UI_SET_KEYBIT, key) != 0) {
goto setup_error;
}
}
if (ioctl(fd, UI_DEV_CREATE) != 0) {
goto setup_error;
}
return fd;
setup_error:
fprintf(stderr, "could not setup %s\n", "uinput");
perror(NULL);
close(fd);
return -1;
}
gcc -Wall my_kbd.c && sudo ./a.out
without sleep(1); I never have uinput event happen. with sleep(1);, this works perfect. (emulate keys output to focused program)
I do suspect this could be a cache problem, but fsync(fd); did not help. Please help.
Why does the following code print ‘read(): Resource temporarily unavailable’ 80% of the time? That is the EAGAIN code, which is the same as WOULD BLOCK which means there is no data waiting to be read, but select is returning 1 saying there is data (tested in Linux):
#include <time.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/errno.h>
int main(int argc, char** argv)
{
int fd = open("/dev/lp0", O_RDWR | O_NONBLOCK);
int ret = 0;
int status = 0;
char buffer[1024];
char teststr[] = "This is a test\n";
char XMIT_STATUS_OFFLINE[] = {0x10,0x04,0x02};
char XMIT_STATUS_ERROR[] = {0x10,0x04,0x03};
char XMIT_STATUS_ROLL[] = {0x10,0x04,0x04};
char XMIT_STATUS_SLIP[] = {0x10,0x04,0x05};
fd_set rfds;
FD_ZERO( &rfds );
FD_SET( fd, &rfds );
struct timeval sleep;
sleep.tv_sec = 5;
sleep.tv_usec = 0;
/* Offline status */
ret = write(fd, XMIT_STATUS_OFFLINE, sizeof(XMIT_STATUS_OFFLINE));
//printf("write() returned %d\n", ret);
do {
ret = select( fd + 1, &rfds, NULL, NULL, &sleep );
} while (ret < 0 && (errno == EINTR));
ret = read(fd, buffer, 1024);
if(ret == -1) {
perror("read(): ");
} else {
status = buffer[0];
if((status & 0x04) != 0)
{
printf("The cover is open.\n");
} else {
printf("OFFLINE is good.\n");
}
}
close(fd);
return 0;
}
Your select call will return 0 after the 5 second timeout elapses if no data is available. Your code will ignore this and try to read from the device anyways. Check for ret == 0 and that will fix your problem.