/*

*/
#include "GSM.h"
#include "string.h"
#include "stdlib.h"
#include "stdio.h"
#include "DPC_Timeout.h"
UART_HandleTypeDef huart2;

uint8_t Buffer[8]={0,};
uint8_t Buffer_T[1000]={0,};

uint8_t calibration_status=1; // 0 - не проведена настройка, 1 - проведена


void SIM800_Var_Init(SIM800_Global_Struct* Sim_Struct){

	AT_Commands_Struct* CMD_Struct;
	CMD_Struct=&Sim_Struct->Sim_At_Commands;


	CMD_Struct->AT = "AT\r\n";
	CMD_Struct->ATV = "ATV1\r\n"; //echo turn off
	CMD_Struct->ATE = "ATE1\r\n"; //answer with echo
	CMD_Struct->ATW = "AT&W\r\n"; //save presets to mem
	CMD_Struct->ATCFUN0="AT+CFUN=0\r\n"; //reboot
	CMD_Struct->ATCFUN1="AT+CFUN=1\r\n"; //reboot
	CMD_Struct->ATCMEE2="AT+CMEE=2\r\n"; //return error code
	CMD_Struct->ATCGREG="AT+CGREG?\r\n"; //gprs availability
	CMD_Struct->ATCOPS="AT+COPS=?\r\n";
	CMD_Struct->ATCOPS_Manual="AT+COPS=0,2\r\n";
	CMD_Struct->ATCPAS="AT+CPAS\r\n";
	CMD_Struct->ATCSQ="AT+CSQ\r\n";
	CMD_Struct->ATCDNSCFG_REQ="AT+CDNSCFG?\r\n";
	CMD_Struct->ATCDNSCFG="AT+CDNSCFG=\"8.8.8.8\",\"8.8.4.4\"\r\n";

	//sms
	CMD_Struct->ATCMGF1="AT+CMGF=1\r\n";
	CMD_Struct->ATCSMP="AT+CSMP=17,167,0,0\r\n";
	CMD_Struct->ATCMGFnum="AT+CMGS=\"+79253801217\"\r\n";
	CMD_Struct->ATCMGFtext="Hello\32\r\n";
	CMD_Struct->ATD="ATD+79253801217\r\n";
	CMD_Struct->ATCSCSUCS2="AT+CSCS=\"UCS2\"\r\n";

	//TIME
	CMD_Struct->ATCLTS = "AT+CLTS=1\r\n";
	CMD_Struct->ATCCLK = "AT+CCLK?\r\n";

	//GPRS
	CMD_Struct->ATCGATT_check="AT+CGATT?\r\n";
	CMD_Struct->ATCGATT_disconnect="AT+CGATT=0\r\n";
	CMD_Struct->ATCGATT_connect="AT+CGATT=1\r\n";
	CMD_Struct->ATSAPBR0="AT+SAPBR=0,1\r\n"; //close
	CMD_Struct->ATSAPBR1="AT+SAPBR=1,1\r\n"; //Set connection
	CMD_Struct->ATSAPBR2="AT+SAPBR=2,1\r\n"; //get info and IP
	CMD_Struct->ATSAPBR3_1_CONTYPE="AT+SAPBR=3,1,\"CONTYPE\",\"GPRS\"\r\n"; //CONTYPE gprs connection types
	CMD_Struct->ATSAPBR3_1_APN="AT+SAPBR=3,1,\"APN\",\"internet.beeline.ru\"\r\n"; //APN connection¤
	CMD_Struct->ATSAPBR3_1_USER="AT+SAPBR=3,1,\"USER\",\"Beeline\"\r\n"; //
	CMD_Struct->ATSAPBR3_1_PWD="AT+SAPBR=3,1,\"PWD\",\"Beeline\"\r\n"; //
	CMD_Struct->ATSAPBR4_1="AT+SAPBR=4,1\r\n"; //current settings
	CMD_Struct->ATCIFSR="AT+CIFSR\r\n"; //current settings
	CMD_Struct->ATCIPSTATUS="AT+CIPSTATUS\r\n"; //current settings
	CMD_Struct->ATCSTT="AT+CSTT=\"internet.beeline.ru\",\"Beeline\",\"Beeline\" \r\n";
	CMD_Struct->ATCIICR="AT+CIICR\r\n";
	CMD_Struct->ATCIPSHUT="AT+CIPSHUT\r\n";
	CMD_Struct->ATCIPMUX="AT+CIPMUX=0\r\n";

	//Getting location +CIPGSMLOC: 0,0.000000,0.000000,2021/11/02,14:48:00
	CMD_Struct->ATCIPGSMLOC="AT+ATCIPGSMLOC=1,1\r\n"; //Get time not location
	CMD_Struct->ATCLBS="AT+CLBS=1,1\r\n"; //get location +CLBS: 0, 37.596079, 55.711303,400
	//Latitude moscow 55.711303 Longitude 37.596079

	//HTTP
	CMD_Struct->ATHTTP="AT+HTTPINIT\r\n"; //init http
	CMD_Struct->ATHTTPPARA_CID="AT+HTTPPARA=\"CID\",1\r\n"; //set CID for http session
	CMD_Struct->ATHTTPSTATUS="AT+HTTPSTATUS?\r\n"; //check state
	CMD_Struct->ATHTTPPARA_PARAM="AT+HTTPPARA?\r\n";//parameter list

	//
	CMD_Struct->ATHTTPPARA_URL="AT+HTTPPARA=\"URL\",\"http://battery.cscw.ru/api/v1/battery\"\r\n"; //page address
	CMD_Struct->ATHTTPPARA_URL_EVENT="AT+HTTPPARA=\"URL\",\"http://battery.cscw.ru/api/v1/events\"\r\n"; //Event page address

	// TEST SERVER

	CMD_Struct->ATHTTPPARA_URL_EVENT="AT+HTTPPARA=\"URL\",\"http://ptsv2.com/t/da1w9-1638273723/post\"\r\n"; //page address
	CMD_Struct->ATHTTPPARA_URL="AT+HTTPPARA=\"URL\",\"http://ptsv2.com/t/da1w9-1638273723/post\"\r\n"; //page address

	CMD_Struct->ATHTTPP_ACTION_POST="AT+HTTPACTION=1\r\n";//POST METHOD
	CMD_Struct->ATHTTPP_ACTION_GET="AT+HTTPACTION=0\r\n";//POST METHOD
	CMD_Struct->ATHTTPPARA_CONTENT="AT+HTTPPARA=\"CONTENT\",\"application/json\"\r\n"; //set the Content-Type field in HTTP header
	CMD_Struct->ATHTTPPARA_USERDATA="AT+HTTPPARA=\"USERDATA\",\"x-api-key: 10028535-af51-45ad-8521-12973f7f6f1d\\r\\nAccept: application/json\"\r\n";
	CMD_Struct->ATHTTPHEAD="AT+HTTPHEAD\r\n";//CHECK Receive response


	//CMD_Struct->ATHTTPDATA="AT+HTTPDATA=473,5000\r\n"; //number of bytes, timeout
	//after this should return DOWNLOAD - we ready to transmit

	CMD_Struct->DATA0="{\"serial_number\": 20000054, \"started_at\": \"2021-05-04T17:59:12+0000\", \"ended_at\": "
			"\"2021-05-04T18:31:12+0000\", \"status_indication\" :13, \"energy_sum\": 250, \"battery_level_at_start\": 20, "
			"\"battery_level_at_end\": 70, \"battery_voltage_at_start\": 23.5, \"battery_voltage_at_end\": 23.9, "
			"\"battery_temperature_at_end\": 22, \"latitude\": 56.24587, \"longitude\": 43.25611, \"maximum_load_current\": 645, "
			"\"maximum_charge_current\": 150, \"internal_resistance\": 8.2111011, \"is_moderated\": false}\r\n";


	CMD_Struct->DATA2="param=20000054\r\n";
	CMD_Struct->ATHTTPACTION="AT+HTTPACTION=0\r\n"; //0-GET 1-POST 2-HEAD
	CMD_Struct->ATHTTPREAD="AT+HTTPREAD=442\r\n"; //should return 200
	CMD_Struct->ATHTTPREAD_REQ="AT+HTTPREAD?\r\n";
	CMD_Struct->ATHTTPTERM="AT+HTTPTERM\r\n"; //close
	CMD_Struct->ATSAPBR0="AT+SAPBR=0,1\r\n"; //close
	CMD_Struct->AT_CSCS_GSM="AT+CSCS=\"GSM\"\r\n";
	CMD_Struct->ATCUSD102="AT+CUSD=1,\"*102#\"\r\n";
	CMD_Struct->ATCNMI="AT+CNMI=1,2,2,1,0\r\n";
	CMD_Struct->ATCMGL="AT+CMGL=\"ALL\"\r\n";
	CMD_Struct->ATCCID="AT+CCID\r\n";
	CMD_Struct->ATCREG="AT+CREG?\r\n";
	CMD_Struct->ATCGMR="AT+CGMR=?\r\n"; //Firmware version request
	CMD_Struct->ATHTTPSSLREQUEST="AT+HTTPSSL=?\r\n";

	CMD_Struct->ATHTTPSSL="AT+HTTPSSL=0\r\n";

//	CMD_Struct->ATHTTPDATA0=malloc(100 * sizeof(char));
//	CMD_Struct->ATHTTPDATA1=malloc(100 * sizeof(char));
//
//	CMD_Struct->SE_Length1=malloc(100 * sizeof(char));
//	CMD_Struct->SE_Length2=malloc(100 * sizeof(char));
//
//	CMD_Struct->DATA1=malloc(300 * sizeof(char));
//	CMD_Struct->DATA0=malloc(500 * sizeof(char));

	CMD_Struct->ATHTTPDATA0=&CMD_Struct->ATHTTPDATA0_ch[0];
	CMD_Struct->ATHTTPDATA1=&CMD_Struct->ATHTTPDATA1_ch[0];

	CMD_Struct->SE_Length1=&CMD_Struct->SE_Length1_ch[0];
	CMD_Struct->SE_Length2=&CMD_Struct->SE_Length2_ch[0];

	CMD_Struct->DATA1=&CMD_Struct->DATA1_ch[0];
	CMD_Struct->DATA0=&CMD_Struct->DATA0_ch[0];

}

