--- /dev/null
+/*
+ * mopice.c
+ *
+ * Copyright (C) 2011
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABLILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details. You should have received a
+ * copy of the GNU General Public License along with this program; if
+ * not, write to the Free Software Foundation, Inc, 59 Temple Place -
+ * Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <string.h>
+#include <time.h>
+#include <errno.h>
+#include <signal.h>
+#include <termios.h>
+
+#include "mopice.h"
+
+/*
+ * STRUCTURES
+ */
+
+#define CMD_TYPE_MAND 1
+#define CMD_TYPE_OPT 2
+
+struct cmd {
+ char *snd;
+ char *repl;
+ int wai;
+ int type;
+};
+
+
+/*
+ * PROTOTYPES
+ */
+void alarm_sh(int sig);
+int read_reply(int fh, char *reply, time_t secs);
+int send_cmds(int fh, struct cmd *cmds, int cmds_n);
+
+
+/*
+ * GLOBALS
+ */
+struct cmd init_cmds[] = {
+ /* { "\x10!","OK", 3, CMD_TYPE_OPT } */
+ /* { "\x10\x18","OK", 3, CMD_TYPE_OPT }
+ , */ { "ATZ", "OK", 5, CMD_TYPE_MAND }
+ , { "AT", "OK\r\n", 3, CMD_TYPE_MAND }
+ , { "ATL1", "OK\r\n", 3, CMD_TYPE_MAND }
+ , { "ATE1", "OK\r\n", 3, CMD_TYPE_MAND }
+ , { "ATM2", "OK\r\n", 3, CMD_TYPE_MAND }
+};
+
+struct cmd answ_cmds[] = {
+ { "AT+FCLASS=8", "OK\r\n", 3, CMD_TYPE_MAND }
+ , { "AT+VLS=1", "OK\r\n", 3, CMD_TYPE_MAND }
+ /* , { "AT+VGT=255", "OK\r\n", 3, CMD_TYPE_MAND } */
+ , { "AT+VTX", "CONNECT\r\n", 5, CMD_TYPE_MAND }
+};
+
+struct cmd rec_cmds[] = {
+ /* { "ATH1", "OK", 3, CMD_TYPE_MAND } */
+ { "AT+FCLASS=8", "OK\r\n", 3, CMD_TYPE_MAND }
+ , { "AT+VSD=129,200", "OK\r\n", 3, CMD_TYPE_MAND }
+ , { "AT+VLS=1", "OK\r\n", 3, CMD_TYPE_MAND }
+ , { "AT+VRX", "CONNECT\r\n", 5, CMD_TYPE_MAND }
+};
+
+struct cmd recmsg_cmds[] = {
+ { "\x10\x03","OK\r\n", 3, CMD_TYPE_MAND }
+ , { "AT+VSD=129,200", "OK\r\n", 3, CMD_TYPE_MAND }
+ , { "AT+VGR=255", "OK\r\n", 3, CMD_TYPE_MAND }
+ , { "AT+VTD=80", "OK\r\n", 3, CMD_TYPE_MAND }
+ , { "AT+VTS=[933,0]", "OK\r\n", 3, CMD_TYPE_MAND }
+ , { "AT+VLS=1", "OK\r\n", 3, CMD_TYPE_MAND }
+ , { "AT+VRX", "CONNECT\r\n", 5, CMD_TYPE_MAND }
+};
+
+struct cmd clo_cmds[] = {
+ /* { "\x10\x18","OK", 3, CMD_TYPE_MAND } */
+ /* { "\x10\x1c","", 3, CMD_TYPE_MAND } */
+ /* , { "\x10!\x10\x18\x10\x03","\x10\x62", 3, CMD_TYPE_MAND }
+ , { "\x10!\x10\x18\x10\x03","\x10\x62", 3, CMD_TYPE_MAND } */
+ { "\x10\x03","OK\r\n", 3, CMD_TYPE_MAND }
+ , { "AT", "OK\r\n", 3, CMD_TYPE_MAND }
+ , { "AT+FCLASS=0", "OK\r\n", 3, CMD_TYPE_MAND }
+};
+
+int verbose = 0;
+
+
+/*
+ * FUNCTIONS
+ */
+
+void alarm_sh(int sig)
+{
+ fprintf(stderr, "CATCHED %d\n", sig);
+}
+
+int read_reply(int fh, char *rep, time_t secs)
+{
+ time_t tout;
+ unsigned char bf[1024];
+ int bf_l, ret, i;
+ struct timespec ts;
+
+ if (verbose >= 3) fprintf(stderr, "read_reply::begin\n");
+
+ strcpy(bf,"");
+ bf_l = 0;
+
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+ tout = ts.tv_sec + secs;
+
+ while (1) {
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+ if (ts.tv_sec >= tout) {
+ if (verbose >= 3) fprintf(stderr, "read_reply::end1\n");
+ break;
+ }
+ alarm((unsigned int)secs + 1);
+ if (bf_l == sizeof(bf)) {
+ if (verbose >= 3) fprintf(stderr, "read_reply::end2\n");
+ return (-2);
+ }
+ if (verbose >= 3) fprintf(stderr, "read_reply::pre_read\n");
+ ret = read(fh, &(bf[bf_l]), 512 - bf_l);
+ if (verbose >= 3) fprintf(stderr, "read_reply::post_read %d\n", ret);
+ if (verbose >= 3) {
+ for (i = 0 ; i < ret ; i++) {
+ fprintf(stderr, "xx %02x ", bf[bf_l+i]);
+ if (i % 16 == 15) {
+ fprintf(stderr, "\n");
+ }
+ }
+ if (i % 16 != 15)
+ fprintf(stderr, "\n");
+ }
+ if (ret < 0) {
+ if (errno == EINTR) {
+ if (verbose >= 3) fprintf(stderr, "read_reply::end3\n");
+ return (0);
+ }
+ else {
+ if (verbose >= 3) fprintf(stderr, "read_reply::end4\n");
+ return (-1);
+ }
+ }
+ alarm(0);
+ bf[bf_l+ret] = '\0';
+ bf_l = strlen(bf);
+ fprintf(stderr, "bf_l: %d %d %p\n", bf_l, strlen(rep), strstr(bf, rep));
+ if (strstr(bf, rep)) {
+ if (verbose >= 3) fprintf(stderr, "read_reply::end5\n");
+ if (verbose >= 2) fprintf(stderr, "RET: [%s]\n", bf);
+ return (1);
+ }
+ }
+
+ if (verbose >= 3) fprintf(stderr, "read_reply::end6\n");
+ return (0);
+}
+
+int send_cmds(int fh, struct cmd *cmds, int cmds_n)
+{
+ char bf[512];
+ int i, ret;
+
+ if (verbose >= 3) fprintf(stderr, "send_cmds::begin\n");
+
+ for (i = 0 ; i < cmds_n ; i++) {
+ if (verbose >= 2) fprintf(stderr, "send: [%s](%d)\n", cmds[i].snd,strlen(cmds[i].snd));
+ sprintf(bf, "%s\r\n", cmds[i].snd);
+ write(fh, bf, strlen(bf));
+ ret = read_reply(fh, cmds[i].repl, cmds[i].wai);
+
+ if (verbose >= 3) fprintf(stderr, "send_cmds::read_reply return %d\n", ret);
+ if (ret < 0) {
+ fprintf(stderr, "ERROR: read_reply return %d\n", ret);
+ if (verbose >= 3) fprintf(stderr, "send_cmds::end1\n");
+ return 0;
+ }
+ else if (ret == 0) {
+ if (verbose >= 3) fprintf(stderr, "DE CHE: %d\n", cmds[i].type);
+ if (cmds[i].type == CMD_TYPE_MAND) {
+ if (verbose >= 3) fprintf(stderr, "send_cmds::end2\n");
+ return 0;
+ }
+ else if (cmds[i].type == CMD_TYPE_OPT) {
+ fprintf(stderr, "WARN: on command %d REPLY [%s] NOT ARRIVED\n", i, cmds[i].repl);
+ if (verbose >= 3) fprintf(stderr, "send_cmds::end3\n");
+ }
+ }
+ }
+
+ if (verbose >= 3) fprintf(stderr, "send_cmds::end4\n");
+ return 1;
+}
+
+#define BAUDRATE B115200
+/*
+ * MAIN
+ */
+int main(int argc, char *argv[])
+{
+ int fh;
+ FILE *fp;
+ struct termios oldtio,newtio;
+ struct sigaction sa;
+ int i, e, a, n, ret;
+ unsigned char bf[10240], bf2[10240], c;
+
+ struct timespec ts;
+ time_t tout;
+
+ sa.sa_handler = alarm_sh;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = 0;
+ if (sigaction(SIGALRM, &sa, NULL))
+ exit(1);
+
+ if ((fh = open("/dev/ttyS0", O_RDWR | O_NOCTTY)) == -1) {
+ fprintf(stderr, "open failed\n");
+ exit(1);
+ }
+ ioctl( fh, TIOCNOTTY, 0 );
+
+
+ tcgetattr(fh,&oldtio); /* save current serial port settings */
+ bzero(&newtio, sizeof(newtio));
+ newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD;
+ newtio.c_iflag = IGNPAR;
+ newtio.c_oflag = 0;
+
+ /* set input mode (non-canonical, no echo,...) */
+ newtio.c_lflag = 0;
+
+ newtio.c_cc[VTIME] = 0; /* inter-character timer unused */
+ newtio.c_cc[VMIN] = 1; /* blocking read until 5 chars received */
+
+ tcflush(fh, TCIFLUSH);
+ tcsetattr(fh,TCSANOW,&newtio);
+
+
+ printf("SIZE: %d NCMD: %d\n", sizeof(init_cmds), sizeof(init_cmds) / sizeof(struct cmd));
+
+ ret = send_cmds(fh, init_cmds, sizeof(init_cmds) / sizeof(struct cmd));
+ fprintf(stderr, "INIT_CMDS: %d\n", ret);
+
+ a = fgetc(stdin);
+
+#if 0
+ if ((fp = fopen("output.raw", "w")) == NULL) {
+ exit(3);
+ }
+ ret = send_cmds(fh, rec_cmds, sizeof(rec_cmds) / sizeof(struct cmd));
+ fprintf(stderr, "ANSW_CMDS: %d\n", ret);
+
+ while ((ret = read(fh, bf2, 4096)) > 0) {
+ fwrite(bf2, 1, ret, fp);
+ fflush(fp);
+ }
+
+ exit(123);
+#endif
+
+
+ if ((fp = fopen("greetings.dli", "r")) == NULL) {
+ exit(3);
+ }
+ ret = send_cmds(fh, answ_cmds, sizeof(answ_cmds) / sizeof(struct cmd));
+ fprintf(stderr, "ANSW_CMDS: %d\n", ret);
+
+ while ((ret = fread(bf, 1, 512, fp)) > 0) {
+ for (i = 0, e = 0 ; i < ret ; i++, e++) {
+ if (bf[i] == '\x10') {
+ bf2[e++] = '\x10';
+ bf2[e] = '\x10';
+ fprintf(stderr, "bf[%u] bf[%u]\n", bf[i], bf[i+1]);
+ }
+ else {
+ bf2[e] = bf[i];
+ }
+ }
+ write(fh, bf2, e);
+ }
+ fclose(fp);
+
+ ret = send_cmds(fh, recmsg_cmds, sizeof(recmsg_cmds) / sizeof(struct cmd));
+ fprintf(stderr, "RECMSG_CMDS: %d\n", ret);
+ if ((fp = fopen("output_new.raw", "w")) == NULL) {
+ exit(3);
+ }
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+ tout = ts.tv_sec + 10;
+
+ while ((ret = read(fh, bf2, 4096)) > 0) {
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+ if (ts.tv_sec >= tout) {
+ if (verbose >= 3) fprintf(stderr, "read_reply::end1\n");
+ break;
+ }
+ fwrite(bf2, 1, ret, fp);
+ fflush(fp);
+ }
+ fclose(fp);
+
+ ret = send_cmds(fh, clo_cmds, sizeof(clo_cmds) / sizeof(struct cmd));
+ fprintf(stderr, "CLO_CMDS: %d\n", ret);
+
+
+ tcsetattr(fh,TCSANOW,&oldtio);
+
+ close(fh);
+
+ exit (0);
+ return (0);
+}