#include <errno.h>
#include <signal.h>
#include <termios.h>
+#include <unistd.h>
#include "mopice.h"
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);
+int ring_waiter(int fh, int ring_numb, int ring_inter);
+int greetings_send(int fh, char *gree);
/*
* GLOBALS
*/
struct cmd init_cmds[] = {
- /* { "\x10!","OK", 3, CMD_TYPE_OPT } */
- /* { "\x10\x18","OK", 3, CMD_TYPE_OPT }
- , */ { "ATZ", "OK", 5, CMD_TYPE_MAND }
+ { "ATZ", "OK", 5, CMD_TYPE_MAND }
, { "AT", "OK\r\n", 3, CMD_TYPE_MAND }
- , { "ATL1", "OK\r\n", 3, CMD_TYPE_MAND }
+ , { "ATH0", "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+VGT=135", "OK\r\n", 3, CMD_TYPE_MAND }
, { "AT+VTX", "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+VLS=0", "OK\r\n", 3, CMD_TYPE_MAND }
, { "AT+FCLASS=0", "OK\r\n", 3, CMD_TYPE_MAND }
};
void alarm_sh(int sig)
{
- fprintf(stderr, "CATCHED %d\n", sig);
+ if (verbose >= 3) fprintf(stderr, "CATCHED %d\n", sig);
}
int read_reply(int fh, char *rep, time_t secs)
{
time_t tout;
- unsigned char bf[1024];
+ char bf[1024];
int bf_l, ret, i;
struct timespec ts;
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 (verbose >= 3) fprintf(stderr, "bf_l: %d %ld %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);
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));
+ if (verbose >= 2) fprintf(stderr, "send: [%s](%ld)\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 >= 1) fprintf(stderr, "ERROR: read_reply return %d\n", ret);
if (verbose >= 3) fprintf(stderr, "send_cmds::end1\n");
return 0;
}
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 >= 1) fprintf(stderr, "WARN: on command %d REPLY [%s] NOT ARRIVED\n", i, cmds[i].repl);
if (verbose >= 3) fprintf(stderr, "send_cmds::end3\n");
}
}
return 1;
}
-#define BAUDRATE B115200
+
+#define RING "RING\r\n"
+
+int ring_waiter(int fh, int ring_numb, int ring_inter)
+{
+ char bf[512];
+ int ret, ct_cur = 0;
+ struct timespec ts;
+ time_t tout = 0;
+
+ if (verbose >= 3) fprintf(stderr, "%s:: BEGIN\n", __FUNCTION__);
+
+ while ((ret = read(fh, bf, 511)) > 0) {
+ bf[ret] = '\0';
+ if (strstr(bf, RING)) {
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+
+ if (ct_cur > 0) {
+ if (ts.tv_sec < tout) {
+ if ((ct_cur + 1) == ring_numb) {
+ return (1);
+ }
+ }
+ else {
+ ct_cur = 0;
+ }
+ }
+ tout = ts.tv_sec + ring_inter;
+ ct_cur++;
+ }
+ if (verbose >= 3) fprintf(stderr, "%s:: ct_cur: %d\n", __FUNCTION__, ct_cur);
+ }
+ return 0;
+}
+
+int greetings_send(int fh, char *gree)
+{
+ FILE *fp;
+ int ret, i, e;
+ unsigned char bf[10240], bf2[10240];
+
+ /* sox greetings.wav -e unsigned-integer -b 8 -r 8000 -c 1 greetings.raw */
+ if ((fp = fopen(gree, "r")) == NULL) {
+ if (verbose >= 1) fprintf(stderr, "open greetings [%s] failed\n", gree);
+ return 0;
+ }
+ 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';
+ if (verbose >= 5) fprintf(stderr, "bf[%u] bf[%u]\n", bf[i], bf[i+1]);
+ }
+ else {
+ bf2[e] = bf[i];
+ }
+ }
+ write(fh, bf2, e);
+ }
+ fclose(fp);
+
+ return 1;
+}
+
/*
* MAIN
*/
+#define BAUDRATE B115200
+#define RECORD_LEN 60
+#define RING_NUMB 5
+#define RING_INTER 8
+#define GREETINGS "/var/spool/mopice/messages/greetings.raw"
+#define OUTPATH "/var/spool/mopice/incoming"
+#define SDEVICE "/dev/ttyS0"
+#define OUTFILE_FORMAT "%Y%m%d-%H%M%S"
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;
-
+ int i, e, ret;
+ unsigned char bf[10240], bf2[10240];
+ char outname[10240];
+ int ring_numb = RING_NUMB, ring_inter = RING_INTER;
struct timespec ts;
time_t tout;
+ int is_busy;
+ char outstr[200];
+ time_t t;
+ struct tm *tmp;
+
+ /* --- signal handling --- */
+ /* NOTE: without it using the more simple old school
+ signal()/alarm() the read syscall restart and not exit */
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");
+ if ((fh = open(SDEVICE, O_RDWR | O_NOCTTY)) == -1) {
+ if (verbose >= 1) fprintf(stderr, "tty open failed\n");
exit(1);
}
- ioctl( fh, TIOCNOTTY, 0 );
+ /* --- serial initialization --- */
+ 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);
+ 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);
- 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);
+ /* --- modem initialization --- */
+ ret = send_cmds(fh, init_cmds, sizeof(init_cmds) / sizeof(struct cmd));
+ if (verbose >= 1) fprintf(stderr, "INIT_CMDS: %d\n", ret);
+ if (ret == 0) {
+ exit (2);
}
-
- exit(123);
+ while (1) {
+ /* wait the right number of rings */
+#if 1
+ if (ring_waiter(fh, ring_numb, ring_inter) == 0) {
+ if (verbose >= 1) fprintf(stderr, "RING WAITER failed\n");
+ exit (2);
+ }
+#else
+ ring_numb = fgetc(stdin);
#endif
+ /* instruct modem for greetings message */
+ ret = send_cmds(fh, answ_cmds, sizeof(answ_cmds) / sizeof(struct cmd));
+ if (verbose >= 1) fprintf(stderr, "ANSW_CMDS: %d\n", ret);
+ if (ret == 0) {
+ exit(4);
+ }
+
+ /* send the greetings message */
+ /* NOTE: sox greetings.wav -e unsigned-integer -b 8 -r 8000 -c 1 greetings.raw */
+ if (greetings_send(fh, GREETINGS) == 0) {
+ exit(5);
+ }
- 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);
+ /* instruct modem to send a beep and start message recording */
+ ret = send_cmds(fh, recmsg_cmds, sizeof(recmsg_cmds) / sizeof(struct cmd));
+ if (verbose >= 1) fprintf(stderr, "RECMSG_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]);
+ /* record the message */
+ t = time(NULL);
+ tmp = localtime(&t);
+ if (tmp == NULL) {
+ if (verbose >= 1) fprintf(stderr, "localtime failed\n");
+ exit(6);
+ }
+ if (strftime(outstr, sizeof(outstr), OUTFILE_FORMAT, tmp) == 0) {
+ if (verbose >= 1) fprintf(stderr, "strftime failed\n");
+ exit(7);
+ }
+ sprintf(outname, "%s/%s.dli", OUTPATH, outstr);
+ if ((fp = fopen(outname, "w")) == NULL) {
+ exit(8);
+ }
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+ tout = ts.tv_sec + RECORD_LEN;
+
+ is_busy = 0;
+ while (is_busy == 0 && (ret = read(fh, bf, 4096)) > 0) {
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+ if (ts.tv_sec >= tout) {
+ if (verbose >= 3) fprintf(stderr, "read_reply::end1\n");
+ break;
}
- else {
+
+ for (i = 0, e = 0 ; i < ret ; i++, e++) {
+ if (bf[i] == '\x10') {
+ i++;
+ if (verbose >= 1) fprintf(stderr, "0x10 found followed by %d\n", bf[i]);
+ if (bf[i] == 'b') {
+ if (verbose >= 1) fprintf(stderr, "BUSY found, stop recording\n");
+ is_busy = 1;
+ break;
+ }
+ }
bf2[e] = bf[i];
}
+
+ fwrite(bf2, 1, e, fp);
+ fflush(fp);
}
- 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);
+
+ /* reset the modem for the next call */
+ ret = send_cmds(fh, clo_cmds, sizeof(clo_cmds) / sizeof(struct cmd));
+ if (verbose >= 1) fprintf(stderr, "CLO_CMDS: %d\n", ret);
}
- 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);
+ /* reset the serial to the old configs */
+
+ tcsetattr(fh, TCSANOW, &oldtio);
close(fh);