📄 ttyaccess.c
字号:
/*************************************************************************** * copyright : (C) 2002 by Hendrik Sattler * * mail : post@hendrik-sattler.de * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/#include "common.h"#include "helpers.h"#include "depincludes.h"#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <errno.h>#include <string.h>#include <stdlib.h>#include <fcntl.h>speed_t tty_speed(char *newttyspeed){ switch(atoi(newttyspeed)){ case 9600: return B9600; break; case 19200: return B19200; break; case 38400: return B38400; break;#ifdef B57600 case 57600: return B57600; break;#endif#ifdef B115200 case 115200: return B115200; break;#endif default: myprintf(0,"No valid baudrate defined. Using compiled in value...\n"); return tty_speed(TTYSPEED); break; }}void tty_open(char* ttyport, speed_t baudrate, unsigned int timeout, unsigned int ignore_serial_bits){ int flags=O_RDWR | O_NOCTTY | O_NONBLOCK; // int flags=O_RDWR | O_NOCTTY; struct termios newtio; //opening the device myprintf(0,"Accessing device %s\n",ttyport); if ((mytty=open(ttyport,flags)) == -1){ myprintf(0,"Error on opening device.\n%s\n",strerror(errno)); exit(1); } if (fcntl(mytty,F_SETFL,0) == -1) { fprintf(stderr,"Error in setting port attributes: %s\n",strerror(errno)); exit(1); } if (!ignore_serial_bits) { //getting port parameters if (tcgetattr(mytty,&newtio) < 0){ fprintf(stderr,"Error in getting device attributes: %s\n",strerror(errno)); exit(1); } } else { memset(&newtio,0,sizeof(newtio)); } cfsetispeed(&newtio, baudrate); //input at baudrate cfsetospeed(&newtio, baudrate); //ouput at baudrate cfmakeraw(&newtio); //make raw, 8N1 /* CLOCAL: ignore modem control lines * CREAD: enable receiver * ~CSTOPB: do not send two stop bits (but one) */ newtio.c_cflag |= (CLOCAL | CREAD); newtio.c_cflag &= ~CSTOPB; newtio.c_cc[VMIN]=0; //be comfortable with returning this amount of characters newtio.c_cc[VTIME]=10*timeout; //try reading for this amount of time (in deciseconds) tcflush(mytty, TCIOFLUSH); //clear serial tty if(tcsetattr(mytty,TCSANOW,&newtio) < 0){ //set now fprintf(stderr,"Error in setting device attributes: %s\n",strerror(errno)); exit(1); }}char* tty_write_read(char *at_command_p){ //write to the port... tty_write_command(at_command_p); //...and read it to get the acknowledge or data return tty_read(at_command_p);}void tty_write_command(const char *at_command_p){ //Writing to the device myprintf(1,"\nSending: %s\n",at_command_p); if (tty_write(at_command_p,strlen(at_command_p),"\r") == -1) { errexit("Error on sending at command: %s\n",strerror(errno)); }}int tty_write_data (const char* data, size_t count) { return tty_write(data,count,"\x1a");}int tty_write (const char* data, size_t count, const char* finish) { int status=0; int instatus; do { instatus=write(mytty,&data[status],count-status); if (instatus != -1) { status+=instatus; } else if (status == -1 && errno==EAGAIN) { usleep(1); } } while ((status==-1 && errno==EAGAIN) || status<count); if (status!=-1 && strlen(finish)) { status=0; do { instatus=write(mytty,&finish[status],strlen(finish)-status); if (instatus != -1) { status+=instatus; } else if (status == -1 && errno==EAGAIN) { usleep(1); } } while ((status==-1 && errno==EAGAIN) || status<strlen(finish)); } return status;}/* This function returns a char* that must be freed. * If it returns NULL, there was an error. Look at errno for the reason. * If the strlen(char*)==0, reading from the device timed out. Retry or abort. * (the timeout might only happen when the device was not opened with O_NOBLOCK, * the timeout time refers to the value that was set as c_cc[VTIME]) */char* tty_readline (){ char* retval; int retvalsize=0; int status; char buffer; //buffer the read character for checks int counter=0; //count the read-and-used characters int repeat=0; //tell the inner loop to loop retval=NULL; do { do { status=read(mytty,&buffer,1); if (status == -1) { if (errno==EAGAIN) { usleep(1); repeat=1; } else { return NULL; } } else if (status==0) { return str_dup(""); } else { repeat=0; } } while (repeat); // allocate space on stack if (counter>=retvalsize) { retvalsize+=BUFSIZ; retval=mem_realloc(retval,retvalsize+1); memset(retval+counter,0,retvalsize-counter+1); } if (buffer==0) { /* fix the @=0x00 problem here :-( * we simply add the eigth bit, so when processing: * only look at the last 7 bits (char&127) */ retval[counter++]=128; } else { retval[counter++]=buffer; } } while (buffer!='\n' && !(retval[0]=='>' && counter>1)); /* There are two types of possible answers: * "><space>" (2 character) for data input requests * "....<CR><LF>" for all other things (even empty) */ return mem_realloc(retval,strlen(retval)+1);}char* tty_read (char *at_command_p){ char* value; char* temp; char tempat[BUFSIZ]; // int rcount=0; //count, how often we tried to read int repeat; value=NULL; do { repeat=0; value=tty_readline(); if (value==NULL) { errexit("Error on reading from device: %s\n", strerror(errno)); } else if (strlen(value)==0) { errexit("Reading from the device timed out.\n"); /* value=mem_realloc(value,0); ++rcount; if (rcount < 3) { myprintf(1,"Waiting for an answer from the phone: Timed out. %s\n","Retrying..."); tcflush(mytty, TCIOFLUSH); tty_write_command(at_command_p); repeat=1; } else { errexit("Waiting for an answer from the phone: Timed out. %s\n","Aborting."); }*/ } else { if ((temp=index(value,'\r')) || (temp=index(value,'\n'))) { //we don't want values 13=<CR>='\r' and 10=<LF>='\n' in our strings memset(temp,0,1); //we do not want to return empty strings //we do not accept the at_command_p as answer if (strlen(value)==0 || !strcmp(value,at_command_p)) { value=mem_realloc(value,0); repeat=1; } } } } while (repeat); myprintf(1,"Received: %s\n",value); //PIN handling for all function is done transparently here if (!strncmp(value,"+CME ERROR: ",12) && (strstr(value+12,"PIN")!=NULL || strstr(value+12,"PUK")!=NULL)) { if (strlen(PIN)==0) { errexit("%s\nUse the --pin parameter\n",value+12); } else { memset(tempat,0,sizeof(tempat)); new_at_command(tempat,"+CPIN"); add_at_command(tempat,"=\"%s\"",PIN); mem_realloc(value,0); value=tty_write_read(tempat); if (strcmp(value,"OK")) { errexit("Error on using pin: %s\n",value+12); } mem_realloc(value,0); value=tty_write_read(at_command_p); } } else if (!strncmp(value,"RING",4)) { mem_realloc(value,0); value=tty_read(at_command_p); } return mem_realloc(value,strlen(value)+1);}void tty_close(){ close(mytty);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -