#class auto #memmap xmem //used to print to screen and serial port (1=print 0=don't print) #define debug_print_on 1 //CINGULAR //#define DIALUP_SENDEXPECT1 "@AT OK AT+CGDCONT=1,\"IP\",\"WAP.CINGULAR\",,,,\r OK @ATDT*99***1# CONNECT" //DIALUP_AUTH //#define PAP_USER "WAP@CINGULARGPRS.COM" // PAP Athentication user //#define PAP_PASSWORD "CINGULAR1" // Kore #define DIALUP_SENDEXPECT1 "@AT OK AT+CGDCONT=1,\"IP\",\"c1.korem2m.com\",,0,0\r OK @ATDT*99***1# CONNECT" //DIALUP_AUTH #define PAP_USER "" // PAP Athentication user #define PAP_PASSWORD "" #define FTP_VERBOSE #define MSSG_TMOUT 2000UL //#define TIMEZONE -6 // CST=-6, EST=-5, MST=-7, PST=-8 offset from GMT #use "morestr.c" // Define the type of modem to be used. Supported Selections are // MDM_ENFORA, MDM_WAVECOM, and MDM_MULTI_TECH currently. The Default // Value is MDM_ENFORA #define MDM_TYPE MDM_ENFORA // Number Of Modems to Use (6 max). This sample is setup to use 1 // modem only. #define MAX_MODEMS 1 // Used in sample only. To designate what modem channel to used if // multiple modems were to be connected. This sample is setup to use 1 // modem only, so define as 0 #define MDM_CHANNEL 0 // Enables SMS Text Messaging #define GSM_SMS_ENABLE #define GSM_GPRS_ENABLE // Check for Rabbit 3000 Chip installed #if ( _BOARD_TYPE_ < RCM3400A || _BOARD_TYPE_ > RCM3410A ) #define SERB_CTS_PORT PCDR #define SERB_CTS_BIT 3 // use PC3 as CTS (input) #define SERB_RTS_PORT PCDR #define SERB_RTS_SHADOW PCDRShadow #define SERB_RTS_BIT 2 // use PC2 as RTS (output) #define MODEM_SERB_ENABLED // Serial Port to Connect Modem to #define MODEM_SERB_HANDSHAKING // Enables Handshaking (RTS/CTS) #define BINBUFSIZE 1023 // Largest RX Packet Avail. #define BOUTBUFSIZE 1023 #define MDM_INBUFSIZE BINBUFSIZE // Modem Input Buffer Size #define MDM_OUTBUFSIZE BOUTBUFSIZE // Modem Output Buffer Size #else #define SERD_CTS_PORT PCDR #define SERD_CTS_BIT 3 // use PC3 as CTS (input) #define SERD_RTS_PORT PCDR #define SERD_RTS_SHADOW PCDRShadow #define SERD_RTS_BIT 2 // use PC2 as RTS (output) #define MODEM_SERD_ENABLED // Serial Port to Connect Modem to #define MODEM_SERD_HANDSHAKING // Enables Handshaking (RTS/CTS) #define DINBUFSIZE 1023 // Largest RX Packet Avail. #define DOUTBUFSIZE 1023 // Largest TX Packet #define MDM_INBUFSIZE DINBUFSIZE // Modem Input Buffer Size #define MDM_OUTBUFSIZE DOUTBUFSIZE // Modem Output Buffer Size #endif //************************* DEBUGGING MACROS *********************************** #define RED "\x1b[31m" // foreground colors for printf #define GREEN "\x1b[32m" // foreground colors for printf #define BLUE "\x1b[34m" // foreground colors for printf #define BLACK "\x1b[30m" // foreground colors for printf //************************* INTERFACE SETTUP MACROS **************************** #define IF_NUM 1 // number of interfaces #define USE_PPP_SERIAL 0x02 // bring in PPP and use serial port B #define ETH_MTU 1500 #define ETH_MAXBUFS 3 // FTP Server //#define FTP_MAX_NAMELEN 64 // our ftp_user is longer than the default 16 bytes #define FTP_MAX_FNLEN 64 // filename limit #define USE_PASSIVE // use passive if behind a firewall #ifdef USE_PASSIVE #define PASSIVE_FLAG FTP_MODE_PASSIVE #else #define PASSIVE_FLAG 0 #endif #use "dcrtcp.lib" #use "ftp_client.lib" // wireless modem api function routines. #use "gsm_gprs.lib" // Modem Baudrate. Multi-tech and Enfora can operate at 115200, the // wavecom and only run at 9600 #if (MDM_TYPE == MDM_WAVECOM) #define MDM_BAUD_RATE 9600L #else #define MDM_BAUD_RATE 115200L #endif //include this macro if you want to delete the file //off the server after downloading #define FTP_DELETE #define CAMERA_BAUD 38400L #define MAXPICSIZE 60000L #define MAXTXDATSIZE 300 #define MAXRXDATSIZE 300 // serial B buffer size used temporarily for camera //#define BINBUFSIZE 255 //#define BOUTBUFSIZE 255 // serial A buffer size #define AINBUFSIZE 255 #define AOUTBUFSIZE 255 // serial D buffer size #define DINBUFSIZE 255 #define DOUTBUFSIZE 255 // camera timeout (msecs) #define CAMERA_TMOUT 3000L // camera communications timeout (secs) // used in watchdog (wd) #define CAMCOM_TMOUT 45 // starting address in USER BLOCK where config data can be store // if using something other than the BL2000 series, look in user manual // to find out what the usuable USER BLOCK range is. I selected this // starting address because it is above the Board ID and the analog // signal constants address range. Don't go beyond 0x1FFF. - djr #define UB_CONFIG_ADDRESS 0x1E00 // starting address #define UB_CONFIG_LEN 144 // expected length of config data ' added fields needs to be bigger!!!!!!!!!! #define UB_INT_SPACE 2 // number of memory addresses for an integer value #define UB_UL_SPACE 4 // number of memory addresses for an long/unsigned long value // IO CONSTANTS #define D_ON 0 // state - digital IO on state #define D_OFF 1 // state - digital IO off state #define HV_ON 1 // state - HV digital IO on state (note: this is opposite of the other digital IO) #define HV_OFF 0 // state - HV digital IO off state (note: this is opposite of the other digital IO) #define O_KILL 0 // (HV0) output bit - power reset RELAY #define O_MODEM 1 // (HV1) output bit - apply power to modem RELAY #define O_LIGHT 2 // (HV2) output bit - turn on light RELAY //#define O_MODEM2 3 //test modem #define O_NETBAT_TEST_R 6 // (PB6) output bit - net connectivity/battery level indicator Red LED #define O_NETBAT_TEST_G 7 // (PB7) output bit - net connectivity/battery level indicator Green LED #define I_TEST_MODE 0 // (PB0) input bit - test mode selected PB #define I_POWER_SAVE 1 // (PB1) input bit - power save mode SS #define I_DAYLIGHT 2 // (PB2) input bit - daylight sensor PE #define I_BAT_SIGNAL 0 // input channel (analog) - battery level indication VOLTS #define TESTMODE_TMOUT 300 // stay in test mode for 5 minutes (300 secs) #define BATTTEST_TMOUT 10 // test battery for this long in test mode (10 secs) #define CYCLE_TMOUT 300 // consider the system "hung" if it is on for more than 5 minutes (300 secs) #define MODEM_BOOT_TMOUT 40 // amount of time to wait for modem to power up #define FTP_RETRY_MAX 3 // number of acceptable tries to send a file #define LIGHT_TMOUT 3 //seconds - time to allow camera to adjust (white balance) to light #define CAMERAON_TMOUT 3 // seconds - time to allow camera to come on and adjust #define BATT_FULL_LEVEL 660 // raw counts, 660=12volts #define BATT_DEAD_LEVEL 480 // raw counts, 480=8volts #define MODEM_FULL_SIG 21 // (dbm) high reading (sitting on my desk by window) #define MODEM_BAD_SIG 0 // (dbm) assummed bad reading (djr-need to fine tune) #define MODEM_FULL_PULSE 5 // number of LED pulses to indicate FULL signal #define CHECKSUM_FIELDSIZE 6 // dat file field sizes #define IMEI_FIELDSIZE 15 #define PICDELAY_FIELDSIZE 5 #define DAYMODE_FIELDSIZE 1 #define ACTIVEMODE_FIELDSIZE 1 #define DATE_FIELDSIZE 8 #define TIME_FIELDSIZE 6 #define FTPSITE_FIELDSIZE 50 #define FTPUSER_FIELDSIZE 15 #define FTPPASS_FIELDSIZE 15 #define SMS_NO_FIELDSIZE 11 #define SMS_CAM_NAME_FIELDSIZE 10 #define PICSIZE_FIELDSIZE 1 #define BATSTAT_FIELDSIZE 3 #define GPSCOORD_FIELDSIZE 10 #define CODEVERISON_FIELDSIZE 10 #define ERRORCODE_FIELDSIZE 10 #define FILE_FILL_CONST '\x20' // space character // User Defined Modem Setup Function used in the GSM_Initialize function. // This function will setup the serial port that is used, as well as // the RTS/CTS lines for flow control. This function is setup for use // with the RCM3000/31000/3200 development board. void MyModemSetup(long baudrate) { #if (_BOARD_TYPE_ < RCM3400A || _BOARD_TYPE_ > RCM3410A) // Setup for the Serial port being used Modem_Serial_Options(MDM_CHANNEL, M_SERB, baudrate, PARAM_8BIT, PARAM_NOPARITY, 1); // Configures the RTS Line Modem_Signal_Config(MDM_CHANNEL, MODEM_RTS, Modem_WrPortI, PCDR, &PCDRShadow, SERB_RTS_BIT, 0); // Configures the CTS Line Modem_Signal_Config(MDM_CHANNEL, MODEM_CTS, Modem_RdPortI, PCDR, &PCDRShadow, SERB_CTS_BIT, 0); #else // Setup for the Serial port being used Modem_Serial_Options(MDM_CHANNEL, M_SERD, baudrate, PARAM_8BIT, PARAM_NOPARITY, 1); // Configures the RTS Line Modem_Signal_Config(MDM_CHANNEL, MODEM_RTS, Modem_WrPortI, PCDR, &PCDRShadow, SERD_RTS_BIT, 0); // Configures the CTS Line Modem_Signal_Config(MDM_CHANNEL, MODEM_CTS, Modem_RdPortI, PCDR, &PCDRShadow, SERD_CTS_BIT, 0); #endif // Open Serial Port Modem_Port_Open(MDM_CHANNEL); // special command for BL2000 //serMode(1); } //**************** STRUCTS, GLOBALS, & FUNCTION DELCARATIONS ******************* typedef struct { char* name; // ptr to the name of this interface int state; // state the interface is in tcp_Socket sock; // socket for this interface int ifx; // the interface word lport; // the local port to use to connect to remote port char* rip; // remote ip address word rport; // remote port long timer; // time keeper char* filename; // name of my file unsigned long fileaddrs;// address to the file in xmem sram unsigned long filesize; // size of file }IFS_Type; const int ifaces[] = {IF_PPP1}; // actual interfaces const char *if_name[] = {"IF_PPP1"}; // name of interfaces CoData CoPPPup,CoFTP; unsigned long pic_fileaddress; // extended memory address of picture to be uploaded unsigned long txdat_fileaddress; // extended memory address of text file to be uploaded (tx) //unsigned long dat_fileaddress; // extended memory address of dat file to be downloaded long pic_filesize; int txdat_filesize; // filesize of dat file to send (tx) longword rxdat_filesize; // filesize of dat file to receive (rx) char rxdat_file_buf[200]; // buffer location for data read (rx) from dat file that is downloaded from server char pic_filename[40]; // filename of uploaded picture file (i.e. 353530000222991-08022005-135055.jpg) char txdat_filename[40]; // filename of uploaded (tx'd) data file (i.e. 353530000222991-08022005-135055.txt) char rxdat_filename[IMEI_FIELDSIZE + 5]; // filename of downloaded (rx'd) data file (i.e. 353530000222991.dat) char pic_date[DATE_FIELDSIZE + 1]; // dateof picture (i.e. mmddyyyy) char pic_time[TIME_FIELDSIZE + 1]; // time of picture (i.e. hhmmss) char simnumber[12]; // 11-digit phone number of sim card (i.e. 16625551234) char gps_cord[GPSCOORD_FIELDSIZE + 1]; // coordinates of GPS location (future expansion) char IMEInumber[IMEI_FIELDSIZE + 1]; // IMEI number of modem char SMS_Phone[12]; static char SMS_Msg[10]; int IFs_Setup (IFS_Type *iface,int index); int FTP_Client (IFS_Type *iface, int type); int FTP_Datahandler(char *data,int len,longword offset,int flags,void *dhnd_data); int Close_IFs (IFS_Type *iface); void MyModemSetup(long baudrate); int send_file(int nettestmode); void BatteryCheck(int testmode); void debug_print(char msg[500]); // used to print to screen and serial port for debug void delay_ms(unsigned long delay_mS); int Take_Picture(); int Get_Picture(); void errorHandler(); int wd(int val); int format_report_buf(); int Read_Config_Mem(); int charpos(char * source, char x); int Load_Default_Settings(); const char sync_camera_cmd[7] = {'\xAA','\x0D','\x00','\x00','\x00','\x00','\0'}; const char sync_camera_ack[4] = {'\xAA','\x0E','\x0D','\0'}; const char initialize_camera_cmd[7] = {'\xAA','\x01','\x00','\x07','\x07','\x07','\0'}; const char initialize_camera_cmd_small[7] = {'\xAA','\x01','\x00','\x07','\x07','\x05','\0'}; const char initialize_camera_ack[4] = {'\xAA','\x0E','\x01','\0'}; const char ack_camera_cmd[7] = {'\xAA','\x0E','\x0D','\x00','\x00','\x00','\0'}; const char reset_camera_cmd[7] = {'\xAA','\x08','\x00','\x00','\x00','\xFF','\0'}; const char reset_camera_ack[4] = {'\xAA','\x0E','\x08','\0'}; const char pkgsize_camera_cmd[7] = {'\xAA','\x06','\x08','\x00','\x02','\x00','\0'}; const char pkgsize_camera_ack[4] = {'\xAA','\x0E','\x06','\0'}; const char snapshot_camera_cmd[7] = {'\xAA','\x05','\x00','\x00','\x00','\x00','\0'}; const char snapshot_camera_ack[4] = {'\xAA','\x0E','\x05','\0'}; const char getpicture_camera_cmd[7] = {'\xAA','\x04','\x01','\x00','\x00','\x00','\0'}; const char getpicture_camera_ack[4] = {'\xAA','\x0E','\x04','\0'}; const int sync_camera_cmd_size = 6; const int sync_camera_ack_size = 3; const int initialize_camera_cmd_size = 6; const int initialize_camera_ack_size = 3; const int ack_camera_cmd_size = 6; const int reset_camera_cmd_size = 6; const int reset_camera_ack_size = 3; const int pkgsize_camera_cmd_size = 6; const int pkgsize_camera_ack_size = 3; const int snapshot_camera_cmd_size = 6; const int snapshot_camera_ack_size = 3; const int getpicture_camera_cmd_size = 6; const int getpicture_camera_ack_size = 3; const int getpicture_camera_dat_size = 6; // config data stored in USER BLOCK memory (come from server file) long config_pic_delay; // number of secs between pictures int config_daymode; // true if day only mode is active int config_active; // true if camera is active char config_ftp_server[FTPSITE_FIELDSIZE + 1]; // ftp server address char config_ftp_user[FTPUSER_FIELDSIZE + 1]; // ftp server username char config_ftp_pass[FTPPASS_FIELDSIZE + 1]; // ftp server password char config_sms_no_1[SMS_NO_FIELDSIZE + 1]; char config_sms_no_2[SMS_NO_FIELDSIZE + 1]; char config_sms_no_3[SMS_NO_FIELDSIZE + 1]; char config_sms_cam_name[SMS_CAM_NAME_FIELDSIZE + 1]; int config_imagesize; // size of image 0=640x480, 1=320x240 const char version[11] = "1.3.0"; // version of Rabbit code const char SMS_Msg_Hdr[15] = "Pic Taken By: "; // working data stored in USER BLOCK memory unsigned long mem_lastimagetime; // last time a picture was taken (secs from 1980) unsigned long tmr_powerup_start; unsigned long tmr_modemup_start; int batterylevel; // % of battery long ecode; // error code (future use) int daylightlatch; int modemsignal; // dbm - measurement of modem reception int motion_debounce; // msecs - used to debounce the motion sensor output /******************************************************************************/ // program entry point int main() { int i; unsigned long memi; static struct tm Time; static long tmChk; int nettestpass; // flag to indicate nettest passed int nettestindcount, nettestpulseind; float netsigratio; char zeroarray[10]; // do not set more than 3000 because of delay in Take_Picture routine motion_debounce = 2000; //set the function that is called if a RT error occurs defineErrorHandler(errorHandler); // set the clock - djr - not tested if (tmChk != dc_timestamp) { mktm(&Time,dc_timestamp); tm_wr(&Time); tmChk = dc_timestamp; } tm_rd(&Time); // reset vars memset(simnumber, '\0', sizeof(simnumber)); memset(IMEInumber, '\0', sizeof(IMEInumber)); memset(rxdat_file_buf, '\0', sizeof(rxdat_file_buf)); memset(pic_filename, '\0', sizeof(pic_filename)); memset(txdat_filename, '\0', sizeof(txdat_filename)); memset(rxdat_filename, '\0', sizeof(rxdat_filename)); memset(pic_date, '\0', sizeof(pic_date)); memset(pic_time, '\0', sizeof(pic_time)); memset(config_ftp_server, '\0', sizeof(config_ftp_server)); memset(config_ftp_user, '\0', sizeof(config_ftp_user)); memset(config_ftp_pass, '\0', sizeof(config_ftp_pass)); memset(gps_cord, '\0', sizeof(gps_cord)); memset(SMS_Phone, '\0', sizeof(SMS_Phone)); memset(SMS_Msg, '\0', sizeof(SMS_Msg)); memset(config_sms_no_1, '\0', sizeof(config_sms_no_1)); memset(config_sms_no_2, '\0', sizeof(config_sms_no_2)); memset(config_sms_no_3, '\0', sizeof(config_sms_no_3)); memset(config_sms_cam_name, '\0', sizeof(config_sms_cam_name)); pic_filesize = 0; rxdat_filesize = 0; txdat_filesize = 0; mem_lastimagetime = 0; tmr_powerup_start = 0; batterylevel = 0; ecode = 0; // default settings - temp strcpy(gps_cord, "0.0.0"); //brdInit(); // 2030 only jrioInit(); //special call for 1800 series board Jr485Init(); //special call for 1800 series board serDopen(19200); //used for printing debug info to hyperterminal Jr485Tx(); //special call for 1800 series // enable transmitter // IO TESTING SECTIONS - DEBUG ONLY - UNCOMMENT TO TEST NEW BOARDS // //******************************************************************// /* digOut(O_MODEM, HV_ON); digOut(O_MODEM, HV_OFF); digOut(O_LIGHT, HV_ON); digOut(O_LIGHT, HV_OFF); BitWrPortI(PBDR, &PBDRShadow, D_OFF, O_NETBAT_TEST_R); BitWrPortI(PBDR, &PBDRShadow, D_OFF, O_NETBAT_TEST_G); BitWrPortI(PBDR, &PBDRShadow, D_ON, O_NETBAT_TEST_R); BitWrPortI(PBDR, &PBDRShadow, D_ON, O_NETBAT_TEST_G); BitWrPortI(PBDR, &PBDRShadow, D_OFF, O_NETBAT_TEST_R); BitWrPortI(PBDR, &PBDRShadow, D_OFF, O_NETBAT_TEST_G); BitWrPortI(PBDR, &PBDRShadow, D_ON, O_NETBAT_TEST_G); daylightlatch = BitRdPortI(PBDR, I_TEST_MODE); daylightlatch = BitRdPortI(PBDR, I_POWER_SAVE); daylightlatch = BitRdPortI(PBDR, I_TEST_MODE); daylightlatch = BitRdPortI(PBDR, I_TEST_MODE); BatteryCheck(0); for(;;) { printf("Light Input: %d\n", BitRdPortI(PBDR, I_DAYLIGHT)); delay_ms(1000); } */ //******************************************************************// // IO TESTING SECTIONS - DEBUG ONLY - UNCOMMENT TO TEST NEW BOARDS // // make sure all outputs are off BitWrPortI(PBDR, &PBDRShadow, D_OFF, O_NETBAT_TEST_R); BitWrPortI(PBDR, &PBDRShadow, D_OFF, O_NETBAT_TEST_G); for(i=0;i<3;i++) digOut(i, HV_OFF); // pulse reset - this prevents the taking of a picture when power is // applied after the unit was cut off prematurly. digOut(O_KILL,HV_ON); delay_ms(motion_debounce); digOut(O_KILL,HV_OFF); // digOut(O_MODEM2, HV_ON); pic_fileaddress = xalloc(MAXPICSIZE); //allocate bytes of SRAM for picture (upload) txdat_fileaddress = xalloc(MAXTXDATSIZE); //allocate bytes of SRAM for text file (upload-tx) /* for (i=0;i<10;i++) zeroarray[i] = '0'; debug_print("Start Mem Set1"); for (memi=0;memi MODEM_BAD_SIG) { // Calculate number of LED pulses to indicate signal strength netsigratio = (MODEM_FULL_SIG - MODEM_BAD_SIG) / (MODEM_FULL_PULSE - 1); nettestpulseind = (int) ((modemsignal - MODEM_BAD_SIG)/netsigratio) + 1; } else nettestpulseind = 1; } nettestindcount = 0; // counter used to limit signal indication to three cycles do { if ((nettestpass == 1) && (nettestindcount <=2)) { // modem signal strength indications delay_ms(1500); for(i=1; i<=nettestpulseind; i++) { BitWrPortI(PBDR, &PBDRShadow, D_ON, O_NETBAT_TEST_G); delay_ms(500); BitWrPortI(PBDR, &PBDRShadow, D_OFF, O_NETBAT_TEST_G); delay_ms(500); } nettestindcount = nettestindcount + 1; } else // leave green light on for remainder of test mode if (nettestpass == 1) { delay_ms(1500); BitWrPortI(PBDR, &PBDRShadow, D_ON, O_NETBAT_TEST_G); } //wd(0); disable watchdog during test mode } // loop for a specified amount of time while((read_rtc() - tmr_powerup_start) <= TESTMODE_TMOUT); } else // not in test mode { debug_print("Power On."); // check delay between pics if (((tmr_powerup_start - mem_lastimagetime) > config_pic_delay) || (mem_lastimagetime >= tmr_powerup_start)) // check for night mode condition if (((daylightlatch == D_ON) && !(config_daymode == 2)) || ((daylightlatch == D_OFF) && ((config_daymode == 0) || (config_daymode == 2)))) { // apply power to the modem digOut(O_MODEM, HV_ON); debug_print("Take Picture"); if (Take_Picture() == 1) { // capture the number of seconds when modem is powered up tmr_modemup_start = read_rtc(); debug_print("Get Picture"); if (Get_Picture() == 1) { debug_print("Send File"); if (send_file(0) == 1) // write current start time to User Block memory writeUserBlock(UB_CONFIG_ADDRESS, (unsigned long *)&tmr_powerup_start, UB_UL_SPACE); } } } } debug_print("Power Off"); // turn off "picture taken" indicator BitWrPortI(PBDR, &PBDRShadow, D_OFF, O_NETBAT_TEST_G); BitWrPortI(PBDR, &PBDRShadow, D_OFF, O_NETBAT_TEST_R); digOut(O_MODEM, HV_OFF); // digOut(O_MODEM2, HV_ON); delay_ms(4000); // suicide digOut(O_KILL, HV_ON); return 1; } //end main /******************************************************************************/ /******************************************************************************/ // sends file via FTP // Return 1=success, 0=fail int send_file(int nettestmode) { IFS_Type iface[IF_NUM]; char at_rsp[MDM_INBUFSIZE]; int str,berr,done,index,chk,recv,loop; int count,result; int ftpRetry; char tempbuf[30]; int picfilewritten, rxdatfileread, txdatfilewritten, downloadresult; int bitErr; char tempString1[50]; char tempString2[50]; picfilewritten = 0; rxdatfileread = 0; txdatfilewritten = 0; downloadresult = 0; modemsignal = 0; count = done = index = 0; ftpRetry = 0; // loop for modem bootup while(((read_rtc() - tmr_modemup_start) <= MODEM_BOOT_TMOUT) && wd(0)); if (sock_init() != 0) { debug_print("Error opening socket!"); return 0; } // Initialize Modem while (((chk = GSM_Initialize(MDM_CHANNEL,10,1000,MDM_BAUD_RATE,MyModemSetup)) == 0) && wd(0)); if (chk != MDM_SUCCESS) { debug_print("!!!NO MODEM PRESENT!!!"); return 0; } // Loop until all functions are completed. while (!done) { // Sample costate for getting misc. information from the modem. costate { // Get the Manufacturer Description //waitfor(GSM_GetManuFacturer(MDM_CHANNEL,at_rsp)); // Get the Model ID Number //waitfor(GSM_GetModelID(MDM_CHANNEL,at_rsp)); // Get the Subscriber Phone on the Sim Card waitfor(GSM_GetPhoneNumber(MDM_CHANNEL,simnumber)); // Get Modem IMEI Number waitfor(GSM_GetSerNumber(MDM_CHANNEL, IMEInumber)); // Get the SMSC Number from the sim card //waitfor(GSM_GetSMSCNumber(MDM_CHANNEL,at_rsp)); // Check the Current Network Status waitfor(GSM_NetworkConnect(MDM_CHANNEL)); waitfor(GSM_GetNetworkStatus(MDM_CHANNEL,&str,&berr)); // capture modem signal strength waitfor(GSM_GetSignalStrength(MDM_CHANNEL, &modemsignal, &bitErr)); // Initialize SMS Text Messaging waitfor(GSM_SmsInit(MDM_CHANNEL)); // Set the Modem in SMS Text mode. //waitfor(GSM_SmsMode(MDM_CHANNEL)); strcpy(SMS_Msg, config_sms_cam_name); // strcat(SMS_Msg, config_sms_cam_name); // debug_print(SMS_Msg); if (strlen(config_sms_no_1) == 11) { // strcpy(SMS_Phone,config_sms_no_1); waitfor(DelayMs(2000)); // delay for 2 seconds to allow modem waitfor(GSM_SmsSend(MDM_CHANNEL,config_sms_no_1,SMS_Msg)); debug_print("Message 1 Sent!"); } if (strlen(config_sms_no_2) == 11) { // strcpy(SMS_Phone,config_sms_no_2); waitfor(DelayMs(2000)); // delay for 2 seconds to allow modem waitfor(GSM_SmsSend(MDM_CHANNEL,config_sms_no_2,SMS_Msg)); debug_print("Message 2 Sent!"); } if (strlen(config_sms_no_3) == 11) { // strcpy(SMS_Phone,config_sms_no_3); waitfor(DelayMs(2000)); // delay for 2 seconds to allow modem waitfor(GSM_SmsSend(MDM_CHANNEL,config_sms_no_3,SMS_Msg)); debug_print("Message 3 Sent!"); } done = 1; } wd(0); } //printf("Phone number is: %s\n", simnumber); //printf("Modem IMEI is: %s\n", IMEInumber); strcpy(tempString1,"Phone number is: "); strcat(tempString1, simnumber); debug_print(tempString1); strcpy(tempString1,"IMEI number is: "); strcat(tempString1, IMEInumber); debug_print(tempString1); if (strlen(IMEInumber) != 15) { // debug_print("IMEI number invalid!!!"); strcpy(tempString1,"IMEI number invalid: "); strcat(tempString1, IMEInumber); debug_print(tempString1); return 0; } // build filenames strcpy(pic_filename, IMEInumber); strcat(pic_filename, "-"); strcat(pic_filename, pic_date); strcat(pic_filename, "-"); strcat(pic_filename, pic_time); strcpy(txdat_filename, pic_filename); strcat(pic_filename, ".jpg"); strcat(txdat_filename, ".dat"); strcpy(rxdat_filename, IMEInumber); strcat(rxdat_filename, ".dat"); printf("Filenames are: %s, %s, %s.\n", pic_filename, rxdat_filename, txdat_filename); while((0 == GPRS_Init(MDM_CHANNEL)) && wd(0)); // check to make sure the correct pdp contexts // Main Loop For Receiving/Send Reply to SMS Messages. debug_print("Modem Ready!"); // setup FTP session variables if (IFs_Setup(iface,index) != 1) return 0; CoBegin(&CoPPPup); while(1) { wd(0); tcp_tick(NULL); costate CoPPPup // bring up the PPP interface { printf("Bring up %s\n",iface[0].name); if (ifconfig(IF_PPP1, IFS_PPP_INIT, IFS_PPP_SPEED, MDM_BAUD_RATE, IFS_PPP_FLOWCONTROL, 1, // 0 = NO flowcontrol IFS_PPP_RTSPIN, PCDR, &PCDRShadow, 2, // flowcontrol pin IFS_PPP_CTSPIN, PCDR, 3, // flowcontrol pin IFS_PPP_SENDEXPECT, DIALUP_SENDEXPECT1, IFS_PPP_REMOTEAUTH, PAP_USER, PAP_PASSWORD, IFS_PPP_HANGUP, "ATH", IFS_PPP_MODEMESCAPE, 1, IFS_PPP_ACCEPTIP, 1, IFS_PPP_ACCEPTDNS, 1, IFS_UP, IFS_DEBUG,6, // additional lower level debugging info IFS_END) != 0) { return 0; } // debug_print(DIALUP_SENDEXPECT1); waitfor((ifpending(iface[0].ifx) == 2) || DelayMs(45000)); if(0 == ifstatus(iface[0].ifx)) { debug_print("Bring Up Interface Fialed"); printf("%s%s: FAILED\n%s",RED,iface[0].name,BLACK); ftpRetry = ftpRetry + 1; //increment retry counter if (ftpRetry < FTP_RETRY_MAX) { CoBegin(&CoPPPup); // try bringing PPP up again } else { debug_print("Number of FTP retries exceeded!"); return 0; } } else { debug_print("Bring Up Interface Successful."); printf("%s%s: IS UP!\n%s",GREEN,iface[0].name,BLACK); CoBegin(&CoFTP); } } costate CoFTP { //ip_print_ifs(); //router_printall(); //djr -check file sizes to prevent overflow // don't send a file. just test network connectivity in nettestmode. if (nettestmode != 1) { // look to see if a dat file is on the server to be downloaded if (rxdatfileread != 1) { debug_print("Look for Dat file on server."); // fill rxdat_file_buf with dat file data from server memset(rxdat_file_buf, '\0', sizeof(rxdat_file_buf)); rxdat_filesize = 0; iface[0].filename = rxdat_filename; iface[0].fileaddrs = 0; //not used iface[0].filesize = 0; //not used downloadresult = FTP_Client(&iface[0], 1); if (downloadresult == 1) { // set flag to prevent re-download rxdatfileread = 1; // process uploaded data file Process_Server_Dat(); } else if (downloadresult == 2) // set flag to indicate there was no flag to download rxdatfileread = 2; } // write the image file to the server if ((picfilewritten != 1) && (config_active == 1)) { debug_print("Write Image File to server."); iface[0].filename = pic_filename; iface[0].fileaddrs = pic_fileaddress; iface[0].filesize = pic_filesize; if (FTP_Client(&iface[0], 0) == 1) { // set flag to prevent re-upload picfilewritten = 1; } } // write the image dat file to the server if ((txdatfilewritten != 1) && (config_active == 1)) { if (format_report_buf() == 1) { debug_print("Write Dat File to server."); iface[0].filename = txdat_filename; iface[0].fileaddrs = txdat_fileaddress; iface[0].filesize = txdat_filesize; if (FTP_Client(&iface[count], 0) == 1) { // set flag to prevent re-upload txdatfilewritten = 1; } } } if (((config_active == 0) && ((rxdatfileread == 1) || (rxdatfileread == 2))) || ((config_active == 1) && (picfilewritten == 1) && (txdatfilewritten == 1) && ((rxdatfileread == 1) || (rxdatfileread == 2)))) { debug_print("Finished Send Function"); result = 1; } else result = 0; } else // in nettestmode result = 1; Close_IFs(iface); router_del_all(); if (result == 1) { Modem_Port_Open(MDM_CHANNEL); //serMode(1); CoReset(&CoFTP); return 1; } else { ftpRetry = ftpRetry + 1; //increment retry counter if (ftpRetry < FTP_RETRY_MAX) { CoBegin(&CoPPPup); // try bringing PPP up again } else { debug_print("Number of FTP retries exceeded!"); return 0; } } } } // end while(1) } // end send_file() /******************************************************************************/ /******************************************************************************* This function sets up the interface structure for an FTP server. *******************************************************************************/ int IFs_Setup(IFS_Type *iface, int index) { iface[0].name = if_name[0]; iface[0].state = 0; iface[0].ifx = ifaces[0]; iface[0].lport = 8000+(0*1000); iface[0].rip = config_ftp_server; iface[0].rport = 21; iface[0].timer = 0; return 1; } //end IFs_Setup /******************************************************************************/ /******************************************************************************* This function starts up an ftp session over the default interface, in our case PPP. Then it resolves the ftp server's IP address and uploads/downloads a file. type = 0-download, 1-upload Return: 1=success, 0=fail *******************************************************************************/ int FTP_Client(IFS_Type *iface, int type) { longword destIP; // hex value of the destination IP char tbuff[16]; // temp buff to hold dotted IP int ftp_status; // return value for the ftp_client_tick unsigned long data[2]; // data array for ftp datahandler if(!ifstatus(iface->ifx)) // check if interface is up!! return 0; // interface is down so return if( 0L == (destIP = resolve(iface->rip))) { printf( "%sERROR: Cannot resolve %s into an IP address\n%s",RED,iface->rip,BLACK); return 0; } else { printf("%s%s: %s%s\n",BLUE,iface->rip,inet_ntoa(tbuff,destIP),BLACK); } printf("Calling ftp_client_setup() to transfer %s...\n", iface->filename); if (type == 1) // downloading from server { if(ftp_client_setup(destIP, iface->rport, config_ftp_user, config_ftp_pass, FTP_MODE_DOWNLOAD|PASSIVE_FLAG, iface->filename, // name of the file "outgoing", // remote directory rxdat_file_buf, // buffer location sizeof(rxdat_file_buf)) != 0) { printf("FTP setup failed.\n"); return 0; } } else // uploading to server { if(ftp_client_setup(destIP, iface->rport, config_ftp_user, config_ftp_pass, FTP_MODE_UPLOAD|PASSIVE_FLAG, iface->filename, // name of the file "incoming", // remote directory NULL, // using data_handler 0) != 0) { printf("FTP setup failed.\n"); return 0; } // use data handler for uploads data[0] = iface->fileaddrs; // address in xmem for our data file data[1] = iface->filesize; // the filesize for our data file ftp_data_handler(FTP_Datahandler,data,0); } printf("Looping on ftp_client_tick()...\n"); // djr - no way to check to make sure filesize isn't too big on download from server while ((0 == (ftp_status = ftp_client_tick())) && wd(0)); if(1 != ftp_status) { printf("FTP transfer failed: status = %d, last code = %d\n", ftp_status,ftp_last_code()); //code 550 - file not available - special case if (ftp_last_code() == 550) return 2; else return 0; } else { printf("FTP transfer completed successfully %ld bytes.\n", ftp_client_xfer()); if (type == 1) // downloading from server rxdat_filesize = ftp_client_xfer(); } return 1; } //end FTP_Client /******************************************************************************/ /******************************************************************************/ /** * The return value from this function depends on the in/out * flag. For FTPDH_IN, the function should return 'len' * if the data was processed successfully and download should * continue; -1 if an error has occurred and the transfer * should be aborted. For FTPDH_OUT, the function should * return the actual number of bytes placed in the data * buffer, or -1 to abort. If 0 is returned, then the * upload is terminated normally. For FTPDH_END, the * return code should be 0 for success or -1 for error. If * an error is flagged, then this is used as the return code * for ftp_client_tick(). For FTPDH_ABORT, the return code * is ignored. */ int FTP_Datahandler(char * data, int length, longword offset, int flags, void * dhnd_data) { auto unsigned mod; unsigned datasize; // this is the length of the file we are sending unsigned long xaddrs; // address to the data in xmem that we are sending xaddrs = ((*(unsigned long*)dhnd_data)+offset); datasize = (unsigned)*(((unsigned long*)dhnd_data)+1); switch (flags) { case FTPDH_IN: printf("DH: got %d bytes at offset %ld\n",length,offset); return length; case FTPDH_OUT: // uploading a file if (offset >= datasize) return 0; // done mod = (int)(offset % datasize); // check if we have send all the data if (length > datasize - mod) length = datasize - mod; xmem2root(data,xaddrs,length); return length; case FTPDH_END: // done printf("DH: END OK\n"); return 0; case FTPDH_ABORT: printf("DH: ABORTED\n"); return 0; } return -1; } //end FTP_Datahandler /******************************************************************************/ /*******************************************************************************/ //This function closes all sockets and brings down all interfaces int Close_IFs(IFS_Type *iface) { int count; for(count=0;count 100) { debug_print("Error syncing with Camera!"); return 0; } } //send ack serAwrFlush(); serArdFlush(); //+ debug_print("Sending Ack To Camera."); if (serAwrite (ack_camera_cmd, ack_camera_cmd_size) != ack_camera_cmd_size) // send cmd debug_print("Error Sending Ack Command!"); delay_ms(500); //initialize camera serAwrFlush(); serArdFlush(); //+ debug_print("Sending Initialize Command."); memset(Buf, '\0', sizeof(Buf)); // clear buffer n=0; if (config_imagesize == 1) //take small pic { if (serAwrite (initialize_camera_cmd_small, initialize_camera_cmd_size) != initialize_camera_cmd_size) { return 0; debug_print("Error Sending Initialize Command!"); } } else //take big pic { if (serAwrite (initialize_camera_cmd, initialize_camera_cmd_size) != initialize_camera_cmd_size) { return 0; debug_print("Error Sending Initialize Command!"); } } while ((serArdFree() == AINBUFSIZE) && wd(CAMCOM_TMOUT)); // wait for a byte to arrive wd(0); n = serAread(Buf, initialize_camera_ack_size, CAMERA_TMOUT); delay_ms(500); //set package size serAwrFlush(); serArdFlush(); //+ debug_print("Sending Set Package Size Command."); memset(Buf, '\0', sizeof(Buf)); // clear buffer n=0; if (serAwrite (pkgsize_camera_cmd, pkgsize_camera_cmd_size) != pkgsize_camera_cmd_size) debug_print("Error Sending Set Package Size Command!"); delay_ms(500); while ((serArdFree() == AINBUFSIZE) && wd(CAMCOM_TMOUT)); // wait for a byte to arrive wd(0); n = serAread(Buf, pkgsize_camera_ack_size, CAMERA_TMOUT); delay_ms(500); //send snapshot command serAwrFlush(); serArdFlush(); //+ debug_print("Sending Snapshot Command."); memset(Buf, '\0', sizeof(Buf)); // clear buffer n=0; if (serAwrite (snapshot_camera_cmd, snapshot_camera_cmd_size) != snapshot_camera_cmd_size) debug_print("Error Sending Snapshot Command!"); //+ delay_ms(500); while ((serArdFree() == AINBUFSIZE) && wd(CAMCOM_TMOUT)); // wait for a byte to arrive wd(0); n = serAread(Buf, snapshot_camera_ack_size, CAMERA_TMOUT); // turn off light delay_ms(10000); //added 10/11/07 by js to allow camera to caputure ir pic???? digOut(O_LIGHT, HV_OFF); //+ debug_print("Light Off!"); serAclose(); //capture date/time of picture tm_rd(&rtc); // get time in struct tm t0 = mktime(&rtc); sprintf(pic_date, "%02d%02d%04d", rtc.tm_mon, rtc.tm_mday, 1900+rtc.tm_year); sprintf(pic_time, "%02d%02d%02d", rtc.tm_hour, rtc.tm_min, rtc.tm_sec); return 1; } //end Take_Picture /******************************************************************************/ /******************************************************************************/ // retrieve picture from camera buffer // Return: 1=success, 0=fail int Get_Picture() { char Buf[550]; char tempString1[50]; char tempString2[50]; int n; int packetcount; int packetsize; int read_packetcount; char ack_string[7]; int ack_size; long read_picsize; ack_size = 6; ack_string[0] = '\xAA'; ack_string[1] = '\x0E'; ack_string[2] = '\x00'; ack_string[3] = '\x00'; ack_string[4] = '\x00'; ack_string[5] = '\x00'; ack_string[6] = '\0'; serAopen(CAMERA_BAUD); // set baud rate serAwrFlush(); //clear Rx and Tx data buffers serArdFlush(); //Send Get Picture Command debug_print("Sending Get Picture Command."); if (serAwrite (getpicture_camera_cmd, getpicture_camera_cmd_size) != getpicture_camera_cmd_size)// send cmd debug_print("Error Sending Get Picture Command!"); while ((serArdFree() == AINBUFSIZE) && wd(CAMCOM_TMOUT)); // wait for a byte to arrive wd(0); n = serAread(Buf, getpicture_camera_ack_size, CAMERA_TMOUT); if (strncmp(Buf, getpicture_camera_ack, getpicture_camera_ack_size) != 0) { debug_print("Get Picture ACK NOT received!"); } else { debug_print("Get Picture Ack received!"); } // djr - 100107 while ((serArdFree() == AINBUFSIZE) && wd(0)); // wait for a byte to arrive //Get Remainder of Picture Ack out of buffer memset(Buf, '\0', sizeof(Buf)); // clear buffer n=0; n = serAread(Buf, 6 - getpicture_camera_ack_size, CAMERA_TMOUT); // djr - 100107 while ((serArdFree() == AINBUFSIZE) && wd(0)); // wait for a byte to arrive //Get Image Size Data memset(Buf, '\0', sizeof(Buf)); // clear buffer n=0; n = serAread(Buf, getpicture_camera_dat_size, CAMERA_TMOUT); packetcount = 0; // initialize packet count pic_filesize = 0; // initialize file size read_picsize = (((int) Buf[4]) * 256) + ((int) Buf[3]); printf("Total File Size: %d\n", read_picsize); // djr - 100107 strcpy(tempString1,"Pic Size to acquire (bytes): "); itoa(read_picsize,tempString2); strcat(tempString1, tempString2); debug_print(tempString1); do { serAwrFlush(); //clear Rx and Tx data buffers serArdFlush(); //Send Data Size Ack ack_string[4] = (char) packetcount; if (serAwrite (ack_string, ack_size) != ack_size)// send cmd debug_print("Error Sending Ack!"); while ((serArdFree() == AINBUFSIZE) && wd(0));// wait for a byte to arrive memset(Buf, '\0', sizeof(Buf)); // clear buffer n=0; // reset count n = serAread(Buf, 4, CAMERA_TMOUT); // get packet id read_packetcount = (((int) Buf[1]) * 256) + ((int) Buf[0]); packetsize = (((int) Buf[3]) * 256) + ((int) Buf[2]); // capture packet size printf("Packet #%d: Size: %d bytes\n", read_packetcount, packetsize); // debug_print("Packet Received."); // delay needed when printf statement is not active delay_ms(10); memset(Buf, '\0', sizeof(Buf)); // clear buffer n=0; // reset count n = serAread(Buf, packetsize + 2, CAMERA_TMOUT); // read data portion of packet + ETX char // ensure image size is within bounds of allocated memory if ((pic_filesize + packetsize) > MAXPICSIZE) { printf("Image size out of bounds!\n"); return 0; } // write data to SRAM if (root2xmem((pic_fileaddress + pic_filesize), Buf, packetsize)!= 0) { printf("Error writing xmem address: %u\n",(pic_fileaddress + pic_filesize)); return 0; } // increment after writing to XMEM pic_filesize = pic_filesize + packetsize; packetcount = packetcount + 1; // increment packet count wd(0); // djr - 100107 // strcpy(tempString1,"Pic Size (Accum): "); // itoa(pic_filesize,tempString2); // strcat(tempString1, tempString2); // debug_print(tempString1); } while (pic_filesize < read_picsize); // loop until EOT indicato // djr - 100107 strcpy(tempString1,"Got Picture. Size: "); itoa(pic_filesize,tempString2); // convert integer to string strcat(tempString1, tempString2); strcat(tempString1, " bytes"); debug_print(tempString1); printf("Total file size: %d bytes\n", pic_filesize); serAclose(); //pic_filesize = 60000; return 1; } //end Get_Picture /******************************************************************************/ /******************************************************************************/ // delay that is safe to use when in sleepy mode void delay_ms(unsigned long delay_mS) { auto unsigned long delay_end; delay_end = MS_TIMER + delay_mS; // OK to return early if MS_TIMER + delay_mS wraps while (((MS_TIMER < delay_end) && (delay_end >= delay_mS))); }//end delay_ms /******************************************************************************/ /******************************************************************************/ // actions to do upon RT error or wd (watchdog) timeout root void errorHandler() { printf("Executing error handler.\n"); // suicide digOut(O_KILL, HV_ON); exit(0); } //end errorHandler /******************************************************************************/ /******************************************************************************/ // indicate battery level // only turn on LEDs if in testmode (=1) void BatteryCheck(int testmode) { int batsig; int * ptr_batsig; float mathtemp1, mathtemp2, mathtemp3, mathtemp4; int i; long sum; int count; // take snapshot of battery level // anaIn returns a non-scaled count value (10-bit for the BL2030, 0-1023 counts) sum = 0; count = 0; for (i=0;i<10;i++) { anaIn(I_BAT_SIGNAL, &batsig); if (batsig > 0) { sum = sum + batsig; count = count + 1; } } if (count > 0) batsig = (int) (sum/count); // create a percentage of battery power if (batsig > BATT_DEAD_LEVEL) { mathtemp1 = (batsig - BATT_DEAD_LEVEL); mathtemp2 = BATT_FULL_LEVEL - BATT_DEAD_LEVEL; mathtemp3 = mathtemp1/mathtemp2; mathtemp4 = mathtemp3 * 100; batterylevel = (int) mathtemp4; if (batterylevel > 100) batterylevel = 100; } else batterylevel = 0; if (testmode == 1) { if (batterylevel >= 85) { BitWrPortI(PBDR, &PBDRShadow, D_ON, O_NETBAT_TEST_G); BitWrPortI(PBDR, &PBDRShadow, D_OFF, O_NETBAT_TEST_R); } else if (batterylevel >= 35) { BitWrPortI(PBDR, &PBDRShadow, D_ON, O_NETBAT_TEST_G); BitWrPortI(PBDR, &PBDRShadow, D_ON, O_NETBAT_TEST_R); } else { BitWrPortI(PBDR, &PBDRShadow, D_OFF, O_NETBAT_TEST_G); BitWrPortI(PBDR, &PBDRShadow, D_ON, O_NETBAT_TEST_R); } } }//end BatteryCheck /******************************************************************************/ /******************************************************************************/ // watch dog timer // Used to prevent endless execution of program. Kills program if program runs // more than a fixed amount of time. // Return: 1=no timeout, 0=timeout occurred int wd (int val) { int TMOUT; if (val > 0) TMOUT = val; else TMOUT = CYCLE_TMOUT; if ((read_rtc() - tmr_powerup_start) > TMOUT) { printf("Watchdog timer exceeded!\n"); debug_print("Watchdog timer exceeded!"); errorHandler(); return 0; } else return 1; }//end myWD /******************************************************************************/ /******************************************************************************/ // format buffer to be sent to the server as report // Return: 1=success, 0=fail int format_report_buf () { char report_file_buf[MAXTXDATSIZE]; // temp buffer to store report data to be written to server int i; char temp[51]; // temp register for string conversions and padding char fill_data[2]; // register for character used for padding char *fill; // pointer to padding character int fieldstart; fill_data[0] = FILE_FILL_CONST; // pad with a space fill=fill_data; // clear file buffer memset(report_file_buf, '\0', sizeof(report_file_buf)); fieldstart = 0; // write simnumber to file strncat(report_file_buf, IMEInumber, IMEI_FIELDSIZE); fieldstart = fieldstart + IMEI_FIELDSIZE; // write delay between pics to file memset(temp, '\0', sizeof(temp)); ltoa(config_pic_delay, temp); for (i=strlen(temp); i