#include <avr/io.h>
#define F_CPU 8000000// Clock Speed
#include <util/delay.h>
#include <stdlib.h>
#include <avr/interrupt.h>
#define NL 12
#define n1 10
#define n3 6
#define BAUD 9600
#define MYUBRR F_CPU/16/BAUD-1
unsigned char PIN[]="at+cpin=1234";
unsigned char SCC[]="at+csca=+40722004000";
unsigned char MEM[]="at+cpms=mt,mt,mt";
unsigned char POLL[]="at+cmgl=0";
unsigned char DEL[]="at+cmgd=1";
unsigned char CR=0x0D;
unsigned char Pnumber[12+1];
unsigned char R[4+1];
unsigned char relay_positions = 0x00;
int length;
unsigned char msg[256];
unsigned char tmp;
unsigned char antet[n1+1]="0011000B91";
unsigned char mijloc[n3+1]="0000AA";
//USART part
void USART_Transmit(unsigned char data){
    while (!(UCSRA&(1<<UDRE)))// Wait for empty transmit buffer
        ;
    UDR = data; // Put data into buffer, sends the data 
}
void USART_Transmit_string(unsigned char *data, int l){
    int i;
    for(i=0;i<l;i++)
        USART_Transmit(data[i]);
}
void USART_Flush( void ){
    unsigned char dummy;
    while ( UCSRA & (1<<RXC) ) dummy = UDR;
}
//Init Part
void Init_USART(unsigned int ubrr){
    UBRRH = (unsigned char)(ubrr>>8); //set BaudRate
    UBRRL = (unsigned char)ubrr;
    UCSRB = (1<<RXEN)|(1<<TXEN)|(1<<RXCIE); //enable Receiver and Transmitter
    UCSRC = (1<<URSEL)|(0<<USBS)|(3<<UCSZ0); //set frame format
}
void Init_Relays(){
    DDRC=0xFF;
    PORTC=relay_positions;
}
void Init_Phone(){
    USART_Transmit_string(PIN,12);
    USART_Transmit(CR);
    int j;
    for(j=0;j<100;j++)
        _delay_ms(100);
    USART_Transmit_string(MEM,16);
    USART_Transmit(CR);
    _delay_ms(1000);
    USART_Transmit_string(SCC,20);
    USART_Transmit(CR);
    _delay_ms(1000);
}
/*Rutina de descifrare a mesajelor SMS*/
void taiereantet(){
    for(int j=0;j<(length-82);j++)
        msg[j]=msg[j+82];
    length-=82;
}
void taierecapat(){
    msg[length-8]=0x00;
    length-=8;
}
void makehex(){
    unsigned char ch;
    int j=0;
    ch=msg[j];
    while(ch!=0){
        if((ch>='A')&&(ch<='F'))
            ch=ch-'A'+10;
        else if((ch>='a')&&(ch<='f'))
            ch=ch-'a'+10;
        else if((ch>='0')&&(ch<='9'))
            ch=ch-'0';
        msg[j]=ch;
        ch=msg[++j];
    }
}
void rearrange(){
    unsigned char tmp[2]={0,0};
    for(int j=0;j<=(length-1)/4;j++){
        tmp[0]=msg[2*j];
        tmp[1]=msg[(2*j)+1];
        msg[2*j]=msg[length-1-(2*j)-1];
        msg[(2*j)+1]=msg[length-1-(2*j)];
        msg[length-1-(2*j)-1]=tmp[0];
        msg[length-1-(2*j)]=tmp[1];
    }
}
void rearrange2(){
    unsigned char tmp;
    for(int j=0;j<=(length-1)/2;j++){
        tmp=msg[j];
        msg[j]=msg[length-1-j];
        msg[length-1-j]=tmp;
    }
}
void scriepe8biti(){
    unsigned char tmp;
    unsigned char c2[128];
    for(int j=(length-1);j>0;j=j-2){
        tmp=msg[j]|(msg[j-1]<<4);
        c2[j/2]=tmp;
    }
    for(int j=0;j<128;j++) 
        msg[j]=c2[j];
}
void shiftarefrate(){
    unsigned char c3[32];
    unsigned char a,b;
    int safetyspace=1+(length/7);
    for(int k=0;k<(length+safetyspace);k++)
        c3[k]=0;
    for(int k=0;k<length;k++){
        c3[k+safetyspace]=msg[k];
    }
    for(int z=(length+safetyspace-1);z>=0;z--){
        b=0;
        for(int j=z;j>=0;j--){
            a=c3[j];
            a=a>>7;
            c3[j]=c3[j]<<1;
            c3[j]=c3[j]+b;
            b=a;
        }
        c3[z]=c3[z]>>1;
    }
    length=length+safetyspace;
    for(int j=0;j<128;j++) 
        msg[j]=c3[j];
}
void descifrare_SMS(){
    rearrange();
    makehex();
    scriepe8biti();
    length/=2;
    shiftarefrate();
    rearrange2();
}
//Rutina de compunere a mesajelor SMS
/*void relaypos(){
    if((relay_positions|0b00000001))
        R[0]=1;
    if((relay_positions|0b00000100)==0b00000100)
        R[1]=1;
    if((relay_positions|0b00010000)==0b00010000)
        R[2]=1;
    if((relay_positions|0b01000000)==0b01000000)
        R[3]=1;
    R[4]=0x00;
}*/
int main(void){
    Init_USART(MYUBRR);
    Init_Relays();
    Init_Phone();
    USART_Flush();
    sei();
    while(1){
        length=0;
        USART_Transmit_string(POLL,9);
        USART_Transmit(CR);
        _delay_ms(3000);
        if(length>=13){
            if(msg[12]==0x2B){
                int j;
                for(j=0;j<12;j++)
                    Pnumber[j]=msg[j+50];
                Pnumber[12]=0x00;
                taiereantet();
                taierecapat();
                descifrare_SMS();
                if((msg[0]=='R')||(msg[0]=='r')){
                    /*if(msg[2]=='?'){
                        relaypos();
                        compose_Relaypos_msg();
                        send_SMS();
                    }*/
                    if((msg[2]=='0')||(msg[2]=='1')){
                        relay_positions=0;
                        if(msg[2]=='0')
                            relay_positions+=2;
                        if(msg[2]=='1')
                            relay_positions+=1;
                        if(msg[3]=='0')
                            relay_positions+=8;
                        if(msg[3]=='1')
                            relay_positions+=4;
                        if(msg[4]=='0')
                            relay_positions+=32;
                        if(msg[4]=='1')
                            relay_positions+=16;
                        if(msg[5]=='0')
                            relay_positions+=128;
                        if(msg[5]=='1')
                            relay_positions+=64;
                        PORTC=relay_positions;
                    }
                }
                USART_Transmit_string(DEL,9);
                USART_Transmit(CR);
                _delay_ms(1000);
            }
        }
    }
}
ISR(_VECTOR(11)) {
    length++;
    msg[length-1]=UDR;
    msg[length]=0x00;
    return;
}