#include <system.h>

#pragma DATA _CONFIG1H, _INTIO1_OSC_1H
#pragma DATA _CONFIG2H, _WDT_OFF_2H
#pragma DATA _CONFIG3H, _MCLRE_ON_3H
#pragma DATA _CONFIG4L, _LVP_ON_4L

							//  Using the PIC18LF2320

char MESSAGE[144];  		// Global variables will be capitalized from now on

char NUMBER_ONE[10];		// Stores the first saved number	

char NUMBER_TWO[10];		// Stores the second saved number

char PASSWORD[3];			// Stores the 4 character passcode

volatile bit cren@RCSTA.4;	// Used to clear the over run error

bool SECURITY;				// Security Flag

void BUFFERinit()			// Initialiaes the Message Buffer, don't want anything left over from dirty memory in there
{
	char uncount = 0;
	while(uncount <= 143)
	{
		MESSAGE[uncount++] = NULL;
	}
	return;
}


void NUMBERinit()			// Initializes the number buffer, One number is pre stored
{
	NUMBER_ONE[0] = '2';
	NUMBER_ONE[1] = '1';
	NUMBER_ONE[2] = '7';
	NUMBER_ONE[3] = '9';
	NUMBER_ONE[4] = '7';
	NUMBER_ONE[5] = '1';
	NUMBER_ONE[6] = '0';
	NUMBER_ONE[7] = '5';
	NUMBER_ONE[8] = '4';
	NUMBER_ONE[9] = '6';
	
	return;
}
	

void PASSWORDinit()			// Initializes the passcode buffer, passcode is pre stored
{
	PASSWORD[0] = 'P';
	PASSWORD[1] = 'A';
	PASSWORD[2] = 'S';
	PASSWORD[3] = 'S';
	return;
}

void USARTinit()
{
       txsta = 0b00100000;  // txsta<5> is txenable, txsta<2> is brgh
						    // We will want brgh to be 0 because it is for low speed
       rcsta = 0b10010000;  // serialportenable bit rcsta<7>
       trisc = 0b10000000;  // trisc<6 & 7>    trisc 6 = 0, trisc 7 = 1
       spbrg = 51;          // 2400, Using this from now on, more time to gather each character
						    // hopefully less error prone, and it helps to allow flag time
       intcon.7 = 1;
       intcon.6 = 1;
       pie1.4 = 1;
       pie1.5 = 0;

       return;
}


void putc(char value)		// General put c
{
       volatile bit txif@PIR1.4;

       while(!txif);

       txreg = value;

       return;
}


void put_ctrl_z()			// Special put c, it putc control-Z for use with sending text messages
{
       txreg = 0x1A;

       return;
}


void putc_special(char value)	// Artifact from testing
{
       volatile bit txif@PIR1.4;
	   
       txreg = rcreg;

       return;
}



char getc(void)					// General get c, used to light LEDs connected to c3
{
	
       volatile bit rcif@PIR1.5;
       
       char value;
	  
	   //latc.3 = 0;
	   
       while(!rcif);
       
       value = rcreg;
          
       //latc.3 = 1;
       
       
       return value;
}


void printf( const char* text )			// Print a string
{
       char i = 0;

       while( text[i] != NULL )
       {
               putc(text[i++]);
       }

       return;
}


void GM_send()				//  Send a text message to a number from which a message was just received
{
	   printf("\r\n");
	   printf("\r\n");
       delay_s(5);
       printf("AT+CMGS=+1");
       putc(MESSAGE[24]);
       putc(MESSAGE[25]);
       putc(MESSAGE[26]);
       putc(MESSAGE[27]);
       putc(MESSAGE[28]);
       putc(MESSAGE[29]);
       putc(MESSAGE[30]);
       putc(MESSAGE[31]);
       putc(MESSAGE[32]);
       putc(MESSAGE[33]);
       printf("\r\n");
       delay_s(5);
       printf("DONE");//text to send
       delay_s(5);
       put_ctrl_z();
       delay_s(5);
       printf("\r\n");
       delay_s(30);

       return;
}


// NOTE:  the I/O pins used here are also used for debugging, take them out of code before calling either of these functions
void window_open()
{

       latc.1 = 1; // direction set to open
       delay_s(3); // reduce arcing
       latc.2 = 1; // motor on
       delay_s(30); // time motor takes to open window
       latc.2 = 0; // motor off
       latc.1 = 0; // default direction set to close
       printf("\r\n");
       printf("\r\n");
       printf("WINDOW OPEN!\r\n");

       return;
}


void window_close()
{

       latc.1 = 0; // direction set to close
       delay_s(3); // reduce arcing
       latc.2 = 1; // motor on
       delay_s(30); // time motor takes to close window
       latc.2 = 0; // motor off
       latc.1 = 0; // default direction set to close
       printf("\r\n");
       printf("\r\n");
       printf("WINDOW CLOSED!\r\n");

       return;
}


void lock_con()
{

       latc.0 = 1; // unlock door
       printf("\r\n");
       printf("\r\n");
       printf("DOOR UNLOCKED!\r\n");
       delay_s(5); // time unlocked
       latc.0 = 0; // lock door again
       printf("\r\n");
       printf("\r\n");
       printf("DOOR LOCKED!\r\n");

       return;
}


void GM_debug()
{
	printf("\r\n");
   
	char count = 0;
	
	/*
	printf("?");
	putc(MESSAGE[61]);
	printf("?");
	
	printf("?");
	putc(MESSAGE[62]);				// For debugging purposes
	printf("?");
	
	printf("?");
	putc(MESSAGE[63]);
	printf("?");
	
	printf("\r\n");
    printf("\r\n");
    */
       
	while(MESSAGE[count] != NULL)		// For demonstration purposes
	{
		putc(MESSAGE[count++]);
	}

	return;
}


void GM_receive2()
{
       //printf("AT+CMGR=2\r\n"); //Reads message from memory space 2 on the SIM card
       
       printf("\r\n");
       printf("\r\n");
       
       BUFFERinit();
       
       char count = 0;
       char uncount = 0;
       bool stop_flag = 0;
       
       cren = 0;
       
       delay_s(5);
       
       cren = 1;
	   
	   
	   printf("AT+CMGR=2\r\n");	// Reads from index 2
	 
	   
	   while(!stop_flag)
	   {								// All messages end with ok, this is result code default, very useful
			MESSAGE[count] = getc();
			if(MESSAGE[count] == 'K')
			{
				stop_flag = 1;
			}
			count++;
		}
	   

	   //latc.3 = rcsta.1;
	   delay_s(5);
	   //latc.3 = rcsta.1;
	   
	   //latc.4 = 0;
	   
	   GM_debug();
       
       // all of the following is how to string compare parts of messages
       if(MESSAGE[62] == 'N' & MESSAGE[63] == 'U' & MESSAGE[64] == 'M' & MESSAGE[65] == 'B' & MESSAGE[66] == 'E' & MESSAGE[67] == 'R' & MESSAGE[68] == ' ' & MESSAGE[69] == 'O' & MESSAGE[70] == 'N' & MESSAGE[71] == 'E') // if message says add phonebook 1
       {
			if(SECURITY)
			{
				NUMBER_ONE[0] = MESSAGE[73];
				NUMBER_ONE[1] = MESSAGE[74];
				NUMBER_ONE[2] = MESSAGE[75];
				NUMBER_ONE[3] = MESSAGE[76];
				NUMBER_ONE[4] = MESSAGE[77];
				NUMBER_ONE[5] = MESSAGE[78];
				NUMBER_ONE[6] = MESSAGE[79];
				NUMBER_ONE[7] = MESSAGE[80];
				NUMBER_ONE[8] = MESSAGE[81];
				NUMBER_ONE[9] = MESSAGE[82];
				GM_send();
				latc.4 = 0;
				delay_s(5);
				latc.4 = 1;
				delay_s(5);
			}
			else
			{
				delay_s(3);
			}
	   }
       
       
       if(MESSAGE[62] == 'N' & MESSAGE[63] == 'U' & MESSAGE[64] == 'M' & MESSAGE[65] == 'B' & MESSAGE[66] == 'E' & MESSAGE[67] == 'R' & MESSAGE[68] == ' ' & MESSAGE[69] == 'T' & MESSAGE[70] == 'W' & MESSAGE[71] == 'O') // if message says add phonebook 2
       {
			if(SECURITY)
			{
				NUMBER_TWO[0] = MESSAGE[73];
				NUMBER_TWO[1] = MESSAGE[74];
				NUMBER_TWO[2] = MESSAGE[75];
				NUMBER_TWO[3] = MESSAGE[76];
				NUMBER_TWO[4] = MESSAGE[77];
				NUMBER_TWO[5] = MESSAGE[78];
				NUMBER_TWO[6] = MESSAGE[79];
				NUMBER_TWO[7] = MESSAGE[80];
				NUMBER_TWO[8] = MESSAGE[81];
				NUMBER_TWO[9] = MESSAGE[82];
				GM_send();
				latc.4 = 0;
				delay_s(5);
				latc.4 = 1;	
				delay_s(5);	
				
			}
			else
			{
				delay_s(3);
			}
	   }
       
       
       if(MESSAGE[62] == PASSWORD[0] & MESSAGE[63] == PASSWORD[1] & MESSAGE[64] == PASSWORD[2] & MESSAGE[65] == PASSWORD[3]) // if message says add phonebook 2
       {
			if(SECURITY)
			{
				PASSWORD[0] = MESSAGE[67];
				PASSWORD[1] = MESSAGE[68];
				PASSWORD[2] = MESSAGE[69];
				PASSWORD[3] = MESSAGE[70];
				GM_send();
				latc.4 = 0;
				delay_s(5);
				latc.4 = 1;	
				delay_s(5);	
				
			}
			else
			{
				delay_s(3);
			}
	   }
       
       // What to do if certain messages are received
       else if(MESSAGE[62] == 'D' & MESSAGE[63] == 'O' & MESSAGE[64] == 'O' & MESSAGE[65] == 'R' & MESSAGE[66] == ' ' & MESSAGE[67] == 'U' & MESSAGE[68] == 'N' & MESSAGE[69] == 'L' & MESSAGE[70] == 'O' & MESSAGE[71] == 'C' & MESSAGE[72] == 'K')  // if message says unlock door
	   {
			latc.3 = 0;
			delay_s(5);
			latc.3 = 1;
			delay_s(5);
			lock_con();
			GM_send();
	   }
	   else if(MESSAGE[62] == 'O' & MESSAGE[63] == 'P' & MESSAGE[64] == 'E' & MESSAGE[65] == 'N' & MESSAGE[66] == ' ' & MESSAGE[67] == 'W' & MESSAGE[68] == 'I' & MESSAGE[69] == 'N' & MESSAGE[70] == 'D' & MESSAGE[71] == 'O' & MESSAGE[72] == 'W')  // if message says open window
	   {
	   		latc.3 = 0;
			delay_s(5);
			latc.3 = 1;
			delay_s(5);
			window_open();
			GM_send();
	   }
	   else if(MESSAGE[62] == 'C' & MESSAGE[63] == 'L' & MESSAGE[64] == 'O' & MESSAGE[65] == 'S' & MESSAGE[66] == 'E' & MESSAGE[67] == ' ' & MESSAGE[68] == 'W' & MESSAGE[69] == 'I' & MESSAGE[70] == 'N' & MESSAGE[71] == 'D' & MESSAGE[72] == 'O' & MESSAGE[73] == 'W') // if message says close window
	   {
	   		latc.3 = 0;
			delay_s(5);
			latc.3 = 1;
			delay_s(5);
			window_close();
			GM_send();
	   }
		
       // Clear message buffer if nothing was accepted
       else
       {
			while(uncount <= 143)
			{
				MESSAGE[uncount++] = NULL;
			}
	   }
		
	   // If we were working continuously, then we would neeed to keep indexes 1 and 2 open all the time
	   //printf("AT+CMGD=2\r\n");//Delete the first space in memory so as to prepare for the next message
       
       
       delay_s(5);
	   
	 
	   return;
}

// Routine if the number is stored and recognized by system
void secure()
{
	if(MESSAGE[62] == PASSWORD[0] & MESSAGE[63] == PASSWORD[1] & MESSAGE[64] == PASSWORD[2] & MESSAGE[65] == PASSWORD[3]) 	  // if message says the password
	{	
		latc.3 = 0;
		delay_s(5);
		latc.3 = 1;
		delay_s(5);
		GM_receive2();
	}
	else if(MESSAGE[62] == 'D' & MESSAGE[63] == 'O' & MESSAGE[64] == 'O' & MESSAGE[65] == 'R' & MESSAGE[66] == ' ' & MESSAGE[67] == 'U' & MESSAGE[68] == 'N' & MESSAGE[69] == 'L' & MESSAGE[70] == 'O' & MESSAGE[71] == 'C' & MESSAGE[72] == 'K')  // if message says unlock door
	{
		latc.3 = 0;
		delay_s(5);
		latc.3 = 1;
		delay_s(5);
		lock_con();
		GM_send();
	}
	else if(MESSAGE[62] == 'O' & MESSAGE[63] == 'P' & MESSAGE[64] == 'E' & MESSAGE[65] == 'N' & MESSAGE[66] == ' ' & MESSAGE[67] == 'W' & MESSAGE[68] == 'I' & MESSAGE[69] == 'N' & MESSAGE[70] == 'D' & MESSAGE[71] == 'O' & MESSAGE[72] == 'W')  // if message says open window
	{
	   	latc.3 = 0;
		delay_s(5);
		latc.3 = 1;
		delay_s(5);
		window_open();
		GM_send();
	}
	else if(MESSAGE[62] == 'C' & MESSAGE[63] == 'L' & MESSAGE[64] == 'O' & MESSAGE[65] == 'S' & MESSAGE[66] == 'E' & MESSAGE[67] == ' ' & MESSAGE[68] == 'W' & MESSAGE[69] == 'I' & MESSAGE[70] == 'N' & MESSAGE[71] == 'D' & MESSAGE[72] == 'O' & MESSAGE[73] == 'W') // if message says close window
	{
	    latc.3 = 0;
		delay_s(5);
		latc.3 = 1;
		delay_s(5);
		window_close();
		GM_send();
	}
	else
	{
		latc.4 = 0;
		delay_s(5);
		latc.4 = 1;
		delay_s(5);
		delay_s(3);
	}
	
	
	// if connected to network, we would need to keep the 
	//printf("AT+CMGD=1\r\n");//Delete the first space in memory so as to prepare for the next message 
	
	return;
}

	// Routine for Unsecure, unrecognized numbers,  Is it the passcode

void unsecure()
{
	if(MESSAGE[62] == PASSWORD[0] & MESSAGE[63] == PASSWORD[1] & MESSAGE[64] == PASSWORD[2] & MESSAGE[65] == PASSWORD[3]) 	  // if message says the password
	{	
		latc.4 = 0;
		delay_s(5);
		latc.4 = 1;
		delay_s(5);
		GM_receive2();
	}
	else
	{
		latc.3 = 0;
		delay_s(5);
		latc.3 = 1;
		delay_s(5);
		delay_s(3);
	}
	
	//printf("AT+CMGD=1\r\n");//Delete the first space in memory so as to prepare for the next message 
	
	return;
}


void check_number()			// Checking to see if a number is recognized
{
	if(MESSAGE[24] == NUMBER_ONE[0] & MESSAGE[25] == NUMBER_ONE[1] & MESSAGE[26] == NUMBER_ONE[2] & MESSAGE[27] == NUMBER_ONE[3] & MESSAGE[28] == NUMBER_ONE[4] & MESSAGE[29] == NUMBER_ONE[5] & MESSAGE[30] == NUMBER_ONE[6] & MESSAGE[31] == NUMBER_ONE[7] & MESSAGE[32] == NUMBER_ONE[8] & MESSAGE[33] == NUMBER_ONE[9])  //still just a filler, need sim working to identify this
	{
		latc.4 = 0;
		delay_s(5);
		latc.4 = 1;
		delay_s(5);
		secure();
	}
	else if(MESSAGE[24] == NUMBER_TWO[0] & MESSAGE[25] == NUMBER_TWO[1] & MESSAGE[26] == NUMBER_TWO[2] & MESSAGE[27] == NUMBER_TWO[3] & MESSAGE[28] == NUMBER_TWO[4] & MESSAGE[29] == NUMBER_TWO[5] & MESSAGE[30] == NUMBER_TWO[6] & MESSAGE[31] == NUMBER_TWO[7] & MESSAGE[32] == NUMBER_TWO[8] & MESSAGE[33] == NUMBER_TWO[9])
	{
		secure();
	}
	else
	{
		latc.3 = 0;
		delay_s(5);
		latc.3 = 1;
		delay_s(5);
		unsecure();
	}
	
	return;
}


void mc_on_off()
{
       trisa.0 = 0; // MC pin for ON/OFF on the GSM modem is output
       delay_s(1);
       lata.0 = 1;
       delay_s(3);
       lata.0 = 0;

       return;
}


void GM_init()
{
       printf("ATE0\r\n");//turns off command echo
       delay_s(3);
       printf("AT+COPS=0\r\n"); // start network search
       delay_s(3);
       //printf("AT+CNUM\r\n");
       //delay_s(3);
       printf("AT+CFUN=1\r\n");//sets the gm862 so it does not go into low power mode
       delay_s(3);
       printf("AT#SELINT=2\r\n");//sets instruction set
       delay_s(3);
       printf("AT+CMGF=1\r\n");//sets the gsm to text mode
       delay_s(3);
	   printf("AT+CPMS=\"SM\"\r\n"); //sets to SIM memory to read messages
       delay_s(3);
       printf("AT#BND=3\r\n");
       delay_s(3);
       printf("AT#AUTOBND=1\r\n");
       delay_s(10);

       return;
}


void GM_receive()
{
       //printf("AT+CMGR=1\r\n"); //Reads message from memory space 1 on the SIM card
       
       BUFFERinit();
       
       char count = 0;
       char uncount = 0;
       bool stop_flag = 0;
       
       cren = 0;			// Clear overrun error
       
       delay_s(5);
       
       cren = 1;
	   
	   
	   printf("AT+CMGR=1\r\n");
	 
	   
	   while(!stop_flag)
	   {
			MESSAGE[count] = getc();
			if(MESSAGE[count] == 'K')
			{
				stop_flag = 1;
			}
			count++;
		}
	   

	   //latc.3 = rcsta.1;
	   delay_s(5);
	   //latc.3 = rcsta.1;
	   
	   
	   GM_debug();
       
       
       if(MESSAGE[12] == 'R' & MESSAGE[13] == 'E' & MESSAGE[14] == 'C' & MESSAGE[15] == ' ' & MESSAGE[16] == 'R' & MESSAGE[17] == 'E' & MESSAGE[18] == 'A' & MESSAGE[19] == 'D')  // check if read
       {
			latc.4 = 0;
			delay_s(5);
			latc.4 = 1;
			delay_s(5);
			check_number();
		}
       
       else
       {
			while(uncount <= 143)
			{
				MESSAGE[uncount++] = NULL;
			}
		}
		
		
       

	   return;
}


void main()
{
       osctune = 0b00000011;//Beginning of initialization sequence
       osccon = 0b01110110;
	   
       USARTinit();
       
       NUMBERinit();
       
       PASSWORDinit();
       
	   latc.3 = 1;
	   latc.4 = 1;
	   
       mc_on_off();
       delay_s(5);
    
	   //window_open();
	   //delay_s(5);
	   //window_close();
    
	   GM_init();//End of initialization sequence
  
	   GM_receive();
       
       while(1){
       
				delay_s(5);
				
		}
       

       return;
}