Next steps
- Complete integration testing (just let it run for a couple of days...)
- Wire everything together and do the final testing
Here's the code with the LCD routines integrated (see Phil Bambridge's blog for complete details on the LCD routines.)
/*
* main.c
*
* M. Amos
* (LCD code by Phil Bambridge)
*
* Listens for Caller ID info from USB modem, decodes it, writes it to the console, formats the info onto a
* web page and writes the caller name and number to an LCD display
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <sys/sysinfo.h>
#include <sys/vfs.h>
#include <time.h>
#include <unistd.h>
#include <signal.h>
#include "lcd.h"
struct lcdmodule module;
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, char **argv) {
struct lcdmodule module2;
// Variables for Caller ID
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";
// Here we create and initialise two LCD modules.
// The arguments are, in order, EN, RS, D4, D5, D6, D7.
module = lcdInit(17, 18, 22, 23, 24, 25);
module2 = lcdInit(21, 18, 22, 23, 24, 25);
// 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/ttyACM0", "w");
if (out_file == NULL) {
fprintf(stderr, "Can't open output file\n");
}
fprintf(out_file,"ATE0"); // Turn off echo
fprintf(out_file,"%c%c",0x0d,0x0a);
fprintf(out_file,"ATQ1"); // Turn off status messages
fprintf(out_file,"%c%c",0x0d,0x0a);
fprintf(out_file,"AT#CID=2"); // Turn on unformatted Caller ID
fprintf(out_file,"%c%c",0x0d,0x0a);
fclose(out_file);
// Open modem for input
FILE *in_file;
in_file = fopen("/dev/ttyACM0", "r");
if (in_file == NULL) {
fprintf(stderr, "Can't open input file\n");
}
// display splash screen on LCD
gotoXy(module, 0,0);
prints(module, "Caller ID ");
gotoXy(module, 0,1);
prints(module, "Version 1.0 ");
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
// Parse message while there's still input to be had
while (str_ptr < msg_end){
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
int i = 0;
for (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
// Echo date, number and name to console
printf("Date: %s\n",str_date_time);
printf("Number: %s\n",str_nbr);
printf("Name: %s\n",str_nam);
// Create the HTML for the web page displaying the Caller ID info
write_web_page(str_date_time, str_nbr, str_nam);
// Display Caller ID info on LCD
gotoXy(module, 0,0);
prints(module,str_nbr);
prints(module," ");
gotoXy(module, 0,1);
prints(module,str_nam);
prints(module," ");
}
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
return 0;
} // main
// Create HTML for web page to display the Caller ID info:
int write_web_page(char *str_date_time, char *str_nbr, char *str_nam){
FILE *web_file;
web_file = fopen("/var/www/index.html", "w"); // for Raspberry Pi use /var/www/index.html
if (web_file == NULL) {
fprintf(stderr, "Can't open web page 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><b>Caller ID</b></p>\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;
}
// Convert two characters from the incoming string and return as an integer
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);
}
No comments:
Post a Comment