void Battery_Data_Length_Calculating(/*AT_Commands_Struct* CMD_Struct*/SIM800_Global_Struct* Sim_Struct){

	AT_Commands_Struct* CMD_Struct;
	CMD_Struct = &Sim_Struct->Sim_At_Commands;

	uint16_t Data_Length1;
	uint16_t Data_Length2;

	CMD_Struct->SE_HTTPDATA="AT+HTTPDATA=";
	CMD_Struct->SE_DATATO=",1000";
	CMD_Struct->SE_ENDOFSTRING="\r\n";

	Data_Length1 = strlen(CMD_Struct->DATA0);
	Data_Length1 =  Data_Length1 - 2;
	Data_Length2 = strlen(CMD_Struct->DATA1);
	Data_Length2 =  Data_Length2 - 2;
	//CMD_Struct->ATHTTPDATA="AT+HTTPDATA="; //number of bytes, timeout


	itoa(Data_Length1,CMD_Struct->SE_Length1, 10);
	strcpy(CMD_Struct->ATHTTPDATA0,CMD_Struct->SE_HTTPDATA);
	//strcat(CMD_Struct->ATHTTPDATA,CMD_Struct->SE_HTTPDATA);
	strcat(CMD_Struct->ATHTTPDATA0,CMD_Struct->SE_Length1);
	strcat(CMD_Struct->ATHTTPDATA0,CMD_Struct->SE_DATATO);
	strcat(CMD_Struct->ATHTTPDATA0,CMD_Struct->SE_ENDOFSTRING);

	itoa(Data_Length2,CMD_Struct->SE_Length2, 10);
	strcpy(CMD_Struct->ATHTTPDATA1,CMD_Struct->SE_HTTPDATA);
	//strcat(CMD_Struct->ATHTTPDATA,CMD_Struct->SE_HTTPDATA);
	strcat(CMD_Struct->ATHTTPDATA1,CMD_Struct->SE_Length2);
	strcat(CMD_Struct->ATHTTPDATA1,CMD_Struct->SE_DATATO);
	strcat(CMD_Struct->ATHTTPDATA1,CMD_Struct->SE_ENDOFSTRING);

}

void HTTP_Data_Init(SIM800_Global_Struct* Sim_Struct){

	HTTP_DATA_Struct* HTTP_DATA;
	HTTP_DATA=&Sim_Struct->Sim_HTTP_Data;


//	HTTP_DATA->Serial_Number = malloc(10 * sizeof(char));
//	HTTP_DATA->Battery_Condition_ID = malloc(10 * sizeof(char));
//	HTTP_DATA->Event_time = malloc(30 * sizeof(char));
//	HTTP_DATA->Started_At_Time = malloc(30 * sizeof(char));
//	HTTP_DATA->Ended_At_Time = malloc(30 * sizeof(char));
//	HTTP_DATA->Status_Indication = malloc(10 * sizeof(char));
//	HTTP_DATA->Energy_Sum = malloc(10 * sizeof(char));
//	HTTP_DATA->Battery_Level_At_Start = malloc(10 * sizeof(char));
//	HTTP_DATA->Battery_Level_At_End = malloc(10 * sizeof(char));
//	HTTP_DATA->Battery_Voltage_At_Start = malloc(10 * sizeof(char));
//	HTTP_DATA->Battery_Voltage_At_End = malloc(10 * sizeof(char));
//	HTTP_DATA->Battery_Temperature_At_End = malloc(10 * sizeof(char));
//	HTTP_DATA->Latitude = malloc(10 * sizeof(char));
//	HTTP_DATA->Longitude = malloc(10 * sizeof(char));
//	HTTP_DATA->Maximum_Load_Current = malloc(10 * sizeof(char));
//	HTTP_DATA->Maximum_Charge_Current= malloc(10 * sizeof(char));
//	HTTP_DATA->Internal_Resistance = malloc(15 * sizeof(char));
//	HTTP_DATA->Moderated = malloc(15 * sizeof(char));
//	HTTP_DATA->Current_time = malloc(30 * sizeof(char));


	HTTP_DATA->Serial_Number				 = &HTTP_DATA->Serial_Number_var[0];
	HTTP_DATA->Battery_Condition_ID			 = &HTTP_DATA->Battery_Condition_ID_var[0];
	HTTP_DATA->Event_time					 = &HTTP_DATA->Event_time_var[0];
	HTTP_DATA->Started_At_Time 				 = &HTTP_DATA->Started_At_Time_var[0];
	HTTP_DATA->Ended_At_Time				 = &HTTP_DATA->Ended_At_Time_var[0];
	HTTP_DATA->Status_Indication			 = &HTTP_DATA->Status_Indication_var[0];
	HTTP_DATA->Energy_Sum					 = &HTTP_DATA->Energy_Sum_var[0];
	HTTP_DATA->Battery_Level_At_Start		 = &HTTP_DATA->Battery_Level_At_Start_var[0];
	HTTP_DATA->Battery_Level_At_End			 = &HTTP_DATA->Battery_Level_At_End_var[0];
	HTTP_DATA->Battery_Voltage_At_Start 	 = &HTTP_DATA->Battery_Voltage_At_Start_var[0];
	HTTP_DATA->Battery_Voltage_At_End		 = &HTTP_DATA->Battery_Voltage_At_End_var[0];
	HTTP_DATA->Battery_Temperature_At_End	 = &HTTP_DATA->Battery_Temperature_At_End_var[0];
	HTTP_DATA->Latitude						 = &HTTP_DATA->Latitude_var[0];
	HTTP_DATA->Longitude					 = &HTTP_DATA->Longitude_var[0];
	HTTP_DATA->Maximum_Load_Current			 = &HTTP_DATA->Maximum_Load_Current_var[0];
	HTTP_DATA->Maximum_Charge_Current		 = &HTTP_DATA->Maximum_Charge_Current_var[0];
	HTTP_DATA->Internal_Resistance			 = &HTTP_DATA->Internal_Resistance_var[0];
	HTTP_DATA->Moderated					 = &HTTP_DATA->Moderated_var[0];
	HTTP_DATA->Current_time					 = &HTTP_DATA->Current_time_var[0];


}

void Battery_Data_Event_Processing(/*AT_Commands_Struct* CMD_Struct, HTTP_DATA_Struct* HTTP_DATA,*/SIM800_Global_Struct* Sim_Struct){

	AT_Commands_Struct* AT_CMD;
	HTTP_DATA_Struct* HTTP_DATA;

	char* Serial = "{\"serial_number\": ";
	char* BatCond = ", \"battery_condition_id\": ";
	char* EventTime = ", \"event_time\": \"";
	char* JSONEND="\"}\r\n";

	AT_CMD = &Sim_Struct->Sim_At_Commands;
	HTTP_DATA = &Sim_Struct->Sim_HTTP_Data;

	strcpy(AT_CMD->DATA1, Serial);
	strcat(AT_CMD->DATA1,HTTP_DATA->Serial_Number);
	strcat(AT_CMD->DATA1,BatCond);
	strcat(AT_CMD->DATA1,HTTP_DATA->Battery_Condition_ID);
	strcat(AT_CMD->DATA1,EventTime);
	strcat(AT_CMD->DATA1,HTTP_DATA->Event_time);
	strcat(AT_CMD->DATA1,JSONEND);
}

void Battery_Data_to_String_Converter(SIM800_Global_Struct* Sim_Struct){
	Battery_Data_Struct* Bat_data;
	//char* Raw = malloc(100 * sizeof(char));
	char* Raw = &Sim_Struct->Raw_var[0];
	int Size;
	Bat_data = &Sim_Struct->BATTERY_DATA;

	itoa(Bat_data->Serial,Raw,sizeof(Bat_data->Serial)+2);
	strcpy(Sim_Struct->Sim_HTTP_Data.Serial_Number, Raw);

	itoa(Bat_data->Battery_cond_ID,Raw,10);
	strcpy(Sim_Struct->Sim_HTTP_Data.Battery_Condition_ID, Raw);
	// SIM800_Struct.Sim_HTTP_Data.Event_time
	SIM800_Time_To_String(&Bat_data->Event_time,Sim_Struct->Sim_HTTP_Data.Event_time);
	SIM800_Time_To_String(&Bat_data->Started_At_Time,Sim_Struct->Sim_HTTP_Data.Started_At_Time);
	SIM800_Time_To_String(&Bat_data->Ended_At_Time,Sim_Struct->Sim_HTTP_Data.Ended_At_Time);

	//memcpy(Sim_Struct->Sim_HTTP_Data.Event_time,Raw,sizeof(*Raw));
	//Sim_Struct->Sim_HTTP_Data.Event_time = SIM800_Time_To_String(&Bat_data->Event_time);
	//Sim_Struct->Sim_HTTP_Data.Started_At_Time = SIM800_Time_To_String(&Bat_data->Started_At_Time);
	//Sim_Struct->Sim_HTTP_Data.Ended_At_Time = SIM800_Time_To_String(&Bat_data->Ended_At_Time);

	itoa(Bat_data->Status_Indication,Raw,10);
	strcpy(Sim_Struct->Sim_HTTP_Data.Status_Indication, Raw);

	itoa(Bat_data->Energy_Sum,Raw,10);
	strcpy(Sim_Struct->Sim_HTTP_Data.Energy_Sum, Raw);

	itoa(Bat_data->Battery_Level_At_Start,Raw,10);
	strcpy(Sim_Struct->Sim_HTTP_Data.Battery_Level_At_Start, Raw);

	itoa(Bat_data->Battery_Level_At_End,Raw,10);
	strcpy(Sim_Struct->Sim_HTTP_Data.Battery_Level_At_End, Raw);

	sprintf(Raw, "%f", Bat_data->Battery_Voltage_At_Start);
	//ftoa(Bat_data->Battery_Voltage_At_Start,Raw,sizeof(Bat_data->Battery_Voltage_At_Start));
	strcpy(Sim_Struct->Sim_HTTP_Data.Battery_Voltage_At_Start, Raw);

	sprintf(Raw, "%f", Bat_data->Battery_Voltage_At_End);
	//ftoa(Bat_data->Battery_Voltage_At_End,Raw,sizeof(Bat_data->Battery_Voltage_At_End));
	strcpy(Sim_Struct->Sim_HTTP_Data.Battery_Voltage_At_End, Raw);

	itoa(Bat_data->Battery_Temperature_At_End,Raw,10);
	strcpy(Sim_Struct->Sim_HTTP_Data.Battery_Temperature_At_End, Raw);

	itoa(Bat_data->Maximum_Load_Current,Raw,10);
	strcpy(Sim_Struct->Sim_HTTP_Data.Maximum_Load_Current, Raw);

	itoa(Bat_data->Maximum_Charge_Current,Raw,10);
	strcpy(Sim_Struct->Sim_HTTP_Data.Maximum_Charge_Current, Raw);

	sprintf(Raw, "%f", Bat_data->Internal_Resistance);
	//ftoa(Bat_data->Internal_Resistance,Raw,sizeof(Bat_data->Internal_Resistance));
	strcpy(Sim_Struct->Sim_HTTP_Data.Internal_Resistance, Raw);

	if (Bat_data->Moderated){
		strcpy(Sim_Struct->Sim_HTTP_Data.Moderated,"true");
	}
	else strcpy(Sim_Struct->Sim_HTTP_Data.Moderated,"false");

	//free(Raw);
	memset(Raw,0,100);

}

void Battery_Data_Time_Processing(SIM800_Global_Struct* Sim_Struct/*HTTP_DATA_Struct* HTTP_DATA,Time_Struct* time*/){

	HTTP_DATA_Struct* HTTP_DATA;
	Time_Struct* Time;
	char* Year_def= "{\"serial_number\": ";
	//char* Raw = malloc(100 * sizeof(char));
	char* Raw = &Sim_Struct->Raw_var[0];
	char* delimeter1 = "-";
	char* delimeter2 = ":";
	char* delimeter3 = "T";
	char* delimeter4 = "+";
	char* delimeter5 = "/0";
	uint16_t Year;

	HTTP_DATA = &Sim_Struct->Sim_HTTP_Data;
	Time = &Sim_Struct->Sim_Time;

	//2021-05-04T17:59:12+0000

	Year = Time->year +2000;
	itoa(Year,Raw,10);
	strcpy(HTTP_DATA->Current_time, Raw);
	strcat(HTTP_DATA->Current_time,delimeter1);

	itoa(Time->month,Raw,10);
	strcat(HTTP_DATA->Current_time, Raw);
	strcat(HTTP_DATA->Current_time,delimeter1);

	itoa(Time->day,Raw,10);
	strcat(HTTP_DATA->Current_time, Raw);
	strcat(HTTP_DATA->Current_time,delimeter3);

	itoa(Time->hour,Raw,10);
	strcat(HTTP_DATA->Current_time, Raw);
	strcat(HTTP_DATA->Current_time,delimeter2);

	itoa(Time->minute,Raw,10);
	strcat(HTTP_DATA->Current_time, Raw);
	strcat(HTTP_DATA->Current_time,delimeter2);

	itoa(Time->second,Raw,10);
	strcat(HTTP_DATA->Current_time, Raw);
	strcat(HTTP_DATA->Current_time,delimeter4);

	itoa(Time->timezone,Raw,10);
	strcat(HTTP_DATA->Current_time, Raw);

	//free(Raw);
	memset(Raw,0,100);
}

char Raw_Buffer[800];
char ReturnValue_Buffer[800];

void SIM800_Time_To_String(Time_Struct* Time, char* DST){

	char* Year_def= "{\"serial_number\": ";

	char* Raw = &Raw_Buffer;
	char* ReturnValue = &ReturnValue_Buffer;

	char* delimeter1 = "-";
	char* delimeter2 = ":";
	char* delimeter3 = "T";
	char* delimeter4 = "+";
	char* delimeter5 = "/0";
	uint16_t Year;


	Year = Time->year + 2000;
	itoa(Year,Raw,10);
	strcpy(DST, Raw);
	strcat(DST, delimeter1);

	itoa(Time->month,Raw,10);
	strcat(DST, Raw);
	strcat(DST,delimeter1);

	itoa(Time->day,Raw,10);
	strcat(DST, Raw);
	strcat(DST,delimeter3);

	itoa(Time->hour,Raw,10);
	strcat(DST, Raw);
	strcat(DST,delimeter2);

	itoa(Time->minute,Raw,10);
	strcat(DST, Raw);
	strcat(DST,delimeter2);

	itoa(Time->second,Raw,10);
	strcat(DST, Raw);
	strcat(DST,delimeter4);

	itoa(Time->timezone,Raw,10);
	strcat(DST, Raw);

	//free(Raw);
	//free(ReturnValue);


//	return &ReturnValue_Buffer;

}

void Battery_Data_Parameters_Processing(/*AT_Commands_Struct* CMD_Struct, HTTP_DATA_Struct* HTTP_DATA,*/SIM800_Global_Struct* Sim_Struct){

	AT_Commands_Struct* CMD_Struct;
	HTTP_DATA_Struct* HTTP_DATA;

	char* Serial = "{\"serial_number\": ";
	char* Started_At = ", \"started_at\": \"";
	char* Ended_At = "\", \"ended_at\": \"";
	char* Status_ind = "\", \"status_indication\": ";
	char* Energy= ", \"energy_sum\": ";
	char* Bat_lev_St = ", \"battery_level_at_start\": ";
	char* Bat_lev_End = ", \"battery_level_at_end\": ";
	char* Bat_V_St = ", \"battery_voltage_at_start\": ";
	char* Bat_V_End=", \"battery_voltage_at_end\": ";
	char* Bat_T_End=", \"battery_temperature_at_end\": ";
	char* Lat=", \"latitude\": ";
	char* Long=", \"longitude\": ";
	char* Max_Load_Cur=", \"maximum_load_current\": ";
	char* Max_Ch_Cur=", \"maximum_charge_current\": ";
	char* Int_Res=", \"internal_resistance\": ";
	char* Mod = ", \"is_moderated\": ";
	char* JSONEND = "}\r\n";

	CMD_Struct = &Sim_Struct->Sim_At_Commands;
	HTTP_DATA = &Sim_Struct->Sim_HTTP_Data;

	strcpy(CMD_Struct->DATA0, Serial);
	strcat(CMD_Struct->DATA0,HTTP_DATA->Serial_Number);
	strcat(CMD_Struct->DATA0,Started_At);
	strcat(CMD_Struct->DATA0,HTTP_DATA->Started_At_Time);
	strcat(CMD_Struct->DATA0,Ended_At);
	strcat(CMD_Struct->DATA0,HTTP_DATA->Ended_At_Time);
	strcat(CMD_Struct->DATA0,Status_ind);
	strcat(CMD_Struct->DATA0,HTTP_DATA->Status_Indication);
	strcat(CMD_Struct->DATA0,Energy);
	strcat(CMD_Struct->DATA0,HTTP_DATA->Energy_Sum);
	strcat(CMD_Struct->DATA0,Bat_lev_St);
	strcat(CMD_Struct->DATA0,HTTP_DATA->Battery_Level_At_Start);
	strcat(CMD_Struct->DATA0,Bat_lev_End);
	strcat(CMD_Struct->DATA0,HTTP_DATA->Battery_Level_At_End);
	strcat(CMD_Struct->DATA0,Bat_V_St);
	strcat(CMD_Struct->DATA0,HTTP_DATA->Battery_Voltage_At_Start);
	strcat(CMD_Struct->DATA0,Bat_V_End);
	strcat(CMD_Struct->DATA0,HTTP_DATA->Battery_Voltage_At_End);
	strcat(CMD_Struct->DATA0,Bat_T_End);
	strcat(CMD_Struct->DATA0,HTTP_DATA->Battery_Temperature_At_End);
	strcat(CMD_Struct->DATA0,Lat);
	strcat(CMD_Struct->DATA0,HTTP_DATA->Latitude);
	strcat(CMD_Struct->DATA0,Long);
	strcat(CMD_Struct->DATA0,HTTP_DATA->Longitude);
	strcat(CMD_Struct->DATA0,Max_Load_Cur);
	strcat(CMD_Struct->DATA0,HTTP_DATA->Maximum_Load_Current);
	strcat(CMD_Struct->DATA0,Max_Ch_Cur);
	strcat(CMD_Struct->DATA0,HTTP_DATA->Maximum_Charge_Current);
	strcat(CMD_Struct->DATA0,Int_Res);
	strcat(CMD_Struct->DATA0,HTTP_DATA->Internal_Resistance);
	strcat(CMD_Struct->DATA0,Mod);
	strcat(CMD_Struct->DATA0,HTTP_DATA->Moderated);
	strcat(CMD_Struct->DATA0,JSONEND);
}

void SIM800_RESET(SIM800_Global_Struct* Sim_Struct){
	Sim_Struct->SIM_RESET_Switch = 1;
}

void SIM800_Send_Command(char* command){
	HAL_UART_Transmit(&huart2, (uint8_t*)command, strlen(command), 20);
}

void SIM800_Send_Command_Long(char* command){
	HAL_UART_Transmit(&huart2, (uint8_t*)command, strlen(command), 50);
}

uint8_t SIM800_Received_LOOKFOR(SIM_Answer_Struct* answ, char* LOOKFOR ){
	uint8_t result=0;
	char *istr='\0';
	istr=strstr((char*)answ->SIM_answer, LOOKFOR);
	if (istr=='\0')
	{
		result=0; //nothing found
	}
	else
	{
		result=1; //found
	}
	return result;
}

void SIM800_get_time(SIM_Answer_Struct* answ, Time_Struct* time)
{
	char *istr='\0'; //answer start
	char *qstr='\0';

    istr=strstr((answ->SIM_answer),"CCLK:");
    qstr=strtok(istr+7,"/");
    time->year=atoi(qstr);
    qstr=strtok(istr+10,"/");
    time->month=atoi(qstr);
    qstr=strtok(istr+13,",");
    time->day=atoi(qstr);
    qstr=strtok(istr+16,":");
    time->hour=atoi(qstr);
    qstr=strtok(istr+19,":");
    time->minute=atoi(qstr);
    qstr=strtok(istr+22,"+");
    time->second=atoi(qstr);
    qstr=strtok(istr+25,"\"");
    time->timezone=atoi(qstr);
}

void SIM800_import_time_to_struct(SIM800_Global_Struct* Sim_Struct, Time_Struct* DST){
	*DST = Sim_Struct->Sim_Time;
}

void SIM800_Get_Coordinates(SIM800_Global_Struct* Sim_Struct/*SIM_Answer_Struct* answ, HTTP_DATA_Struct* HTTP_DATA*/){

	SIM_Answer_Struct* Answer_Struct;
	HTTP_DATA_Struct* HTTP_DATA;


	Answer_Struct = &Sim_Struct->Sim_Answer;
	HTTP_DATA = &Sim_Struct->Sim_HTTP_Data;

	char *istr='\0'; //answer start
	char *qstr='\0';

    istr=strstr((Answer_Struct->SIM_answer),"CLBS:");
    qstr=strtok(istr+8,",");
    strcpy(HTTP_DATA->Longitude,qstr);

    qstr=strtok(istr+18,",");
    strcpy(HTTP_DATA->Latitude,qstr);

}

void SIM800_Interrupt_Handler(SIM800_Global_Struct* Sim_Struct, uint8_t* UART_Buffer, uint16_t Size){

	SIM_Answer_Struct* Answer_Struct;
	Answer_Struct=&Sim_Struct->Sim_Answer;

	memset(Answer_Struct->SIM_answer, 0, 1023);
	memcpy(Answer_Struct->SIM_answer, UART_Buffer, Size);
	Answer_Struct->SIM_RX_Flag=1;
	memset(UART_Buffer, 0, 1023);

}

void SIM800_Processing(SIM800_Global_Struct* Sim_Struct, uint8_t* UART_Buf){

	if (Sim_Struct->INIT_Timeout_Active==0 && Sim_Struct->Sim_Main_States.GPRS_Established==0){
		Sim_Struct->INIT_Timeout_Active=1;
		DPC_TO_Set(TO_SIM_TIMEOUT, 120000);
	}

	if (DPC_TO_Check(TO_UART)==TO_OUT_TOOK){
		Sim_Struct->Sim_Main_States.Permission_to_Send=1;
		HAL_UARTEx_ReceiveToIdle_IT(&huart2, UART_Buf, 1023);
	}

	if (Sim_Struct->SIM_RESET_Switch){
		if (Sim_Struct->SIM_RESET_Set){
			if (DPC_TO_Check(TO_COM)==TO_OUT_TOOK){
				HAL_GPIO_WritePin(GSM_RST_GPIO_Port, GSM_RST_Pin, GPIO_PIN_SET);
				HAL_GPIO_WritePin(HL3_GPIO_Port, HL3_Pin, GPIO_PIN_RESET);
				Sim_Struct->SIM_RESET_Set = 0;
				Sim_Struct->SIM_RESET_Switch = 0;
				Sim_Struct->Sim_Main_States.Init_Complete=0;
				Sim_Struct->Sim_Main_States.GPRS_Established=0;
				Sim_Struct->Sim_Stages_List=AT;
			}
		}
		else
		{
			HAL_GPIO_WritePin(GSM_RST_GPIO_Port, GSM_RST_Pin, GPIO_PIN_RESET);
			HAL_GPIO_WritePin(HL3_GPIO_Port, HL3_Pin, GPIO_PIN_SET);
			Sim_Struct->SIM_RESET_Set = 1;
			DPC_TO_Set(TO_COM, 1000);
		}
	}

	if (DPC_TO_Check(TO_SIM_TIMEOUT)==TO_OUT_TOOK && !Sim_Struct->Sim_Main_States.GPRS_Established){
		Sim_Struct->SIM_RESET_Switch = 1;
		Sim_Struct->Sim_Stages_List = AT;
	}

		//each command have timeout
		if (DPC_TO_Check(TO_AT_TIMEOUT)==TO_OUT_TOOK ){
			if (!Sim_Struct->Sim_Main_States.Init_Complete || !Sim_Struct->Sim_Main_States.GPRS_Established){
				Sim_Struct->Sim_Stages_List = AT;
				Sim_Struct->SIM_RESET_Switch = 1;
			}
			else {
				Sim_Struct->Sim_Stages_List=READY_TO_OPERATE;
				Sim_Struct->REQUEST_Timeout_Active=0;
			}
		}

		if (SIM800_Init(Sim_Struct/*&Sim_States, &Sim_Commands, &SIM_CMD_Struct, &Sim_prev_answer, &Sim_time*/)==READY){
			Sim_Struct->Sim_States_to_return = SIM800_Active_Mode(Sim_Struct);

			if (Sim_Struct->INIT_Timeout_Active==1){
				Sim_Struct->INIT_Timeout_Active=0;
			}

		}
}

SIM800_Op_States SIM800_Init(SIM800_Global_Struct* Sim_Struct/*SIM800_States* State, Sim_Stages* CMD_Type, AT_Commands_Struct* AT_CMD ,SIM_Answer_Struct* Answer_Struct, Time_Struct* Time*/){

	SIM800_States* State;
	Sim_Stages* CMD_Type;
	AT_Commands_Struct* AT_CMD;
	SIM_Answer_Struct* Answer_Struct;
	Time_Struct* Time;

	State = &Sim_Struct->Sim_Main_States;
	CMD_Type = &Sim_Struct->Sim_Stages_List;
	AT_CMD = &Sim_Struct->Sim_At_Commands;
	Answer_Struct = &Sim_Struct->Sim_Answer;
	Time = &Sim_Struct->Sim_Time;



	if (!State->Init_Complete){
		switch(*CMD_Type){
			case AT:
				if (State->Permission_to_Send){
					SIM800_Send_Command(AT_CMD->AT);
					State->Permission_to_Send = 0;
					DPC_TO_Set(TO_UART,100);
				}
				if (Answer_Struct->SIM_RX_Flag){
					Answer_Struct->SIM_RX_Flag=0;
					if (SIM800_Received_LOOKFOR(Answer_Struct, "OK")){
						*CMD_Type = ATE;
						DPC_TO_Set(TO_AT_TIMEOUT,10000);
					}
					else {

					}
				}
				break;
			case ATE:
				if (State->Permission_to_Send){
					SIM800_Send_Command(AT_CMD->ATE);
					State->Permission_to_Send = 0;
					DPC_TO_Set(TO_UART,100);
				}
				if (Answer_Struct->SIM_RX_Flag){
					Answer_Struct->SIM_RX_Flag=0;
					if (SIM800_Received_LOOKFOR(Answer_Struct, "OK")){
						*CMD_Type = ATV;
						DPC_TO_Set(TO_AT_TIMEOUT,10000);
					}
				}
				break;
			case ATV:

				if (State->Permission_to_Send){
					SIM800_Send_Command(AT_CMD->ATV);
					State->Permission_to_Send = 0;
					DPC_TO_Set(TO_UART,100);
				}
				if (Answer_Struct->SIM_RX_Flag){
					Answer_Struct->SIM_RX_Flag=0;
					if (SIM800_Received_LOOKFOR(Answer_Struct, "OK")){
						*CMD_Type = ATCMEE2;
						DPC_TO_Set(TO_AT_TIMEOUT,10000);
					}
				}
				break;
			case ATCMEE2:

				if (State->Permission_to_Send){
					SIM800_Send_Command(AT_CMD->ATCMEE2);
					State->Permission_to_Send = 0;
					DPC_TO_Set(TO_UART,100);
				}
				if (Answer_Struct->SIM_RX_Flag){
					Answer_Struct->SIM_RX_Flag=0;
					if (SIM800_Received_LOOKFOR(Answer_Struct, "OK")){
						*CMD_Type = ATCLTS;
						DPC_TO_Set(TO_AT_TIMEOUT,10000);
					}
				}
				break;
			case ATCLTS:

				if (State->Permission_to_Send){
					SIM800_Send_Command(AT_CMD->ATCLTS);
					State->Permission_to_Send = 0;
					DPC_TO_Set(TO_UART,1000);
				}
				if (Answer_Struct->SIM_RX_Flag){
					Answer_Struct->SIM_RX_Flag=0;

					if (SIM800_Received_LOOKFOR(Answer_Struct, "CLTS") && SIM800_Received_LOOKFOR(Answer_Struct, "OK")){
						*CMD_Type = ATW;
						DPC_TO_Set(TO_AT_TIMEOUT,30000);
					}
				}
				break;

			case ATW:

				if (State->Permission_to_Send){
					SIM800_Send_Command(AT_CMD->ATW);
					State->Permission_to_Send = 0;
					DPC_TO_Set(TO_UART,100);
				}
				if (Answer_Struct->SIM_RX_Flag){
					Answer_Struct->SIM_RX_Flag=0;
					if (SIM800_Received_LOOKFOR(Answer_Struct, "OK")){
						*CMD_Type = ATCREG;
						DPC_TO_Set(TO_AT_TIMEOUT,10000);
					}
				}
				break;

			case ATCCLK:
				if (State->Permission_to_Send){
					SIM800_Send_Command(AT_CMD->ATCCLK);
					State->Permission_to_Send = 0;
					DPC_TO_Set(TO_UART,100);
				}
				if (Answer_Struct->SIM_RX_Flag){
					Answer_Struct->SIM_RX_Flag=0;
					if (SIM800_Received_LOOKFOR(Answer_Struct, "CCLK:") && SIM800_Received_LOOKFOR(Answer_Struct, "OK")){
						SIM800_get_time(Answer_Struct, Time);
 						State->Init_Complete = 1;
						*CMD_Type = ATCGATT_check;
						DPC_TO_Set(TO_AT_TIMEOUT,10000);
					}
				}
				break;

			case ATCREG:

				if (State->Permission_to_Send){
					SIM800_Send_Command(AT_CMD->ATCREG);
					State->Permission_to_Send = 0;
					DPC_TO_Set(TO_UART,1000);
				}
				if (Answer_Struct->SIM_RX_Flag){
					Answer_Struct->SIM_RX_Flag=0;
					if (SIM800_Received_LOOKFOR(Answer_Struct, "CREG: 0,1")){
						*CMD_Type = ATCCLK;
						DPC_TO_Set(TO_AT_TIMEOUT,10000);
					}
					else if (SIM800_Received_LOOKFOR(Answer_Struct, "CREG: 0,2")){
						*CMD_Type = ATCREG;
						DPC_TO_Set(TO_AT_TIMEOUT,10000);
						DPC_TO_Set(TO_UART,5000);
					}
					else if (SIM800_Received_LOOKFOR(Answer_Struct, "CREG: 0,3")){
						*CMD_Type = ATCREG;
						DPC_TO_Set(TO_AT_TIMEOUT,10000);
						DPC_TO_Set(TO_UART,5000);
					}
					else if (SIM800_Received_LOOKFOR(Answer_Struct, "CREG: 0,4")){
						*CMD_Type = ATCREG;
						DPC_TO_Set(TO_AT_TIMEOUT,10000);
					}
					else if (SIM800_Received_LOOKFOR(Answer_Struct, "CREG: 0,0")){
						*CMD_Type = ATCREG;
						DPC_TO_Set(TO_AT_TIMEOUT,10000);
					}
				}
				break;

			case ATCSQ:
				if (State->Permission_to_Send){
					SIM800_Send_Command(AT_CMD->ATCSQ);
					State->Permission_to_Send = 0;
					DPC_TO_Set(TO_UART,200);
				}
				if (Answer_Struct->SIM_RX_Flag){
					Answer_Struct->SIM_RX_Flag=0;
					if (SIM800_Received_LOOKFOR(Answer_Struct, "OK")){
						*CMD_Type = ATCREG;
						DPC_TO_Set(TO_AT_TIMEOUT,10000);
					}
				}
			break;
			case ATCOPS:

				if (State->Permission_to_Send){
					SIM800_Send_Command(AT_CMD->ATCOPS);
					State->Permission_to_Send = 0;
					DPC_TO_Set(TO_UART,15000);
				}
				if (Answer_Struct->SIM_RX_Flag){
					Answer_Struct->SIM_RX_Flag=0;
					if (SIM800_Received_LOOKFOR(Answer_Struct, "Beeline")){
						*CMD_Type = ATCOPS_Manual;
						DPC_TO_Set(TO_AT_TIMEOUT,10000);
					}
				}
				break;
			case ATCOPS_Manual:
				if (State->Permission_to_Send){
					SIM800_Send_Command(AT_CMD->ATCOPS_Manual);
					State->Permission_to_Send = 0;
					DPC_TO_Set(TO_UART,5000);
				}
				if (Answer_Struct->SIM_RX_Flag){
					Answer_Struct->SIM_RX_Flag=0;
					*CMD_Type = ATCREG;
					DPC_TO_Set(TO_AT_TIMEOUT,10000);
				}
				break;
			case ATHTTPSSLREQUEST:
				if (State->Permission_to_Send){
					SIM800_Send_Command(AT_CMD->ATHTTPSSLREQUEST);
					State->Permission_to_Send = 0;
					DPC_TO_Set(TO_UART,100);
				}
				if (Answer_Struct->SIM_RX_Flag){
					Answer_Struct->SIM_RX_Flag=0;
					if (SIM800_Received_LOOKFOR(Answer_Struct, "OK")){
						*CMD_Type = ATHTTPSTATUS;
						DPC_TO_Set(TO_AT_TIMEOUT,10000);
					}
				}
				break;
			case ATHTTPSTATUS:
				if (State->Permission_to_Send){
					SIM800_Send_Command(AT_CMD->ATHTTPSTATUS);
					State->Permission_to_Send = 0;
					DPC_TO_Set(TO_UART,100);
				}
				if (Answer_Struct->SIM_RX_Flag){
					Answer_Struct->SIM_RX_Flag=0;
					if (SIM800_Received_LOOKFOR(Answer_Struct, "OK")){
						*CMD_Type = ATCGMR;
						DPC_TO_Set(TO_AT_TIMEOUT,10000);
					}
				}
				break;

			case ATCGMR:
				if (State->Permission_to_Send){
					SIM800_Send_Command(AT_CMD->ATCGMR);
					State->Permission_to_Send = 0;
					DPC_TO_Set(TO_UART,100);
				}
				if (Answer_Struct->SIM_RX_Flag){
					Answer_Struct->SIM_RX_Flag=0;
					if (SIM800_Received_LOOKFOR(Answer_Struct, "OK")){
						State->Init_Complete = 1;
						*CMD_Type = ATCGATT_check;
						DPC_TO_Set(TO_AT_TIMEOUT,10000);
					}
				}
				break;
		}
	}
	else if (State->Init_Complete && !State->GPRS_Established){

		switch(*CMD_Type){
			case ATCGATT_check:
				//SIM800_Command(CMD_Struct.AT, answ, CMD_Struct);
				if (State->Permission_to_Send){
					SIM800_Send_Command(AT_CMD->ATCGATT_check);
					State->Permission_to_Send = 0;
					DPC_TO_Set(TO_UART,100);
				}
				if (Answer_Struct->SIM_RX_Flag){
					Answer_Struct->SIM_RX_Flag=0;
					if (SIM800_Received_LOOKFOR(Answer_Struct, "CGATT: 0")){
						*CMD_Type = ATCGATT_connect;
						DPC_TO_Set(TO_AT_TIMEOUT,10000);
					}
					else if (SIM800_Received_LOOKFOR(Answer_Struct, "CGATT: 1")){
						*CMD_Type = ATCIPSHUT;
						DPC_TO_Set(TO_AT_TIMEOUT,10000);
					}
					else if (SIM800_Received_LOOKFOR(Answer_Struct, "ERROR")){
						*CMD_Type = ATCGATT_disconnect;
						DPC_TO_Set(TO_AT_TIMEOUT,10000);
					}
				}
				break;
			case ATCGATT_disconnect:
				//SIM800_Command(CMD_Struct.AT, answ, CMD_Struct);
				if (State->Permission_to_Send){
					SIM800_Send_Command(AT_CMD->ATCGATT_disconnect);
					State->Permission_to_Send = 0;
					DPC_TO_Set(TO_UART,100);
				}
				if (Answer_Struct->SIM_RX_Flag){
					Answer_Struct->SIM_RX_Flag=0;
					if (SIM800_Received_LOOKFOR(Answer_Struct, "OK")){
						*CMD_Type = ATCGATT_check;
						DPC_TO_Set(TO_AT_TIMEOUT,20000);
					}
				}
				break;
			case ATCGATT_connect:
				//SIM800_Command(CMD_Struct.AT, answ, CMD_Struct);
				if (State->Permission_to_Send){
					SIM800_Send_Command(AT_CMD->ATCGATT_connect);
					State->Permission_to_Send = 0;
					DPC_TO_Set(TO_UART,1000);
				}
				if (Answer_Struct->SIM_RX_Flag){
					Answer_Struct->SIM_RX_Flag=0;
					if (SIM800_Received_LOOKFOR(Answer_Struct, "OK")){
						*CMD_Type = ATCGATT_check;
						DPC_TO_Set(TO_AT_TIMEOUT,20000);
					}
				}
				break;

			case ATSAPBR0:
				//SIM800_Command(CMD_Struct.AT, answ, CMD_Struct);
				if (State->Permission_to_Send){
					SIM800_Send_Command(AT_CMD->ATSAPBR0);
					State->Permission_to_Send = 0;
					DPC_TO_Set(TO_UART,100);
				}
				if (Answer_Struct->SIM_RX_Flag){
					Answer_Struct->SIM_RX_Flag=0;
					if (SIM800_Received_LOOKFOR(Answer_Struct, "OK")){
						*CMD_Type = ATSAPBR1;
						DPC_TO_Set(TO_AT_TIMEOUT,5000);
					}
				}
				break;

			//case IPPP
			case ATCIPSHUT:
				if (State->Permission_to_Send){
					SIM800_Send_Command(AT_CMD->ATCIPSHUT);
					State->Permission_to_Send = 0;
					DPC_TO_Set(TO_UART,100);
				}
				if (Answer_Struct->SIM_RX_Flag){
					Answer_Struct->SIM_RX_Flag=0;
					if (SIM800_Received_LOOKFOR(Answer_Struct, "OK")){
						*CMD_Type = ATCIPSTATUS;
						DPC_TO_Set(TO_AT_TIMEOUT,5000);
					}
				}
				break;
			case ATCIPSTATUS:
				if (State->Permission_to_Send){
					SIM800_Send_Command(AT_CMD->ATCIPSTATUS);
					State->Permission_to_Send = 0;
					DPC_TO_Set(TO_UART,100);
				}
				if (Answer_Struct->SIM_RX_Flag){
					Answer_Struct->SIM_RX_Flag=0;
					if (SIM800_Received_LOOKFOR(Answer_Struct, "IP INITIAL")){
						*CMD_Type = ATCIPMUX;
						DPC_TO_Set(TO_AT_TIMEOUT,10000);
					}
					else if (SIM800_Received_LOOKFOR(Answer_Struct, "IP GPRSACT")){
						*CMD_Type = ATCIPSTATUS;
						DPC_TO_Set(TO_AT_TIMEOUT,10000);
					}
					else if (SIM800_Received_LOOKFOR(Answer_Struct, "IP STATUS")){
						*CMD_Type = ATSAPBR2;
						DPC_TO_Set(TO_AT_TIMEOUT,10000);
					}
				}
				break;
			case ATCIPMUX:
				//SIM800_Command(CMD_Struct.AT, answ, CMD_Struct);
				if (State->Permission_to_Send){
					SIM800_Send_Command(AT_CMD->ATCIPMUX);
					State->Permission_to_Send = 0;
					DPC_TO_Set(TO_UART,500);
				}
				if (Answer_Struct->SIM_RX_Flag){
					Answer_Struct->SIM_RX_Flag=0;
					if (SIM800_Received_LOOKFOR(Answer_Struct, "OK")){
						*CMD_Type = ATCSTT;
						DPC_TO_Set(TO_AT_TIMEOUT,5000);
					}
				}
				break;

			case ATCDNSCFG:
				//SIM800_Command(CMD_Struct.AT, answ, CMD_Struct);
				if (State->Permission_to_Send){
					SIM800_Send_Command(AT_CMD->ATCDNSCFG);
					State->Permission_to_Send = 0;
					DPC_TO_Set(TO_UART,500);
				}
				if (Answer_Struct->SIM_RX_Flag){
					Answer_Struct->SIM_RX_Flag=0;
					if (SIM800_Received_LOOKFOR(Answer_Struct, "OK")){
						*CMD_Type = ATSAPBR2;
						DPC_TO_Set(TO_AT_TIMEOUT,5000);
					}
				}
			break;
			case ATCSTT:
				if (State->Permission_to_Send){
					SIM800_Send_Command(AT_CMD->ATCSTT);
					State->Permission_to_Send = 0;
					DPC_TO_Set(TO_UART,1000);
				}
				if (Answer_Struct->SIM_RX_Flag){
					Answer_Struct->SIM_RX_Flag=0;
					if (SIM800_Received_LOOKFOR(Answer_Struct, "OK")){
						*CMD_Type = ATCIICR;
						DPC_TO_Set(TO_AT_TIMEOUT,10000);
					}
				}
				break;
			case ATCIICR:
				if (State->Permission_to_Send){
					SIM800_Send_Command(AT_CMD->ATCIICR);
					State->Permission_to_Send = 0;
					DPC_TO_Set(TO_UART,1000);
				}
				if (Answer_Struct->SIM_RX_Flag){
					Answer_Struct->SIM_RX_Flag=0;
					if (SIM800_Received_LOOKFOR(Answer_Struct, "OK")){
						*CMD_Type = ATCIFSR;
						DPC_TO_Set(TO_AT_TIMEOUT,10000);
					}
				}
				break;
			case ATCIFSR:
				if (State->Permission_to_Send){
					SIM800_Send_Command(AT_CMD->ATCIFSR);
					State->Permission_to_Send = 0;
					DPC_TO_Set(TO_UART,100);
				}
				if (Answer_Struct->SIM_RX_Flag){
					Answer_Struct->SIM_RX_Flag=0;
					//if (SIM800_Check_Received(Answer_Struct, &AT_CMD)){
						*CMD_Type = ATCIPSTATUS;
						DPC_TO_Set(TO_AT_TIMEOUT,5000);
					//}
				}
				break;



			case ATSAPBR2:
				//SIM800_Command(CMD_Struct.AT, answ, CMD_Struct);
				if (State->Permission_to_Send){
					SIM800_Send_Command(AT_CMD->ATSAPBR2);
					State->Permission_to_Send = 0;
					DPC_TO_Set(TO_UART,1000);
				}
				if (Answer_Struct->SIM_RX_Flag){
					Answer_Struct->SIM_RX_Flag=0;
					if (SIM800_Received_LOOKFOR(Answer_Struct, "0.0.0.0")){
						*CMD_Type = ATSAPBR3_1_CONTYPE;
						DPC_TO_Set(TO_AT_TIMEOUT,20000);
					}
					else if (SIM800_Received_LOOKFOR(Answer_Struct, "SAPBR: 1,1")){
						*CMD_Type = ATHTTP;
					}
				}
				break;

			case ATHTTP:
				//SIM800_Command(CMD_Struct.AT, answ, CMD_Struct);
				if (State->Permission_to_Send){
					SIM800_Send_Command(AT_CMD->ATHTTP);
					State->Permission_to_Send = 0;
					DPC_TO_Set(TO_UART,200);
				}
				if (Answer_Struct->SIM_RX_Flag){
					Answer_Struct->SIM_RX_Flag=0;
					if (SIM800_Received_LOOKFOR(Answer_Struct, "OK")){
						State->GPRS_Established = 1;
						*CMD_Type = READY_TO_OPERATE;
						DPC_TO_Set(TO_AT_TIMEOUT,5000);
					}
				}
			break;

			case ATSAPBR3_1_CONTYPE:
				//SIM800_Command(CMD_Struct.AT, answ, CMD_Struct);
				if (State->Permission_to_Send){
					SIM800_Send_Command(AT_CMD->ATSAPBR3_1_CONTYPE);
					State->Permission_to_Send = 0;
					DPC_TO_Set(TO_UART,100);
				}
				if (Answer_Struct->SIM_RX_Flag){
					Answer_Struct->SIM_RX_Flag=0;
					if (SIM800_Received_LOOKFOR(Answer_Struct, "OK")){
						*CMD_Type = ATSAPBR3_1_APN;
						DPC_TO_Set(TO_AT_TIMEOUT,20000);
					}
				}
				break;
			case ATSAPBR3_1_APN:
				//SIM800_Command(CMD_Struct.AT, answ, CMD_Struct);
				if (State->Permission_to_Send){
					SIM800_Send_Command(AT_CMD->ATSAPBR3_1_APN);
					State->Permission_to_Send = 0;
					DPC_TO_Set(TO_UART,100);
				}
				if (Answer_Struct->SIM_RX_Flag){
					Answer_Struct->SIM_RX_Flag=0;
					if (SIM800_Received_LOOKFOR(Answer_Struct, "OK")){
						*CMD_Type = ATSAPBR3_1_USER;
						DPC_TO_Set(TO_AT_TIMEOUT,20000);
					}
				}
				break;

			case ATSAPBR3_1_USER:
				//SIM800_Command(CMD_Struct.AT, answ, CMD_Struct);
				if (State->Permission_to_Send){
					SIM800_Send_Command(AT_CMD->ATSAPBR3_1_USER);
					State->Permission_to_Send = 0;
					DPC_TO_Set(TO_UART,100);
				}
				if (Answer_Struct->SIM_RX_Flag){
					Answer_Struct->SIM_RX_Flag=0;
					if (SIM800_Received_LOOKFOR(Answer_Struct, "OK")){
						*CMD_Type = ATSAPBR3_1_PWD;
						DPC_TO_Set(TO_AT_TIMEOUT,20000);
					}
				}
				break;
			case ATSAPBR3_1_PWD:
				//SIM800_Command(CMD_Struct.AT, answ, CMD_Struct);
				if (State->Permission_to_Send){
					SIM800_Send_Command(AT_CMD->ATSAPBR3_1_PWD);
					State->Permission_to_Send = 0;
					DPC_TO_Set(TO_UART,1000);
				}
				if (Answer_Struct->SIM_RX_Flag){
					Answer_Struct->SIM_RX_Flag=0;
					if (SIM800_Received_LOOKFOR(Answer_Struct, "OK")){
						*CMD_Type = ATSAPBR4_1;
						DPC_TO_Set(TO_AT_TIMEOUT,20000);
					}
				}
				break;
			case ATSAPBR4_1:
				//SIM800_Command(CMD_Struct.AT, answ, CMD_Struct);
				if (State->Permission_to_Send){
					SIM800_Send_Command(AT_CMD->ATSAPBR4_1);
					State->Permission_to_Send = 0;
					DPC_TO_Set(TO_UART,1000);
				}
				if (Answer_Struct->SIM_RX_Flag){
					Answer_Struct->SIM_RX_Flag=0;
					*CMD_Type = ATSAPBR1;
					DPC_TO_Set(TO_AT_TIMEOUT,30000);

				}
				break;
			case ATSAPBR1:
				//SIM800_Command(CMD_Struct.AT, answ, CMD_Struct);
				if (State->Permission_to_Send){
					SIM800_Send_Command(AT_CMD->ATSAPBR1);
					State->Permission_to_Send = 0;
					DPC_TO_Set(TO_UART,3000);
				}
				if (Answer_Struct->SIM_RX_Flag){
					Answer_Struct->SIM_RX_Flag=0;
					if (SIM800_Received_LOOKFOR(Answer_Struct, "OK")){
						*CMD_Type = ATSAPBR2;
						DPC_TO_Set(TO_AT_TIMEOUT,20000);
					}
				}
				break;
			}
		}

	if (State->GPRS_Established) return READY;
	else return BUSY;

}

SIM800_Op_States SIM800_Set_Command(SIM800_Global_Struct* Sim_Struct, SIM800_Op_Commands CMD, uint32_t Timeout){

	if (Sim_Struct->Sim_States_to_return == READY){
		Sim_Struct->Sim_Active_Command = CMD;
		Sim_Struct->Sim_States_to_return = BUSY;
		Sim_Struct->REQUEST_Timeout = Timeout;
		Sim_Struct->REQUEST_Timeout_Active = 1;
		DPC_TO_Set(TO_AT_TIMEOUT,Timeout);
		return COMMAND_SET;
	}
	else return COMMAND_NOT_SET;
}

SIM800_Op_States SIM800_Active_Mode(SIM800_Global_Struct* Sim_Struct){



	SIM800_Op_Commands* CMD;
	Sim_Stages* Current_Stage;
	SIM800_States* State;
	AT_Commands_Struct* AT_CMD;
	SIM_Answer_Struct* Answer_Struct;
	Time_Struct* Time;

	State = &Sim_Struct->Sim_Main_States;
	AT_CMD = &Sim_Struct->Sim_At_Commands;
	Answer_Struct = &Sim_Struct->Sim_Answer;
	Time = &Sim_Struct->Sim_Time;
	CMD = &Sim_Struct->Sim_Active_Command;
	Current_Stage = &Sim_Struct->Sim_Stages_List;


	switch (*Current_Stage){
	case READY_TO_OPERATE:

		if (*CMD==GET_GPS_COORDINATES){
			*Current_Stage = GPS_Req;
		}
		else if (*CMD==HTTP_EVENT_POST){
			Battery_Data_Event_Processing(Sim_Struct);
			Battery_Data_Length_Calculating(Sim_Struct);
			*Current_Stage = ATHTTPPARA_CID;
		}
		else if (*CMD==HTTP_PARAMETERS_POST){
			Battery_Data_Parameters_Processing(Sim_Struct);
			Battery_Data_Length_Calculating(Sim_Struct);
			*Current_Stage = ATHTTPPARA_CID;
		}
		else if (*CMD==GET_TIME){
			*Current_Stage = GET_ACTUAL_TIME;
		}
	break;
	case GPS_Req:
		if (State->Permission_to_Send){
			SIM800_Send_Command(AT_CMD->ATCLBS);
			State->Permission_to_Send = 0;
			DPC_TO_Set(TO_UART,2000);
		}
		if (Answer_Struct->SIM_RX_Flag){
			Answer_Struct->SIM_RX_Flag=0;
			if (SIM800_Received_LOOKFOR(Answer_Struct, "+CLBS: 0")){
				SIM800_Get_Coordinates(Sim_Struct);
				*CMD=DONOTHING;
				*Current_Stage = READY_TO_OPERATE;
			}
			else if (SIM800_Received_LOOKFOR(Answer_Struct, "+CLBS:")){
				strcpy(Sim_Struct->Sim_HTTP_Data.Latitude,Sim_Struct->Default_Latitude);
				strcpy(Sim_Struct->Sim_HTTP_Data.Longitude,Sim_Struct->Default_Longitude);
				*Current_Stage = READY_TO_OPERATE;
				*CMD=DONOTHING;
			}
		}
	break;

	case GET_ACTUAL_TIME:
		if (State->Permission_to_Send){
			SIM800_Send_Command(AT_CMD->ATCCLK);
			State->Permission_to_Send = 0;
			DPC_TO_Set(TO_UART,100);
		}
		if (Answer_Struct->SIM_RX_Flag){
			Answer_Struct->SIM_RX_Flag=0;
			if (SIM800_Received_LOOKFOR(Answer_Struct, "CCLK:") && SIM800_Received_LOOKFOR(Answer_Struct, "OK")){
				SIM800_get_time(Answer_Struct, Time);
				*Current_Stage = READY_TO_OPERATE;
				*CMD=DONOTHING;
			}
		}
	break;

	case ATHTTPPARA_CID:
		//SIM800_Command(CMD_Struct.AT, answ, CMD_Struct);
		if (State->Permission_to_Send){
			SIM800_Send_Command(AT_CMD->ATHTTPPARA_CID);
			State->Permission_to_Send = 0;
			DPC_TO_Set(TO_UART,200);
		}
		//if (Answer_Struct->SIM_RX_Flag){
		//	Answer_Struct->SIM_RX_Flag=0;
			//if (SIM800_Received_LOOKFOR(Answer_Struct, "OK")){
				*Current_Stage = ATHTTPPARA_URL;
			//}
		//}
	break;
	case ATHTTPPARA_URL:
		//SIM800_Command(CMD_Struct.AT, answ, CMD_Struct);
		if (State->Permission_to_Send){
			if (*CMD==HTTP_EVENT_POST) SIM800_Send_Command(AT_CMD->ATHTTPPARA_URL_EVENT);
			else if (*CMD==HTTP_PARAMETERS_POST)  SIM800_Send_Command(AT_CMD->ATHTTPPARA_URL);
			State->Permission_to_Send = 0;
			DPC_TO_Set(TO_UART,200);
		}
		if (Answer_Struct->SIM_RX_Flag){
			Answer_Struct->SIM_RX_Flag=0;
			if (SIM800_Received_LOOKFOR(Answer_Struct, "OK")){
				*Current_Stage = ATHTTPPARA_CONTENT;
			}
		}
	break;

	case ATHTTPPARA_CONTENT:
		//SIM800_Command(CMD_Struct.AT, answ, CMD_Struct);
		if (State->Permission_to_Send){
			SIM800_Send_Command(AT_CMD->ATHTTPPARA_CONTENT);
			State->Permission_to_Send = 0;
			DPC_TO_Set(TO_UART,200);
		}
		if (Answer_Struct->SIM_RX_Flag){
			Answer_Struct->SIM_RX_Flag=0;
			if (SIM800_Received_LOOKFOR(Answer_Struct, "OK")){
				*Current_Stage = ATHTTPPARA_USERDATA;
			}
		}
	break;

	case ATHTTPPARA_USERDATA:
		//SIM800_Command(CMD_Struct.AT, answ, CMD_Struct);
		if (State->Permission_to_Send){
			SIM800_Send_Command(AT_CMD->ATHTTPPARA_USERDATA);
			State->Permission_to_Send = 0;
			DPC_TO_Set(TO_UART,200);
		}
		if (Answer_Struct->SIM_RX_Flag){
			Answer_Struct->SIM_RX_Flag=0;
			if (SIM800_Received_LOOKFOR(Answer_Struct, "OK")){
				*Current_Stage = ATHTTPPARA_PARAM;
			}
		}
	break;

	case ATHTTPPARA_PARAM:
		//SIM800_Command(CMD_Struct.AT, answ, CMD_Struct);
		if (State->Permission_to_Send){
			SIM800_Send_Command(AT_CMD->ATHTTPPARA_PARAM);
			State->Permission_to_Send = 0;
			DPC_TO_Set(TO_UART,1000);
		}
		if (Answer_Struct->SIM_RX_Flag){
			Answer_Struct->SIM_RX_Flag=0;
			if (SIM800_Received_LOOKFOR(Answer_Struct, "http://battery.cscw.ru/api/v1/battery")||
				SIM800_Received_LOOKFOR(Answer_Struct, "http://battery.cscw.ru/api/v1/events") ||
				SIM800_Received_LOOKFOR(Answer_Struct, "http://ptsv2.com/t/da1w9-1638273723/post")){
				*Current_Stage = ATHTTPDATA;
			}
			else {
				*Current_Stage = ATHTTPPARA_CID;
			}
		}
	break;

	case ATHTTPDATA:
		if (State->Permission_to_Send){
			if (*CMD==HTTP_EVENT_POST) SIM800_Send_Command(AT_CMD->ATHTTPDATA1);
			else if (*CMD==HTTP_PARAMETERS_POST) SIM800_Send_Command(AT_CMD->ATHTTPDATA0);
			State->Permission_to_Send = 0;
			DPC_TO_Set(TO_UART,500);
		}
		if (Answer_Struct->SIM_RX_Flag){
			Answer_Struct->SIM_RX_Flag=0;
			if (SIM800_Received_LOOKFOR(Answer_Struct, "DOWNLOAD")){
				if (*CMD==HTTP_EVENT_POST) *Current_Stage = DATA1;
				else if (*CMD==HTTP_PARAMETERS_POST) *Current_Stage = DATA0;
			}
			if (SIM800_Received_LOOKFOR(Answer_Struct, "ERROR")){
				*Current_Stage = ATHTTPPARA_CID;
			}
		}
	break;

	case DATA0:
		if (State->Permission_to_Send){
			SIM800_Send_Command_Long(AT_CMD->DATA0);
			State->Permission_to_Send = 0;
			DPC_TO_Set(TO_UART,2000);
		}
		if (Answer_Struct->SIM_RX_Flag){
			Answer_Struct->SIM_RX_Flag=0;

			if (SIM800_Received_LOOKFOR(Answer_Struct, "OK")){
				*Current_Stage = ATHTTPSSL;
			}
			if (SIM800_Received_LOOKFOR(Answer_Struct, "ERROR")){
				*Current_Stage = ATHTTPDATA;
			}
		}
	break;

	case DATA1:
		if (State->Permission_to_Send){
			SIM800_Send_Command_Long(AT_CMD->DATA1);
			State->Permission_to_Send = 0;
			DPC_TO_Set(TO_UART,2000);
		}
		if (Answer_Struct->SIM_RX_Flag){
			Answer_Struct->SIM_RX_Flag=0;
			if (SIM800_Received_LOOKFOR(Answer_Struct, "OK")){
				*Current_Stage = ATHTTPSSL;
			}
			if (SIM800_Received_LOOKFOR(Answer_Struct, "ERROR")){
				*Current_Stage = ATHTTPDATA;
			}
		}
	break;

	case ATHTTPSSL:
		if (State->Permission_to_Send){
			SIM800_Send_Command(AT_CMD->ATHTTPSSL);
			State->Permission_to_Send = 0;
			DPC_TO_Set(TO_UART,1000);
		}
		if (Answer_Struct->SIM_RX_Flag){
			Answer_Struct->SIM_RX_Flag=0;
			if (SIM800_Received_LOOKFOR(Answer_Struct, "OK")){
				*Current_Stage = ATHTTPP_ACTION_POST;
			}
		}
	break;

	case ATHTTPP_ACTION_POST:
		if (State->Permission_to_Send){
			SIM800_Send_Command(AT_CMD->ATHTTPP_ACTION_POST);
			State->Permission_to_Send = 0;
			DPC_TO_Set(TO_UART,5000);
		}
		if (Answer_Struct->SIM_RX_Flag){
			Answer_Struct->SIM_RX_Flag=0;
			if (SIM800_Received_LOOKFOR(Answer_Struct, "HTTPACTION:")){
				if (SIM800_Received_LOOKFOR(Answer_Struct, "HTTPACTION: 0,200")){
					*Current_Stage = READY_TO_OPERATE;
					*CMD=DONOTHING;
				}
				else if (SIM800_Received_LOOKFOR(Answer_Struct, "HTTPACTION: 1,200")){
					*Current_Stage = READY_TO_OPERATE;
					*CMD=DONOTHING;
				}
				else {
					*Current_Stage = ATHTTPHEAD;
				}
			}
		}
	break;

	case ATHTTPHEAD:
		//SIM800_Command(CMD_Struct.AT, answ, CMD_Struct);
		if (State->Permission_to_Send){
			SIM800_Send_Command(AT_CMD->ATHTTPHEAD);
			State->Permission_to_Send = 0;
			DPC_TO_Set(TO_UART,1000);
		}
		if (Answer_Struct->SIM_RX_Flag){
			Answer_Struct->SIM_RX_Flag=0;
			if (SIM800_Received_LOOKFOR(Answer_Struct, "OK")){
				*Current_Stage = READY_TO_OPERATE;
				*CMD=DONOTHING;
			}
		}
	break;

	case ATHTTPREAD:
		//SIM800_Command(CMD_Struct.AT, answ, CMD_Struct);
		if (State->Permission_to_Send){
			SIM800_Send_Command(AT_CMD->ATHTTPREAD);
			State->Permission_to_Send = 0;
			DPC_TO_Set(TO_UART,1000);
		}
		if (Answer_Struct->SIM_RX_Flag){
			Answer_Struct->SIM_RX_Flag=0;
			if (SIM800_Received_LOOKFOR(Answer_Struct, "OK")){
				*Current_Stage = READY_TO_OPERATE;
				*CMD=DONOTHING;
			}
		}
	break;

	case ATHTTPTERM:
		//SIM800_Command(CMD_Struct.AT, answ, CMD_Struct);
		if (State->Permission_to_Send){
			SIM800_Send_Command(AT_CMD->ATHTTPTERM);
			State->Permission_to_Send = 0;
			DPC_TO_Set(TO_UART,1000);
		}
		if (Answer_Struct->SIM_RX_Flag){
			Answer_Struct->SIM_RX_Flag=0;
			if (SIM800_Received_LOOKFOR(Answer_Struct, "OK")){
				*Current_Stage = ATHTTP;
			}
		}
	break;
	}
	if (*Current_Stage==READY_TO_OPERATE) return READY;
	else return BUSY;
}
