Created
August 2, 2020 09:05
-
-
Save sergei-mironov/5e0cea0154c9ce4794489a2e1dc93b76 to your computer and use it in GitHub Desktop.
minimalistic C program which sends AT-command to GSM modem
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <errno.h> | |
#include <fcntl.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <termios.h> | |
#include <unistd.h> | |
int set_interface_attribs(int fd, int speed) | |
{ | |
struct termios tty; | |
memset(&tty, 0, sizeof(tty)); | |
if (tcgetattr(fd, &tty) < 0) { | |
printf("Error from tcgetattr: %s\n", strerror(errno)); | |
return -1; | |
} | |
cfsetospeed(&tty, (speed_t)speed); | |
cfsetispeed(&tty, (speed_t)speed); | |
tty.c_cflag |= (CLOCAL | CREAD); /* ignore modem controls */ | |
tty.c_cflag &= ~CSIZE; | |
tty.c_cflag |= CS8; /* 8-bit characters */ | |
tty.c_cflag &= ~PARENB; /* no parity bit */ | |
tty.c_cflag &= ~CSTOPB; /* only need 1 stop bit */ | |
tty.c_cflag &= ~CRTSCTS; /* no hardware flowcontrol */ | |
/* setup for non-canonical mode */ | |
tty.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON); | |
tty.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN); | |
tty.c_oflag &= ~OPOST; | |
/* fetch bytes as they become available */ | |
tty.c_cc[VMIN] = 1; | |
tty.c_cc[VTIME] = 1; | |
if (tcsetattr(fd, TCSANOW, &tty) != 0) { | |
printf("Error from tcsetattr: %s\n", strerror(errno)); | |
return -1; | |
} | |
return 0; | |
} | |
void set_mincount(int fd, int mcount) | |
{ | |
struct termios tty; | |
if (tcgetattr(fd, &tty) < 0) { | |
printf("Error tcgetattr: %s\n", strerror(errno)); | |
return; | |
} | |
tty.c_cc[VMIN] = mcount ? 1 : 0; | |
tty.c_cc[VTIME] = 5; /* half second timer */ | |
if (tcsetattr(fd, TCSANOW, &tty) < 0) | |
printf("Error tcsetattr: %s\n", strerror(errno)); | |
} | |
int main() | |
{ | |
char *portname = "/dev/ttyUSB0"; | |
int fd; | |
int wlen; | |
fd = open(portname, O_RDWR | O_NOCTTY | O_SYNC); | |
if (fd < 0) { | |
printf("Error opening %s: %s\n", portname, strerror(errno)); | |
return -1; | |
} | |
/*baudrate 115200, 8 bits, no parity, 1 stop bit */ | |
set_interface_attribs(fd, B115200); | |
//set_mincount(fd, 0); /* set to pure timed read */ | |
/* simple output */ | |
wlen = write(fd, "ATI\r\n", 5); | |
if (wlen != 5) { | |
printf("Error from write: %d, %d\n", wlen, errno); | |
} | |
tcdrain(fd); /* delay for output */ | |
/* simple noncanonical input */ | |
do { | |
unsigned char buf[80]; | |
int rdlen; | |
rdlen = read(fd, buf, sizeof(buf) - 1); | |
if (rdlen > 0) { | |
#define DISPLAY_STRING | |
#ifdef DISPLAY_STRING | |
buf[rdlen] = 0; | |
printf("Read %d: \"%s\"\n", rdlen, buf); | |
#else /* display hex */ | |
unsigned char *p; | |
printf("Read %d:", rdlen); | |
for (p = buf; rdlen-- > 0; p++) | |
printf(" 0x%x", *p); | |
printf("\n"); | |
#endif | |
} else if (rdlen < 0) { | |
printf("Error from read: %d: %s\n", rdlen, strerror(errno)); | |
} else { /* rdlen == 0 */ | |
printf("Timeout from read\n"); | |
} | |
/* repeat read to get full message */ | |
} while (1); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment