//
// main.c
// USB Reader
//
// Created by Mark Amos on 12/7/12.
// Copyright (c) 2012 Mark Amos. All rights reserved.
//
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int get_fld(char *, int);
int hex_to_ascii(int, int);
int hex_to_int(int);
int write_web_page(char *, char *, char *);
int main(int argc, const char * argv[])
{
int msg_len;
int msg_end;
long fld_type;
long fld_len;
char fld_val [64] = "";
int str_ptr;
char str_date_time [20] = " / : ";
char str_nbr [20] = " - - ";
char str_nam [64] = "";
char str_input [256] = "\0";
// Send configuration strings to modem
// On Raspberry Pi, leaving echo on and status messages on causes problems with some kind of "loop back" on the
// /dev/ttyACM0 port. So, we have to turn them off.
FILE *out_file;
out_file = fopen("/dev/tty.usbmodem0000001", "w");
if (out_file == NULL) {
fprintf(stderr, "Can't open output file\n");
}
fprintf(out_file,"ATE0\n"); // Turn off echo
fprintf(out_file,"ATQ1\n"); // Turn off status messages
fprintf(out_file,"AT#CID=2\n"); // Turn on unformatted Caller ID
fclose(out_file);
// Open modem for input
FILE *in_file;
in_file = fopen("/dev/tty.usbmodem0000001", "r");
if (in_file == NULL) {
fprintf(stderr, "Can't open input file\n");
}
// loop getting input from modem
while (fgets(str_input, 250, in_file) != NULL ){ // Check to see if there's input available
if(strstr(str_input,"MESG=80")){ // Check to see if we received a CID message
// Get Message Length
str_ptr = 7; // position pointer to point at the message length field
msg_len = get_fld(str_input, str_ptr);
msg_end = (msg_len * 2) + 8; // Adjust for two bytes per hexx digit, plus "header" + length
str_ptr+=2; // position pointer to point to the start of first field
while (str_ptr < msg_end){ // Parse message while there's still input to be had
fld_type = get_fld(str_input, str_ptr); // Get Field Type
str_ptr+=2;
fld_len = get_fld(str_input, str_ptr); // Get Field Length
str_ptr+=2;
fld_len = fld_len * 2;
int j = 0; // Get Field Value
for (int i=str_ptr; i< fld_len + str_ptr - 1; i+=2){
fld_val[j++] = hex_to_ascii(str_input[i], str_input[i+1]);
fld_val[j] = '\0';
}
str_ptr += fld_len; // decode field values using field type
switch (fld_type) {
case 1: {
strcpy(str_date_time, fld_val);
} break;
case 2: {
strcpy(str_nbr, fld_val);
} break;
case 4: {
strcpy(str_nbr, "No Number");
} break;
case 7: {
strcpy(str_nam, fld_val);
} break;
case 8: {
strcpy(str_nam, "No Name");
} break;
}
} // end while parse message
printf("Date: %s\n",str_date_time);
printf("Number: %s\n",str_nbr);
printf("Name: %s\n",str_nam);
write_web_page(str_date_time, str_nbr, str_nam);
}
else { // else extraneous input (i.e. not MESG=...)
printf("%s\n",str_input); // shouldn't be any - we turned off echo and status messages
}
} // end while fgets
} // end main()
// Write out the web page that shows date, time, number, name
int write_web_page(char *str_date_time, char *str_nbr, char *str_nam){
FILE *web_file;
web_file = fopen("/users/markamos/Sites/index.html", "w"); // for Raspberry Pi use /var/www/index.html
if (web_file == NULL) {
fprintf(stderr, "Can't open output file\n");
}
// format the date and time and output a record to the web server.
fprintf(web_file,"<html><body>\n");
fprintf(web_file,"<p>Date: %c%c-%c%c</p>\n",str_date_time[0], str_date_time[1], str_date_time[2], str_date_time[3]);
fprintf(web_file,"<p>Time: %c%c:%c%c</p>\n",str_date_time[4], str_date_time[5], str_date_time[6], str_date_time[7]);
fprintf(web_file,"<p>Number: %s</p>\n", str_nbr);
fprintf(web_file,"<p>Name: %s</p>\n", str_nam);
fprintf(web_file,"</body></html>\n");
fclose(web_file);
return 0;
}
// Convert input hex characters to integer
int hex_to_int(int c){
int first = c / 16 - 3;
int second = c % 16;
int result = first * 10 + second;
if(result > 9) result--;
return result;
}
int hex_to_ascii(int c, int d){
int high = hex_to_int(c) * 16;
int low = hex_to_int(d);
return high+low;
}
int get_fld(char *fldBuf, int bufPtr){
char fldStr[3] = "00";
char *p;
fldStr[0] = fldBuf[bufPtr++];
fldStr[1] = fldBuf[bufPtr++];
return (int) strtoul(fldStr, &p, 16);
}