/*
 * OCPP.c
 *
 *  Created on: 13-Jan-2020
 *      Author: aed
 */

/**************INCLUDE BLOCK**************/
#include "OCPP.h"
#include "usart.h"
#include "modbus.h"
#include "rtc.h"
#include "w25qxx.h"
#include <stdio.h>
#include <string.h>

/***********INCLUDE BLOCK END*************/


/***** Data Type, Constant, and Macro Definitions *****/

/* Constant DATA */

/* enum struct parameters */

struct Config_Parameter OCPP; //need to change memory O.F
struct Config_Parameter_OCPP Ocpp_Setting;//need to change memory O.F
struct gsm_Parameter GSM;
struct FormData form_data;
struct Config_Parameter_Cach_Memory Cash_Memory;

/* Global variables*/

char Array1[5][50];
char meter1whclear=0;
char wifi_status=0;
char Msg_Id[50];
char offset[8];
char otp_ocpp[30];
char RTC_OCPP[14] = {0x5A, 0xA5 ,0x0B ,0x82 ,0x00,0x9c,0x5a ,0xA5 ,0x15, 0x09 ,0x11 ,0x0C ,0x0D ,0x00};

uint8_t hard_reset;
uint8_t Time_Zone;
uint8_t status = 0;
uint8_t remote_start = 0;
uint8_t Store_Key_Parameter;
uint8_t server_packet[1024];

volatile uint8_t HMI_wifi_disconnect=0,HMI_websocket_connect=0,HMI_websocket_disconnect=0,HMI_wifi_connect=0;
volatile uint8_t LocalListAdding,Local_List_Update;
volatile uint8_t inprocess =0,BootNotification_res,RemoteStarttx_res;

String Rec1[50];
String timestamp[20];
String AC001_OCPP_Con1_timestamp = "";
String ExpiryDifferanceTime = "";

int stringlen=0;

/* Extern Data Declarations */

extern uint8_t ocpp_boot_status,CURRENT_STATE;
extern char fw_update,write_para;
extern int SEC;
extern reset_cause_t reset_cause;	//V4.x.8
extern volatile uint16_t hmicp_val;
extern char req_network_select,res_downlink,req_ocpp_status,GSMreq_network_select;;
extern char websocket_success;
extern char Bootnotification[15];
extern char Statusnotification[15];
extern char metervalue[15];
extern volatile String DC001_OCPP_timestamp1;
extern uint8_t year,month,date,hour,min,sec;
extern uint8_t internet_connection;
extern uint8_t gun_1,gun_2,gun_3;
extern unsigned char  fourGtxBuffer[1000];
extern unsigned short fourgtxBufferIndex;
extern char seperator;
#if defined(ioncharge)
////////////V4.x.8////////////////////
extern unsigned char AC_01,AC_02,AC_03;
//////////////////////////////////////
#endif
extern uint8_t WIFI_Setting;
extern char fw_update,write_para;
extern char pwronFlag;
extern unsigned char WaitForResponse;	//v4.x.7 change
extern char HeartBeat_Res[15];
//ac001smart
extern char config_TXstruct,config_RXstruct,config_mode_start,config_mode;


/* Static Data Declarations */

/***** Data Type, Constant, and Macro Definitions END *****/

/***** Public Function Bodies *****/
extern int Get_Time(void);
void rtc_calibration(String rtc);
void RTC_HMI(uint8_t year, uint8_t month, uint8_t day,uint8_t hour, uint8_t min, uint8_t sec);
/***** Public Function Bodies END *****/

/**
 * @brief Send the authorization request to the server.
 *
 * @param Idtoken Authorization token.
 * @param ChargerID Charger ID.
 * @param connector Connector ID.
 * @param RandumNumber Random number.
 * @return NA
 */
void Authorizereq(String1 Idtoken,int ChargerID,int connector,unsigned int RandumNumber)
{
	//char buff[500];/* Local variable */
		char *buff;
		buff = malloc(500 * sizeof(char));

		memset((unsigned char*)fourGtxBuffer,0x00,sizeof(fourGtxBuffer));
		memset((unsigned char*)buff,0x00,sizeof(buff));

		fourgtxBufferIndex =0;
		fourGtxBuffer[fourgtxBufferIndex++]=0x02;//start byte //0
		fourGtxBuffer[fourgtxBufferIndex++]=0x94;//frame info firmware info //1
		fourGtxBuffer[fourgtxBufferIndex++]=0x01;//sub frame  //2
		fourGtxBuffer[fourgtxBufferIndex++]=0x01;//length high //3
		fourGtxBuffer[fourgtxBufferIndex++]=0x01;//length Low  //4

		stringlen = sprintf(buff,"[2,\"%u\",\"Authorize\",{\"idTag\":\"%s\"}]",RandumNumber,Idtoken); /* Fill data in buffer */
		memcpy(&fourGtxBuffer[fourgtxBufferIndex],buff,stringlen); //6 &7

		fourgtxBufferIndex+=stringlen;

		fourGtxBuffer[fourgtxBufferIndex++]=0x03;//end byte //8

		fourGtxBuffer[3]=((fourgtxBufferIndex-6)/256);  //3
		fourGtxBuffer[4]= (fourgtxBufferIndex-6) % 256;   //4

		HAL_UART_Transmit(&huart2, (uint8_t*)fourGtxBuffer,fourgtxBufferIndex,0xffff);
		free(buff);
		buff = NULL;
	//stringlen = sprintf(buff,"[2,\"%u\",\"Authorize\",{\"idTag\":\"%s\"}]",sep,RandumNumber,Idtoken); /* Fill data in buffer */

	//len_buff = strlen(buff);/* calculate length of buffer */
	//Send_msg_to_server(buff,PortNum,len_buff);/* Send message to server */
	//HAL_UART_Transmit(&huart2, (uint8_t*)buff, stringlen,0xffff);
}

/**
 * @brief Send the heartbeat to the server after a given interval.
 *
 * @param ChargerID Charger ID.
 * @param connector Connector ID.
 * @param RandumNumber Random number.
 * @return NA
 */
void Heartbeat(int ChargerID,int connector,unsigned int RandumNumber)
{
	char *buff;
		 buff = malloc(100 * sizeof(char));
	 memset((unsigned char*)fourGtxBuffer,0x00,sizeof(fourGtxBuffer));
	 memset((unsigned char*)buff,0x00,sizeof(buff));

	//		       	sprintf(&buff,"%u",content_length);
		fourgtxBufferIndex =0;
		fourGtxBuffer[fourgtxBufferIndex++]=0x02;//start byte //0
		fourGtxBuffer[fourgtxBufferIndex++]=0x94;//heartbeat
		fourGtxBuffer[fourgtxBufferIndex++]=0x01;//sub frame  //2
		fourGtxBuffer[fourgtxBufferIndex++]=0x01;//length high //3
		fourGtxBuffer[fourgtxBufferIndex++]=0x01;//length Low  //4

		stringlen= 	sprintf(buff,"[2,\"%u\",\"Heartbeat\",{}]",RandumNumber);
		memcpy(&fourGtxBuffer[fourgtxBufferIndex],buff,stringlen); //6 &7

		fourgtxBufferIndex+=stringlen;

		fourGtxBuffer[fourgtxBufferIndex++]=0x03;//end byte //8

		fourGtxBuffer[3]=((fourgtxBufferIndex-6)/256);  //3
		fourGtxBuffer[4]= (fourgtxBufferIndex-6) % 256;   //4

		HAL_UART_Transmit_DMA(&huart2, (uint8_t*)fourGtxBuffer,fourgtxBufferIndex);
		free(buff);
		buff = NULL;
}

/**
 * @brief Send the BootNotification to the server after booting the charger.
 *
 * @param chargePointModel Charge point model.
 * @param chargePointVendor Charge point vendor.
 * @param Model Model information.
 * @param ChargerID Charger ID.
 * @param connector Connector ID.
 * @param RandumNumber Random number.
 * @param ChargerType Charger type information.
 * @return NA
 */
void BootNotification(String chargePointModel,String chargePointVendor,String Model,int ChargerID,int connector,unsigned int RandumNumber,String ChargerType)
{
	char *buff;
			 buff = malloc(512 * sizeof(char));
	 memset((unsigned char*)fourGtxBuffer,0x00,sizeof(fourGtxBuffer));
   memset((unsigned char*)buff,0x00,sizeof(buff));

//		       	sprintf(&buff,"%u",content_length);
	fourgtxBufferIndex =0;
	fourGtxBuffer[fourgtxBufferIndex++]=0x02;//start byte //0
	fourGtxBuffer[fourgtxBufferIndex++]=0x94;//frame info firmware info //1
	fourGtxBuffer[fourgtxBufferIndex++]=0x01;//sub frame  //2
	fourGtxBuffer[fourgtxBufferIndex++]=0x01;//length high //3
	fourGtxBuffer[fourgtxBufferIndex++]=0x01;//length Low  //4
#if target == actype2
	stringlen= sprintf(buff, "[2,\"%u\",\"BootNotification\",{\"chargePointVendor\":\"%s\",\"chargePointModel\":\"%s\",\"chargePointSerialNumber\":\"%s\",\"firmwareVersion\":\"SS_AC001_V0.0.1\"}]",RandumNumber,OCPP.vendor_id,"SS_ACTYPE2",OCPP.serial_no);/* Fill data in buffer */
#else
	stringlen= sprintf(buff, "[2,\"%u\",\"BootNotification\",{\"chargePointVendor\":\"%s\",\"chargePointModel\":\"%s\",\"chargePointSerialNumber\":\"%s\",\"firmwareVersion\":\"SS_AC001_V0.0.1\"}]",RandumNumber,OCPP.vendor_id,"SS_AC001",OCPP.serial_no);/* Fill data in buffer */
#endif
	memcpy(&fourGtxBuffer[fourgtxBufferIndex],buff,stringlen); //6 &7

	fourgtxBufferIndex+=stringlen;

	fourGtxBuffer[fourgtxBufferIndex++]=0x03;//end byte //8

	fourGtxBuffer[3]=((fourgtxBufferIndex-6)/256);  //3
	fourGtxBuffer[4]= (fourgtxBufferIndex-6) % 256;   //4

	HAL_UART_Transmit(&huart2, (uint8_t*)fourGtxBuffer,fourgtxBufferIndex,0xffff);
	free(buff);
	buff = NULL;
}

/**
 * @brief Send the StopTransaction request to the server after each stop request from the charger.
 *
 * @param RandumNumber Random number.
 * @param Idtoken Authorization token.
 * @param meterstopvalue Meter stop value.
 * @param reason Reason for stopping the transaction.
 * @param transactionId Transaction ID.
 * @param ChargerID Charger ID.
 * @param connector Connector ID.
 * @param datetime Date and time information.
 * @return 1 on success, NA otherwise.
 */
char StopTransactionreq(unsigned int RandumNumber,String Idtoken,unsigned long int meterstopvalue,char * reason,unsigned int transactionId,int ChargerID,int connector,String datetime)
{
		char *buff;
		buff = malloc(800 * sizeof(char));
		memset((unsigned char*)fourGtxBuffer,0x00,sizeof(fourGtxBuffer));
		memset((unsigned char*)buff,0x00,sizeof(buff));

		//		       	sprintf(&buff,"%u",content_length);
		fourgtxBufferIndex =0;
		fourGtxBuffer[fourgtxBufferIndex++]=0x02;//start byte //0
		fourGtxBuffer[fourgtxBufferIndex++]=0x94;//frame info firmware info //1
		fourGtxBuffer[fourgtxBufferIndex++]=0x01;//sub frame  //2
		fourGtxBuffer[fourgtxBufferIndex++]=0x01;//length high //3
		fourGtxBuffer[fourgtxBufferIndex++]=0x01;//length Low  //4

		stringlen= sprintf(buff,"[2,\"%u\",\"StopTransaction\",{\"idTag\":\"%s\",\"meterStop\":%ld,\"timestamp\":\"%s\",\"transactionId\":%d,\"reason\":\"%s\"}]",RandumNumber,Idtoken,(int)meterstopvalue,datetime,transactionId,reason); // @suppress("Float formatting support")
		memcpy(&fourGtxBuffer[fourgtxBufferIndex],buff,stringlen); //6 &7

		fourgtxBufferIndex+=stringlen;

		fourGtxBuffer[fourgtxBufferIndex++]=0x03;//end byte //8

		fourGtxBuffer[3]=((fourgtxBufferIndex-6)/256);  //3
		fourGtxBuffer[4]= (fourgtxBufferIndex-6) % 256;   //4

		HAL_UART_Transmit_DMA(&huart2, (uint8_t*)fourGtxBuffer,fourgtxBufferIndex);

		free(buff);
		buff =	NULL;

	return 1;/* Return value */
}
/**
 * @brief Send the FirmwareStatusNotification request to the server.
 *
 * @param RandumNumber Random number.
 * @param version Firmware version.
 * @return 1 on success, NA otherwise.
 */
char FirmwareStatusNotificationreq(unsigned int RandumNumber,int version)
{
		char *buff;
		buff = malloc(512 * sizeof(char));

		memset((unsigned char*)fourGtxBuffer,0x00,sizeof(fourGtxBuffer));
		memset((unsigned char*)buff,0x00,sizeof(buff));

		//		       	sprintf(&buff,"%u",content_length);
		fourgtxBufferIndex =0;
		fourGtxBuffer[fourgtxBufferIndex++]=0x02;//start byte //0
		fourGtxBuffer[fourgtxBufferIndex++]=0x94;//frame info firmware info //1
		fourGtxBuffer[fourgtxBufferIndex++]=0x01;//sub frame  //2
		fourGtxBuffer[fourgtxBufferIndex++]=0x01;//length high //3
		fourGtxBuffer[fourgtxBufferIndex++]=0x01;//length Low  //4

		stringlen=	sprintf(buff,"[2,\"%u\",\"FirmwareStatusNotification\",{\"status\":\"Installed\"}]",RandumNumber); // @suppress("Float formatting support")
		memcpy(&fourGtxBuffer[fourgtxBufferIndex],buff,stringlen); //6 &7

		fourgtxBufferIndex+=stringlen;

		fourGtxBuffer[fourgtxBufferIndex++]=0x03;//end byte //8

		fourGtxBuffer[3]=((fourgtxBufferIndex-6)/256);  //3
		fourGtxBuffer[4]= (fourgtxBufferIndex-6) % 256;   //4

		HAL_UART_Transmit_DMA(&huart2, (uint8_t*)fourGtxBuffer,fourgtxBufferIndex);

		free(buff);
		buff = NULL;
		return 1;/* Return value */
}
/**
** Function name:		Metervalue
**
** Descriptions:		Send the metervalues to server after charger goes into charging state
**
** parameters:			ChargerID,connector,RandumNumber,transactionId,Val,DateTime
** Returned value:		None
**
*/
void Metervalue_ClockAlign(int ChargerID,int connector,unsigned int RandumNumber,unsigned int transactionId,float current,float voltage,float power,float energy,String DateTime)
{
	char *buff;
	buff = malloc(1024 * sizeof(char));
	memset((unsigned char*)fourGtxBuffer,0x00,sizeof(fourGtxBuffer));
	memset((unsigned char*)buff,0x00,sizeof(buff));

//		       	sprintf(&buff,"%u",content_length);
	fourgtxBufferIndex =0;
	fourGtxBuffer[fourgtxBufferIndex++]=0x02;//start byte //0
	fourGtxBuffer[fourgtxBufferIndex++]=0x94;//frame info firmware info //1
	fourGtxBuffer[fourgtxBufferIndex++]=0x01;//sub frame  //2
	fourGtxBuffer[fourgtxBufferIndex++]=0x01;//length high //3
	fourGtxBuffer[fourgtxBufferIndex++]=0x01;//length Low  //4


	stringlen=	sprintf(buff,"[2,\"%u\",\"MeterValues\",{\"connectorId\":%d,\"meterValue\":[{\"timestamp\": \"%s\",\"sampledValue\":[{\"unit\":\"A\",\"measurand\":\"Current.Import\",\"format\":\"Raw\",\"context\":\"Sample.Clock\",\"value\":\"%f\"},{\"unit\":\"W\",\"measurand\":\"Power.Active.Import\",\"format\":\"Raw\",\"context\":\"Sample.Clock\",\"value\":\"%f\"},{\"unit\":\"V\",\"measurand\":\"Voltage\",\"format\":\"Raw\",\"context\":\"Sample.Clock\",\"value\":\"%f\"},{\"unit\":\"Wh\",\"measurand\":\"Energy.Active.Import.Register\",\"format\":\"Raw\",\"context\":\"Sample.Clock\",\"value\":\"%f\"}]}]}]",RandumNumber,connector,DateTime,current,power,voltage,energy);
	memcpy(&fourGtxBuffer[fourgtxBufferIndex],buff,stringlen); //6 &7

	fourgtxBufferIndex+=stringlen;

	fourGtxBuffer[fourgtxBufferIndex++]=0x03;//end byte //8

	fourGtxBuffer[3]=((fourgtxBufferIndex-6)/256);  //3
	fourGtxBuffer[4]= (fourgtxBufferIndex-6) % 256;   //4

	HAL_UART_Transmit(&huart2, (uint8_t*)fourGtxBuffer,fourgtxBufferIndex,0xffff);
	free(buff);
	buff = NULL;
}

/**
 * @brief Send the meter values to the server after the charger goes into the charging state (System format).
 *
 * @param ChargerID Charger ID.
 * @param connector Connector ID.
 * @param RandumNumber Random number.
 * @param transactionId Transaction ID.
 * @param current Current value.
 * @param voltage Voltage value.
 * @param power Power value.
 * @param energy Energy value.
 * @param DateTime Date and time information.
 * @return NA
 */
void Metervalue_ClockAlign_System(int ChargerID,int connector,unsigned int RandumNumber,unsigned int transactionId,float current,float voltage,float power,float energy,String DateTime)
{
	char *buff;
	buff = malloc(1024 * sizeof(char));
	memset((unsigned char*)fourGtxBuffer,0x00,sizeof(fourGtxBuffer));
	memset((unsigned char*)buff,0x00,sizeof(buff));

	//		       	sprintf(&buff,"%u",content_length);
	fourgtxBufferIndex =0;
	fourGtxBuffer[fourgtxBufferIndex++]=0x02;//start byte //0
	fourGtxBuffer[fourgtxBufferIndex++]=0x94;//frame info firmware info //1
	fourGtxBuffer[fourgtxBufferIndex++]=0x01;//sub frame  //2
	fourGtxBuffer[fourgtxBufferIndex++]=0x01;//length high //3
	fourGtxBuffer[fourgtxBufferIndex++]=0x01;//length Low  //4


	stringlen=	sprintf(buff,"[2,\"%u\",\"MeterValues\",{\"connectorId\":%d,\"meterValue\":[{\"timestamp\": \"%s\",\"sampledValue\":[{\"unit\":\"A\",\"measurand\":\"Current.Import\",\"format\":\"Raw\",\"context\":\"Sample.Clock\",\"value\":\"%f\"},{\"unit\":\"kW\",\"measurand\":\"Power.Active.Import\",\"format\":\"Raw\",\"context\":\"Sample.Clock\",\"value\":\"%f\"},{\"unit\":\"V\",\"measurand\":\"Voltage\",\"format\":\"Raw\",\"context\":\"Sample.Clock\",\"value\":\"%f\"},{\"unit\":\"kWh\",\"measurand\":\"Energy.Active.Import.Register\",\"format\":\"Raw\",\"context\":\"Sample.Clock\",\"value\":\"%f\"}]}]}]",RandumNumber,connector,DateTime,current,power,voltage,energy);
	memcpy(&fourGtxBuffer[fourgtxBufferIndex],buff,stringlen); //6 &7

	fourgtxBufferIndex+=stringlen;

	fourGtxBuffer[fourgtxBufferIndex++]=0x03;//end byte //8

	fourGtxBuffer[3]=((fourgtxBufferIndex-6)/256);  //3
	fourGtxBuffer[4]= (fourgtxBufferIndex-6) % 256;   //4

	HAL_UART_Transmit(&huart2, (uint8_t*)fourGtxBuffer,fourgtxBufferIndex,0xffff);
	free(buff);
//	/* Local variable */
//	stringlen=	sprintf(buff,"[2,\"%u\",\"MeterValues\",{\"connectorId\":%d,\"meterValue\":[{\"timestamp\": \"%s\",\"sampledValue\":[{\"unit\":\"A\",\"measurand\":\"Current.Import\",\"format\":\"Raw\",\"context\":\"Sample.Clock\",\"value\":\"%f\"},{\"unit\":\"kW\",\"measurand\":\"Power.Active.Import\",\"format\":\"Raw\",\"context\":\"Sample.Clock\",\"value\":\"%f\"},{\"unit\":\"V\",\"measurand\":\"Voltage\",\"format\":\"Raw\",\"context\":\"Sample.Clock\",\"value\":\"%f\"},{\"unit\":\"kWh\",\"measurand\":\"Energy.Active.Import.Register\",\"format\":\"Raw\",\"context\":\"Sample.Clock\",\"value\":\"%f\"}]}]}]",sep,RandumNumber,connector,DateTime,current,power,voltage,energy);
////	UART_Printf("Meter Value length : %d ",strlen(buff));
//	HAL_UART_Transmit(&huart2, (uint8_t*)buff, stringlen,0xffff);
}

/**
 * @brief Send the meter values to the server periodically.
 *
 * @param ChargerID Charger ID.
 * @param connector Connector ID.
 * @param RandumNumber Random number.
 * @param transactionId Transaction ID.
 * @param current Current value.
 * @param voltage Voltage value.
 * @param power Power value.
 * @param energy Energy value.
 * @param DateTime Date and time information.
 * @return NA
 */
void Metervalue_Periodic(int ChargerID,int connector,unsigned int RandumNumber,unsigned int transactionId,float current,float voltage,float power,float energy,String DateTime)
{
	char *buff;
	buff = malloc(1024 * sizeof(char));
	memset((unsigned char*)fourGtxBuffer,0x00,sizeof(fourGtxBuffer));
	memset((unsigned char*)buff,0x00,sizeof(buff));

	//		       	sprintf(&buff,"%u",content_length);
	fourgtxBufferIndex =0;
	fourGtxBuffer[fourgtxBufferIndex++]=0x02;//start byte //0
	fourGtxBuffer[fourgtxBufferIndex++]=0x94;//frame info firmware info //1
	fourGtxBuffer[fourgtxBufferIndex++]=0x01;//sub frame  //2
	fourGtxBuffer[fourgtxBufferIndex++]=0x01;//length high //3
	fourGtxBuffer[fourgtxBufferIndex++]=0x01;//length Low  //4


	stringlen=	sprintf(buff,"[2,\"%u\",\"MeterValues\",{\"connectorId\":%d,\"transactionId\":%d,\"meterValue\":[{\"timestamp\": \"%s\",\"sampledValue\":[{\"unit\":\"A\",\"measurand\":\"Current.Import\",\"format\":\"Raw\",\"context\":\"Sample.Periodic\",\"value\":\"%f\"},{\"unit\":\"W\",\"measurand\":\"Power.Active.Import\",\"format\":\"Raw\",\"context\":\"Sample.Periodic\",\"value\":\"%f\"},{\"unit\":\"V\",\"measurand\":\"Voltage\",\"format\":\"Raw\",\"context\":\"Sample.Periodic\",\"value\":\"%f\"}, {\"unit\":\"Wh\",\"measurand\":\"Energy.Active.Import.Register\",\"format\":\"Raw\",\"context\":\"Sample.Periodic\",\"value\":\"%f\"}]}]}]",RandumNumber,connector,transactionId,DateTime,current,power,voltage,energy);
	memcpy(&fourGtxBuffer[fourgtxBufferIndex],buff,stringlen); //6 &7

	fourgtxBufferIndex+=stringlen;

	fourGtxBuffer[fourgtxBufferIndex++]=0x03;//end byte //8

	fourGtxBuffer[3]=((fourgtxBufferIndex-6)/256);  //3
	fourGtxBuffer[4]= (fourgtxBufferIndex-6) % 256;   //4

	HAL_UART_Transmit(&huart2, (uint8_t*)fourGtxBuffer,fourgtxBufferIndex,0xffff);

	/* Local variable */
	stringlen=	sprintf(buff,"[2,\"%u\",\"MeterValues\",{\"connectorId\":%d,\"transactionId\":%d,\"meterValue\":[{\"timestamp\": \"%s\",\"sampledValue\":[{\"unit\":\"A\",\"measurand\":\"Current.Import\",\"format\":\"Raw\",\"context\":\"Sample.Periodic\",\"value\":\"%f\"},{\"unit\":\"W\",\"measurand\":\"Power.Active.Import\",\"format\":\"Raw\",\"context\":\"Sample.Periodic\",\"value\":\"%f\"},{\"unit\":\"V\",\"measurand\":\"Voltage\",\"format\":\"Raw\",\"context\":\"Sample.Periodic\",\"value\":\"%f\"}, {\"unit\":\"Wh\",\"measurand\":\"Energy.Active.Import.Register\",\"format\":\"Raw\",\"context\":\"Sample.Periodic\",\"value\":\"%f\"}]}]}]",RandumNumber,connector,transactionId,DateTime,current,power,voltage,energy);
	free(buff);
	buff = NULL;
}

/**
 * @brief Send the meter values to the server when a charging transaction begins.
 *
 * @param ChargerID Charger ID.
 * @param connector Connector ID.
 * @param RandumNumber Random number.
 * @param transactionId Transaction ID.
 * @param current Current value.
 * @param voltage Voltage value.
 * @param power Power value.
 * @param energy Energy value.
 * @param DateTime Date and time information.
 * @return NA
 */
void Metervalue_Began(int ChargerID,int connector,unsigned int RandumNumber,unsigned int transactionId,float current,float voltage,float power,float energy,String DateTime)
{
		char *buff;
		buff = malloc(1024 * sizeof(char));
		memset((unsigned char*)fourGtxBuffer,0x00,sizeof(fourGtxBuffer));
		memset((unsigned char*)buff,0x00,sizeof(buff));

		fourgtxBufferIndex =0;
		fourGtxBuffer[fourgtxBufferIndex++]=0x02;//start byte //0
		fourGtxBuffer[fourgtxBufferIndex++]=0x94;//frame info firmware info //1
		fourGtxBuffer[fourgtxBufferIndex++]=0x01;//sub frame  //2
		fourGtxBuffer[fourgtxBufferIndex++]=0x01;//length high //3
		fourGtxBuffer[fourgtxBufferIndex++]=0x01;//length Low  //4


		stringlen=	sprintf(buff,"[2,\"%u\",\"MeterValues\",{\"connectorId\":%d,\"transactionId\":%d,\"meterValue\":[{\"timestamp\": \"%s\",\"sampledValue\":[{\"unit\":\"A\",\"measurand\":\"Current.Import\",\"format\":\"Raw\",\"context\":\"Transaction.Begin\",\"value\":\"%f\"},{\"unit\":\"W\",\"measurand\":\"Power.Active.Import\",\"format\":\"Raw\",\"context\":\"Transaction.Begin\",\"value\":\"%f\"},{\"unit\":\"V\",\"measurand\":\"Voltage\",\"format\":\"Raw\",\"context\":\"Transaction.Begin\",\"value\":\"%f\"}, {\"unit\":\"Wh\",\"measurand\":\"Energy.Active.Import.Register\",\"format\":\"Raw\",\"context\":\"Transaction.Begin\",\"value\":\"%f\"}]}]}]",RandumNumber,connector,transactionId,DateTime,current,power,voltage,energy);
		memcpy(&fourGtxBuffer[fourgtxBufferIndex],buff,stringlen); //6 &7

		fourgtxBufferIndex+=stringlen;

		fourGtxBuffer[fourgtxBufferIndex++]=0x03;//end byte //8

		fourGtxBuffer[3]=((fourgtxBufferIndex-6)/256);  //3
		fourGtxBuffer[4]= (fourgtxBufferIndex-6) % 256;   //4

		HAL_UART_Transmit(&huart2, (uint8_t*)fourGtxBuffer,fourgtxBufferIndex,0xffff);
		free(buff);
		buff =NULL;
}

/**
 * @brief Send the meter values to the server after the charging transaction ends.
 *
 * @param ChargerID Charger ID.
 * @param connector Connector ID.
 * @param RandumNumber Random number.
 * @param transactionId Transaction ID.
 * @param current Current value.
 * @param voltage Voltage value.
 * @param power Power value.
 * @param energy Energy value.
 * @param DateTime Date and time information.
 * @return NA
 */
void Metervalue_End(int ChargerID,int connector,unsigned int RandumNumber,unsigned int transactionId,float current,float voltage,float power,float energy,String DateTime)
{
		char *buff;
		buff = malloc(1024 * sizeof(char));
		memset((unsigned char*)fourGtxBuffer,0x00,sizeof(fourGtxBuffer));
		memset((unsigned char*)buff,0x00,sizeof(buff));

		//		       	sprintf(&buff,"%u",content_length);
		fourgtxBufferIndex =0;
		fourGtxBuffer[fourgtxBufferIndex++]=0x02;//start byte //0
		fourGtxBuffer[fourgtxBufferIndex++]=0x94;//frame info firmware info //1
		fourGtxBuffer[fourgtxBufferIndex++]=0x01;//sub frame  //2
		fourGtxBuffer[fourgtxBufferIndex++]=0x01;//length high //3
		fourGtxBuffer[fourgtxBufferIndex++]=0x01;//length Low  //4


		stringlen=	sprintf(buff,"[2,\"%u\",\"MeterValues\",{\"connectorId\":%d,\"transactionId\":%d,\"meterValue\":[{\"timestamp\": \"%s\",\"sampledValue\":[{\"unit\":\"A\",\"measurand\":\"Current.Import\",\"format\":\"Raw\",\"context\":\"Transaction.End\",\"value\":\"%f\"},{\"unit\":\"W\",\"measurand\":\"Power.Active.Import\",\"format\":\"Raw\",\"context\":\"Transaction.End\",\"value\":\"%f\"},{\"unit\":\"V\",\"measurand\":\"Voltage\",\"format\":\"Raw\",\"context\":\"Transaction.End\",\"value\":\"%f\"}, {\"unit\":\"Wh\",\"measurand\":\"Energy.Active.Import.Register\",\"format\":\"Raw\",\"context\":\"Transaction.End\",\"value\":\"%f\"}]}]}]",RandumNumber,connector,transactionId,DateTime,current,power,voltage,energy);
		memcpy(&fourGtxBuffer[fourgtxBufferIndex],buff,stringlen); //6 &7

		fourgtxBufferIndex+=stringlen;

		fourGtxBuffer[fourgtxBufferIndex++]=0x03;//end byte //8

		fourGtxBuffer[3]=((fourgtxBufferIndex-6)/256);  //3
		fourGtxBuffer[4]= (fourgtxBufferIndex-6) % 256;   //4

		HAL_UART_Transmit(&huart2, (uint8_t*)fourGtxBuffer,fourgtxBufferIndex,0xffff);
		free(buff);
		buff = NULL;
}

/**
 * @brief Send the StartTransaction request to the server after a charging start request from the charger.
 *
 * @param RandumNumber Random number.
 * @param ChargerID Charger ID.
 * @param connector Connector ID.
 * @param Idtoken Authorization token.
 * @param meterstartval Meter start value.
 * @param ReservationId Reservation ID.
 * @param datetime Date and time information.
 * @return 0 on success, NA otherwise.
 */
char StartTransactionreq(unsigned int RandumNumber,int ChargerID,int connector, String Idtoken,unsigned long int meterstartval,String ReservationId, String datetime)
{

		char *buff;
		buff = malloc(612 * sizeof(char));
		memset((unsigned char*)fourGtxBuffer,0x00,sizeof(fourGtxBuffer));
		memset((unsigned char*)buff,0x00,sizeof(buff));

		//		       	sprintf(&buff,"%u",content_length);
		fourgtxBufferIndex =0;
		fourGtxBuffer[fourgtxBufferIndex++]=0x02;//start byte //0
		fourGtxBuffer[fourgtxBufferIndex++]=0x94;//frame info firmware info //1
		fourGtxBuffer[fourgtxBufferIndex++]=0x01;//sub frame  //2
		fourGtxBuffer[fourgtxBufferIndex++]=0x01;//length high //3
		fourGtxBuffer[fourgtxBufferIndex++]=0x01;//length Low  //4

		stringlen=	sprintf(buff,"[2,\"%u\",\"StartTransaction\",{\"reservationId\": 0,\"timestamp\": \"%s\",\"meterStart\": %ld,\"idTag\": \"%s\",\"connectorId\": %d}]",RandumNumber,datetime,meterstartval,Idtoken,connector);
		memcpy(&fourGtxBuffer[fourgtxBufferIndex],buff,stringlen); //6 &7

		fourgtxBufferIndex+=stringlen;

		fourGtxBuffer[fourgtxBufferIndex++]=0x03;//end byte //8

		fourGtxBuffer[3]=((fourgtxBufferIndex-6)/256);  //3
		fourGtxBuffer[4]= (fourgtxBufferIndex-6) % 256;   //4

		HAL_UART_Transmit_DMA(&huart2, (uint8_t*)fourGtxBuffer,fourgtxBufferIndex);

		free(buff);
		buff = NULL;
		return 0;/* Return value */
}


#ifdef DATATRANSFER
/**
 * @brief Transfer data from the charger to the server.
 *
 * @param RandumNumber Random number.
 * @param vendorid Vendor ID.
 * @param MessageID Message ID.
 * @return NA
 */
void DataTransfer(unsigned int RandumNumber,String vendorid,String MessageID)
{

	memset((unsigned char*)fourGtxBuffer,0x00,sizeof(fourGtxBuffer));
		memset((unsigned char*)buff,0x00,sizeof(buff));

	//		       	sprintf(&buff,"%u",content_length);
		fourgtxBufferIndex =0;
		fourGtxBuffer[fourgtxBufferIndex++]=0x02;//start byte //0
		fourGtxBuffer[fourgtxBufferIndex++]=0x94;//frame info firmware info //1
		fourGtxBuffer[fourgtxBufferIndex++]=0x01;//sub frame  //2
		fourGtxBuffer[fourgtxBufferIndex++]=0x01;//length high //3
		fourGtxBuffer[fourgtxBufferIndex++]=0x01;//length Low  //4


		//stringlen=sprintf(buff,"[2,\"%u\",\"DataTransfer\",{\"vendorId\":\"%s\",\"messageId\":\"%s\",\"tagid\":[{\"tag1\":\"%s\"},{\"tag2\":\"%s\"},{\"tag3\":\"%s\"},{\"tag4\":\"%s\"},{\"tag5\":\"%s\"}]}]",RandumNumber,vendorid,MessageID,OCPP.rfid1,OCPP.rfid2,OCPP.rfid3,OCPP.rfid4,OCPP.rfid5);
		memcpy(&fourGtxBuffer[fourgtxBufferIndex],&buff,stringlen); //6 &7

		fourgtxBufferIndex+=stringlen;

		fourGtxBuffer[fourgtxBufferIndex++]=0x03;//end byte //8

		fourGtxBuffer[3]=((fourgtxBufferIndex-6)/256);  //3
		fourGtxBuffer[4]= (fourgtxBufferIndex-6) % 256;   //4

		HAL_UART_Transmit_DMA(&huart2, (uint8_t*)fourGtxBuffer,fourgtxBufferIndex);

	//char buff[500];/* Local variable */
	//sprintf(buff,"API*[2,\"%u\",\"Dat]aTransfer\",{\"vendorId\":\"%s\",\"messageId\":\"%s\",\"data\":\"%s\"}]",RandumNumber,vendorid,MessageID,Datastatus);/* Fill data in buffer */

//	stringlen=sprintf(buff,"[2,\"%u\",\"DataTransfer\",{\"vendorId\":\"%s\",\"messageId\":\"%s\",\"tagid\":[{\"tag1\":\"%s\"},{\"tag2\":\"%s\"},{\"tag3\":\"%s\"},{\"tag4\":\"%s\"},{\"tag5\":\"%s\"}]}]",RandumNumber,vendorid,MessageID,OCPP.rfid1,OCPP.rfid2,OCPP.rfid3,OCPP.rfid4,OCPP.rfid5);
//	HAL_UART_Transmit_DMA(&huart2, (uint8_t*)buff, stringlen);
}
/**
 * @brief Transfer charging type data to the server.
 *
 * @param RandumNumber Random number.
 * @param transactionId Transaction ID.
 * @param vendorid Vendor ID.
 * @param MessageID Message ID.
 * @param type Charging type.
 * @param value Value associated with the charging type.
 * @return NA
 */
void DataTransferChargingType(unsigned int RandumNumber,unsigned long transactionId,String vendorid,String MessageID,String type,int value)
{
	memset((unsigned char*)fourGtxBuffer,0x00,sizeof(fourGtxBuffer));
	memset((unsigned char*)buff,0x00,sizeof(buff));

//		       	sprintf(&buff,"%u",content_length);
	fourgtxBufferIndex =0;
	fourGtxBuffer[fourgtxBufferIndex++]=0x02;//start byte //0
	fourGtxBuffer[fourgtxBufferIndex++]=0x94;//frame info firmware info //1
	fourGtxBuffer[fourgtxBufferIndex++]=0x01;//sub frame  //2
	fourGtxBuffer[fourgtxBufferIndex++]=0x01;//length high //3
	fourGtxBuffer[fourgtxBufferIndex++]=0x01;//length Low  //4

	stringlen =sprintf(buff,"[2,\"%u\",\"DataTransfer\",{\"transactionId\":%u,\"vendorId\":\"%s\",\"messageId\":\"ChargingType\",\"Type\":\"%s\",\"Value\":%d}]",RandumNumber,transactionId,vendorid,type,value);/* Fill data in buffer */
	memcpy(&fourGtxBuffer[fourgtxBufferIndex],&buff,stringlen); //6 &7

	fourgtxBufferIndex+=stringlen;

	fourGtxBuffer[fourgtxBufferIndex++]=0x03;//end byte //8

	fourGtxBuffer[3]=((fourgtxBufferIndex-6)/256);  //3
	fourGtxBuffer[4]= (fourgtxBufferIndex-6) % 256;   //4

	HAL_UART_Transmit_DMA(&huart2, (uint8_t*)fourGtxBuffer,fourgtxBufferIndex);

	//char buff[200];/* Local variable */
//	stringlen =sprintf(buff,"[2,\"%u\",\"DataTransfer\",{\"transactionId\":%u,\"vendorId\":\"%s\",\"messageId\":\"ChargingType\",\"Type\":\"%s\",\"Value\":%d}]",RandumNumber,transactionId,vendorid,type,value);/* Fill data in buffer */
////	len_buff = strlen(buff);/* calculate length of buffer */
////	Send_msg_to_server(buff,PortNum,len_buff);/* Send message to server */
//	HAL_UART_Transmit_DMA(&huart2, (uint8_t*)buff, stringlen);
}
#endif

/**
 * @brief Get response for the configuration request.
 *
 * @param RandumNumber Random number.
 * @param interval Interval value.
 * @return NA
 */
void getconfig_response(String RandumNumber,int interval)
{
		char *buff;
		buff = malloc(1024 * sizeof(char));
		memset((unsigned char*)buff,0x00,sizeof(buff));
		memset((unsigned char*)fourGtxBuffer,0x00,sizeof(fourGtxBuffer));
		char *buff1; /* Local variable */
	//	int len;
#if ocpptype == jiobp
//		stringlen = sprintf(buff,"[3,%s,{\"configurationKey\":[{\"key\":\"MeterValueSampleInterval\",\"readonly\":false,\"value\":\"%d\"},{\"key\":\"MinimumStatusDuration\",\"readonly\":false,\"value\":\"%d\"},{\"key\":\"HeartbeatInterval\",\"readonly\":false,\"value\":\"%d\"},{\"key\":\"ResetRetries\",\"readonly\":false,\"value\":\"%d\"},{\"key\":\"TransactionMessageRetryInterval\",\"readonly\":false,\"value\":\"%d\"},{\"key\":\"ClockAlignedDataInterval\",\"readonly\":false,\"value\":\"%d\"},{\"key\":\"TransactionMessageAttempts\",\"readonly\":false,\"value\":\"%d\"},{\"key\":\"StopTransactionOnInvalidId\",\"readonly\":false,\"value\":\"%s\"},{\"key\":\"LocalPreAuthorize\",\"readonly\":true,\"value\":\"%s\"},{\"key\":\"LocalAuthorizeOffline\",\"readonly\":false,\"value\":\"%s\"},{\"key\":\"AuthorizeRemoteTxRequests\",\"readonly\":false,\"value\":\"%s\"},{\"key\":\"AuthorizationCacheEnabled\",\"readonly\":false,\"value\":\"%s\"},{\"key\":\"AllowOfflineTxForUnknownId\",\"readonly\":false,\"value\":\"%s\"}],\"unknownKey\":[\"\"]}]",RandumNumber,Ocpp_Setting.MeterIntvl,Ocpp_Setting.StatusDuration,Ocpp_Setting.HeartbeatIntvl,Ocpp_Setting.ResetRetry,Ocpp_Setting.FailedTx_Intvl,Ocpp_Setting.ClkAlgnIntvl,Ocpp_Setting.FailedAttempt,(Ocpp_Setting.StopTxInvalidId == 1 ? "true" : "false"),(Ocpp_Setting.LocalPreAuth  == 1 ? "true" : "false"),(Ocpp_Setting.LocalAuthOffln  == 1 ? "true" : "false"),(Ocpp_Setting.AuthRemotTx == 1 ?"true":"false"),(Ocpp_Setting.AuthCachEnable == 1 ?"true":"false"),(Ocpp_Setting.AllowOfflineTXUnknownId == 1 ?"true":"false"));/* Fill data in buffer */
		stringlen = sprintf(buff,"[3,%s,{\"configurationKey\":[{\"key\":\"MeterValueSampleInterval\",\"readonly\":false,\"value\":\"%d\"},{\"key\":\"MinimumStatusDuration\",\"readonly\":false,\"value\":\"%d\"},{\"key\":\"HeartbeatInterval\",\"readonly\":false,\"value\":\"%d\"},{\"key\":\"ResetRetries\",\"readonly\":false,\"value\":\"%d\"},{\"key\":\"TransactionMessageRetryInterval\",\"readonly\":false,\"value\":\"%d\"},{\"key\":\"ClockAlignedDataInterval\",\"readonly\":false,\"value\":\"%d\"},{\"key\":\"TransactionMessageAttempts\",\"readonly\":false,\"value\":\"%d\"},{\"key\":\"StopTransactionOnInvalidId\",\"readonly\":false,\"value\":\"%s\"},{\"key\":\"LocalPreAuthorize\",\"readonly\":true,\"value\":\"%s\"},{\"key\":\"LocalAuthorizeOffline\",\"readonly\":false,\"value\":\"%s\"},{\"key\":\"AuthorizeRemoteTxRequests\",\"readonly\":false,\"value\":\"%s\"},{\"key\":\"AuthorizationCacheEnabled\",\"readonly\":false,\"value\":\"%s\"},{\"key\":\"GroundFaultDetection\",\"readonly\":false,\"value\":\"%s\"}],\"unknownKey\":[\"\"]}]",RandumNumber,Ocpp_Setting.MeterIntvl,Ocpp_Setting.StatusDuration,Ocpp_Setting.HeartbeatIntvl,Ocpp_Setting.ResetRetry,Ocpp_Setting.FailedTx_Intvl,Ocpp_Setting.ClkAlgnIntvl,Ocpp_Setting.FailedAttempt,(Ocpp_Setting.StopTxInvalidId == 1 ? "true" : "false"),(Ocpp_Setting.LocalPreAuth  == 1 ? "true" : "false"),(Ocpp_Setting.LocalAuthOffln  == 1 ? "true" : "false"),(Ocpp_Setting.AuthRemotTx == 1 ?"true":"false"),(Ocpp_Setting.AuthCachEnable == 1 ?"true":"false"),(Ocpp_Setting.GroundFaultDetection == 1 ?"true":"false"));
#else
#if gunno == three
		stringlen = sprintf(buff,"[3,%s,{\"configurationKey\":[{\"key\":\"SupportedFeatureProfiles\",\"readonly\":true,\"value\":\"Core,FirmwareManagement,RemoteTrigger\"},{\"key\":\"LocalPreAuthorize\",\"readonly\":true,\"value\":\"False\"},{\"key\":\"AuthorizationCacheEnabled\",\"readonly\":true,\"value\":\"False\"},{\"key\":\"MinimumStatusDuration\",\"readonly\":false,\"value\":\"60\"},{\"key\":\"ResetRetries\",\"readonly\":false,\"value\":\"2\"},{\"key\":\"StopTransactionOnEVSideDisconnect\",\"readonly\":true,\"value\":\"false\"},{\"key\":\"UnlockConnectorOnEVSideDisconnect\",\"readonly\":true,\"value\":\"false\"},{\"key\":\"NumberOfConnectors\",\"readonly\":true,\"value\":\"1\"},{\"key\":\"MeterValueSampleInterval\",\"readonly\":false,\"value\":\"60\"},{\"key\":\"MeterValuesSampledDataMaxLength\",\"readonly\":false,\"value\":\"4\"},{\"key\":\"HeartbeatInterval\",\"readonly\":false,\"value\":\"%d\"}],\"unknownKey\":[\"\"]}]",RandumNumber,interval);/* Fill data in buffer */
#else
		stringlen = sprintf(buff,"[3,%s,{\"configurationKey\":[{\"key\":\"SupportedFeatureProfiles\",\"readonly\":true,\"value\":\"Core,FirmwareManagement,RemoteTrigger\"},{\"key\":\"LocalPreAuthorize\",\"readonly\":true,\"value\":\"False\"},{\"key\":\"AuthorizationCacheEnabled\",\"readonly\":true,\"value\":\"False\"},{\"key\":\"MinimumStatusDuration\",\"readonly\":false,\"value\":\"60\"},{\"key\":\"ResetRetries\",\"readonly\":false,\"value\":\"2\"},{\"key\":\"StopTransactionOnEVSideDisconnect\",\"readonly\":true,\"value\":\"false\"},{\"key\":\"UnlockConnectorOnEVSideDisconnect\",\"readonly\":true,\"value\":\"false\"},{\"key\":\"NumberOfConnectors\",\"readonly\":true,\"value\":\"3\"},{\"key\":\"MeterValueSampleInterval\",\"readonly\":false,\"value\":\"60\"},{\"key\":\"MeterValuesSampledDataMaxLength\",\"readonly\":false,\"value\":\"4\"},{\"key\":\"HeartbeatInterval\",\"readonly\":false,\"value\":\"%d\"}],\"unknownKey\":[\"\"]}]",RandumNumber,interval);/* Fill data in buffer */
#endif
#endif
		//	Send_msg_to_server(buff,PortNum,len_buff);/* Send message to server */
	//	len = strlen(buff);

		fourgtxBufferIndex =0;
		fourGtxBuffer[fourgtxBufferIndex++]=0x02;//start byte //0
		fourGtxBuffer[fourgtxBufferIndex++]=0x94;//frame info firmware info //1
		fourGtxBuffer[fourgtxBufferIndex++]=0x02;//sub frame  //2
		fourGtxBuffer[fourgtxBufferIndex++]=0x01;//length high //3
		fourGtxBuffer[fourgtxBufferIndex++]=0x01;//length Low  //4

		memcpy(&fourGtxBuffer[fourgtxBufferIndex],buff,stringlen); //6 &7

		fourgtxBufferIndex+=stringlen;
		fourGtxBuffer[fourgtxBufferIndex++]=0x03;//end byte //8
		fourGtxBuffer[3]=((fourgtxBufferIndex-6)/256);  //3
		fourGtxBuffer[4]= (fourgtxBufferIndex-6) % 256;   //4
		 HAL_UART_Transmit_DMA(&huart2, (uint8_t*)fourGtxBuffer,fourgtxBufferIndex);
	//	HAL_UART_Transmit_DMA(&huart2, (uint8_t*)&fourGtxBuffer[465],(fourgtxBufferIndex-465));
		//delay_ms(1000);
		free(buff);
		buff = NULL;
}

/**
 * @brief Send a response for a reset request to the server.
 *
 * @param RandumNumber Random number.
 * @param response Status response.
 * @return NA
 */
void reset_response(String RandumNumber,String response)
{
	char buff[100];
//	char *buff;
//			 buff = malloc(200 * sizeof(char));
		memset((unsigned char*)fourGtxBuffer,0x00,sizeof(fourGtxBuffer));
		memset((unsigned char*)buff,0x00,sizeof(buff));

	//		       	sprintf(&buff,"%u",content_length);
		fourgtxBufferIndex =0;
		fourGtxBuffer[fourgtxBufferIndex++]=0x02;//start byte //0
		fourGtxBuffer[fourgtxBufferIndex++]=0x94;//frame info firmware info //1
		fourGtxBuffer[fourgtxBufferIndex++]=0x01;//sub frame  //2
		fourGtxBuffer[fourgtxBufferIndex++]=0x01;//length high //3
		fourGtxBuffer[fourgtxBufferIndex++]=0x01;//length Low  //4


		stringlen=	sprintf(buff,"[3,%s,{\"status\":\"\%s\"}]",RandumNumber,response);
		memcpy(&fourGtxBuffer[fourgtxBufferIndex],&buff,stringlen); //6 &7

		fourgtxBufferIndex+=stringlen;

		fourGtxBuffer[fourgtxBufferIndex++]=0x03;//end byte //8

		fourGtxBuffer[3]=((fourgtxBufferIndex-6)/256);  //3
		fourGtxBuffer[4]= (fourgtxBufferIndex-6) % 256;   //4

		HAL_UART_Transmit_DMA(&huart2, (uint8_t*)fourGtxBuffer,fourgtxBufferIndex);

//		free(buff);
//		buff = NULL;
}

/**
 * @brief Send the status of the charger to the server.
 *
 * @param RandumNumber Random number.
 * @param ChargerID Charger ID.
 * @param connector Connector ID.
 * @param status Charger status.
 * @param datetime Date and time of the status notification.
 * @param error Error code associated with the status (if any).
 * @return NA
 */
void StatusNotification(unsigned int RandumNumber,int ChargerID,int connector, String status, String datetime,String error)
{
	char *buff;
			 buff = malloc(600 * sizeof(char));
	memset((unsigned char*)fourGtxBuffer,0x00,sizeof(fourGtxBuffer));
		memset((unsigned char*)buff,0x00,sizeof(buff));

	//		       	sprintf(&buff,"%u",content_length);
		fourgtxBufferIndex =0;
		fourGtxBuffer[fourgtxBufferIndex++]=0x02;//start byte //0
		fourGtxBuffer[fourgtxBufferIndex++]=0x94;//frame info firmware info //1
		fourGtxBuffer[fourgtxBufferIndex++]=0x01;//sub frame  //2
		fourGtxBuffer[fourgtxBufferIndex++]=0x01;//length high //3
		fourGtxBuffer[fourgtxBufferIndex++]=0x01;//length Low  //4

#if defined(ioncharge)
		stringlen=	sprintf(buff,"[2,\"%u\",\"StatusNotification\",{\"connectorId\":%d,\"errorCode\":\"%s\",\"status\":\"%s\",\"timestamp\":\"%s\",\"vendorId\":\"LUBI-AC-2021\",\"vendorErrorCode\":\"%d\"}]",RandumNumber,connector,error,status,datetime,hmicp_val);/* Fill data in buffer */	//V4.x.8
#else
		stringlen=	sprintf(buff,"[2,\"%u\",\"StatusNotification\",{\"connectorId\":%d,\"errorCode\":\"%s\",\"status\":\"%s\",\"timestamp\":\"%s\",\"vendorId\":\"LUBI-AC-2021\",\"vendorErrorCode\":\"%d\"}]",RandumNumber,connector,error,status,datetime,reset_cause);/* Fill data in buffer */	//V4.x.8
#endif
		memcpy(&fourGtxBuffer[fourgtxBufferIndex],buff,stringlen); //6 &7

		fourgtxBufferIndex+=stringlen;

		fourGtxBuffer[fourgtxBufferIndex++]=0x03;//end byte //8

		fourGtxBuffer[3]=((fourgtxBufferIndex-6)/256);  //3
		fourGtxBuffer[4]= (fourgtxBufferIndex-6) % 256;   //4

		HAL_UART_Transmit_DMA(&huart2, (uint8_t*)fourGtxBuffer,fourgtxBufferIndex);
		free(buff);
		buff = NULL;
}

/**
 * @brief Send a remote start transaction request to the server.
 *
 * @param RandumNumber Random number.
 * @param Resp_status Response status.
 * @return NA
 */
void RemoteStartTransaction(String RandumNumber, String Resp_status)
{
	char *buff;
			 buff = malloc(100 * sizeof(char));

	memset((unsigned char*)fourGtxBuffer,0x00,sizeof(fourGtxBuffer));
	memset((unsigned char*)buff,0x00,sizeof(buff));

//		       	sprintf(&buff,"%u",content_length);
	fourgtxBufferIndex =0;
	fourGtxBuffer[fourgtxBufferIndex++]=0x02;//start byte //0
	fourGtxBuffer[fourgtxBufferIndex++]=0x94;//frame info firmware info //1
	fourGtxBuffer[fourgtxBufferIndex++]=0x01;//sub frame  //2
	fourGtxBuffer[fourgtxBufferIndex++]=0x01;//length high //3
	fourGtxBuffer[fourgtxBufferIndex++]=0x01;//length Low  //4


	stringlen=sprintf(buff,"[3,%s,{\"status\":\"%s\"}]",Msg_Id,Resp_status);
	memcpy(&fourGtxBuffer[fourgtxBufferIndex],buff,stringlen); //6 &7

	fourgtxBufferIndex+=stringlen;

	fourGtxBuffer[fourgtxBufferIndex++]=0x03;//end byte //8

	fourGtxBuffer[3]=((fourgtxBufferIndex-6)/256);  //3
	fourGtxBuffer[4]= (fourgtxBufferIndex-6) % 256;   //4

	HAL_UART_Transmit_DMA(&huart2, (uint8_t*)fourGtxBuffer,fourgtxBufferIndex);
free(buff);
buff = NULL;
}

/**
 * @brief Send a remote stop transaction request to the server.
 *
 * @param RandumNumber Random number.
 * @param Resp_status Response status.
 * @return NA
 */
void RemoteStopTransaction(int RandumNumber, String Resp_status)
{
	char *buff;
			 buff = malloc(100 * sizeof(char));
	memset((unsigned char*)fourGtxBuffer,0x00,sizeof(fourGtxBuffer));
	memset((unsigned char*)buff,0x00,sizeof(buff));

//		       	sprintf(&buff,"%u",content_length);
	fourgtxBufferIndex =0;
	fourGtxBuffer[fourgtxBufferIndex++]=0x02;//start byte //0
	fourGtxBuffer[fourgtxBufferIndex++]=0x94;//frame info firmware info //1
	fourGtxBuffer[fourgtxBufferIndex++]=0x01;//sub frame  //2
	fourGtxBuffer[fourgtxBufferIndex++]=0x01;//length high //3
	fourGtxBuffer[fourgtxBufferIndex++]=0x01;//length Low  //4

	stringlen =sprintf(buff,"[3,\"%u\",{\"status\":\"%s\"}]",RandumNumber,Resp_status);/* Fill data in buffer */
	memcpy(&fourGtxBuffer[fourgtxBufferIndex],buff,stringlen); //6 &7

	fourgtxBufferIndex+=stringlen;

	fourGtxBuffer[fourgtxBufferIndex++]=0x03;//end byte //8

	fourGtxBuffer[3]=((fourgtxBufferIndex-6)/256);  //3
	fourGtxBuffer[4]= (fourgtxBufferIndex-6) % 256;   //4

	HAL_UART_Transmit_DMA(&huart2, (uint8_t*)fourGtxBuffer,fourgtxBufferIndex);
	//char buff[500];/* Local variable */
	stringlen =sprintf(buff,"[3,\"%u\",{\"status\":\"%s\"}]",RandumNumber,Resp_status);/* Fill data in buffer */
//	len_buff = strlen(buff);/* calculate length of buffer */
//	Send_msg_to_server(buff,PortNum,len_buff);/* Send message to server */
	HAL_UART_Transmit_DMA(&huart2, (uint8_t*)buff, stringlen);

	free(buff);
	buff = NULL;
}

/**
 * @brief Process the received data from the server.
 *
 * @param None.
 * @return None.
 */
void process_ReceiveArray(void)
{

	//char *found;
	//char day,month,year,min,sec,dow;
	inprocess = 1;
	if(server_packet[0] == '[')
	{

		int i = 0;// Local variable
		int j = 0;// Local variable
		int k = 0;// Local variable
		memset(Rec1,'\0',sizeof(Rec1));		//V4.x.8

	    for(i=0;i<1024;i++)
	    {
	    	if((server_packet[i] == '[') && (server_packet[i-1] != ':' ) ) //If start char of packet received
				{
					k = 0;// Reset the value
					j = 0;// Reset the value
				}
				else if(((server_packet[i] == ']') && ((server_packet[i+1] != '}') && (server_packet[i+1] != ',') )) || (server_packet[i] == '\r'))// If stop char of packet received
				{
					Rec1[j][k] = '\0';
					k = 0;// Reset the value
					j = 0;// Reset the value
					i = 0;// Reset the value
					memset(server_packet,'\0',sizeof(server_packet));
					break;
				}
				else
				{
					if(server_packet[i] != ',')// If comma char in packet received
					{
						Rec1[j][k] = server_packet[i]; // Assign the server packet
						k++;// increment value
					}
					else
					{
						Rec1[j][k] = '\0';
						k = 0; // Reset the value
						j++;// increment value
					}
				}
	    }
//	    Assign_recieve_data(Rec1[0],Rec1[1],Rec1[2]);
	  //  HAL_UART_Transmit(&huart1, (uint8_t*)Rec1[2],strlen(Rec1[2]),0xffff);
	    process_incoming_string();
	}
	else if(server_packet[0] == 0x02)
	{
		if(server_packet[1] == 0x82)  // Request Network
		{
			if(server_packet[2] == 1)	//esp module
			{
				GSMreq_network_select = 0;
				req_network_select = 1;
				ocpp_boot_status = 0;
				websocket_success = 0;
				HMI_wifi_disconnect = 1;
				wifi_status = 0;				//ac001
				config_mode_start = 1;		//ac001
				HMI_websocket_connect = 0;
				internet_connection = 255;
			}
			else if(server_packet[2] == 2)	//GSM module //v4.x.6 changes here//////
			{
				req_network_select = 0;
				GSMreq_network_select = 1;
				req_network_select = 0;
				ocpp_boot_status = 0;
				websocket_success = 0;
				HMI_wifi_disconnect = 1;
				wifi_status = 0;
				HMI_websocket_connect = 0;
				internet_connection = 255;
			}

		}
		else if(server_packet[1] == 0x83) // request OCPP uri (Internet connection)
		{
			if(server_packet[2] == 1)
			{
				wifi_status=1;
				wifi_connected = 1;
				HMI_wifi_connect = 1;
			}
			else if(server_packet[2] == 2)
			{
			    if(server_packet[5] == 0)
				{
			    	wifi_status=0;
					websocket_success = 0;
					HMI_wifi_disconnect = 1;
					HMI_websocket_connect = 0;
					internet_connection = 255;
				}
			}
		}
		else if(server_packet[1] == 0x84) // request OCPP status
		{
			if(server_packet[2] == 1)
			{
				req_ocpp_status = 1;
			}
		}
		else if(server_packet[1] == 0x85) // response websocket
		{
			if(server_packet[2] == 2)
			{
				if(server_packet[5] == 1)
				{
					websocket_success = 1;

					if(pwronFlag==1)	//4.1.5
					{
					pwronFlag=2;
						enQueue(initialisation_ocpp);
						enQueue(G1_StatusNotification_ocpp);
					}
					else if(pwronFlag==2)
					{
						ocpp_boot_status=1;
						enQueue(G1_StatusNotification_ocpp);
					}
					if(charger_status_G1.ocpp_status == Current_Demand)
					{
						enQueue(G1_StatusNotification_ocpp);
					}

					//charger_status_G1.ocpp_status = Not_Connect;
					//charger_status_G2.ocpp_status = Not_Connect;
					HMI_websocket_connect = 1; //hmi indication
					HMI_websocket_disconnect = 0;
					OCPP_State_ACType2 = 1;
//					AC001_OCPP_Charger_Status = 0;
				}
				else if(server_packet[5] == 0)
				{
					//charger_status_G1.ocpp_status = Not_Connect;
					//charger_status_G2.ocpp_status = Not_Connect;
					websocket_success = 0;
					HMI_websocket_disconnect = 1;
					WIFI_Setting = 1;
				}
			}
		}
		else if(server_packet[1] == 0x86) // wifi error
		{
			if(server_packet[2] == 2)
			{
				if(server_packet[5] == 1)
				{

				}
				else if(server_packet[5] == 0)
				{
					websocket_success = 0;
					HMI_wifi_disconnect = 1;
					wifi_status = 0;
					HMI_websocket_disconnect = 1;
					HMI_websocket_connect = 0;
					ocpp_boot_status = 0;
				}
			}
		}
		else if(server_packet[1] == 0x87)
		{

		}

		////////////////4G_PARAMETER//////////////////////////////////////
		 //imei,csq,lattitude,longitude,networkoperator,
		else if(server_packet[1] == 0x93)
		{
			int comma=0,Length=0,lclindex=0,lclrxoperrator[15];
			Length=server_packet[3];
			Length*=256;
			Length|=server_packet[4];

		   for(int index=0;index<Length;index++)
		   {
			   if(server_packet[index+5] == ',')
			   {
				   comma++;
				   lclindex=0;
			   }
			   else if(comma==0)
			   {
				   GSM.imeino[lclindex++]= server_packet[index+5];

				   //imei
			   }
			   else if(comma == 1)
			   {

				   GSM.csq[lclindex++]= server_packet[index+5];
				   if(atoi(GSM.csq) < 17)
				   {
					   enQueue(Status_weak_signal);
				   }
			   }
			   else if(comma == 2)
				{
				   lclrxoperrator[lclindex++]= server_packet[index+5];

						//latt
				}
			   else if(comma == 3)
			   {
				   GSM.lattitude[lclindex++]= server_packet[index+5];

			   }
			   else if(comma == 4)
			   {
				   GSM.longitude[lclindex++]= server_packet[index+5];
			   }
			   else if(comma == 5)
			   {
				   GSM.firmware[lclindex++]= server_packet[index+5];
			   }
			   else
			   {
				   //do nothing
			   }

			 }
		}
		else if(server_packet[1] == 0x95) // request OCPP uri (Internet connection)
		{
			 if(server_packet[2] == 1)
			{
				if(server_packet[5] == 0)
				{
					//unknown error
				}
				else if(server_packet[5] == 1)
				{
					//gsm no error
				}
				if(server_packet[5] == 2)
				{
					//network operator no found
				}
				if(server_packet[5] == 3)
				{
					//no network
				}
				if(server_packet[5] == 4)
				{
					//server not connected
				}
				if(server_packet[5] == 5)
				{
					//SIM not registered
				}
			}
		}
		//////////////////////////////////////////////////
			//ac001smart
		else if(server_packet[1] == 0x71) //
		{
			if(server_packet[5] == 1)
			{
				config_TXstruct=1;
			}
			else if(server_packet[5] == 2)
			{
					// to be decided
			}
		}
		else if(server_packet[1] == 0x73) //
		{
			if(server_packet[5] == 1)
			{

			}
			else if(server_packet[5] == 2)
			{
				config_TXstruct=1;// resend 0x72
			}
		}
		else if(server_packet[1] == 0x74) //
		{
			int comma=0,Length=0,lclindex=0,lclrxoperrator[15];
			Length=server_packet[3];
			Length*=256;
			Length|=server_packet[4];

//			if(Length>100)
//			{
			memcpy(&form_data,&server_packet[5],Length);
//			}
			config_RXstruct=1;
		}
	}
	inprocess = 0;
}

/**
 * @brief Process the received string from the server.
 *
 * @param None.
 * @return None.
 */
void process_incoming_string()
{
	int n = 0;
	int k = 0;
	int d = 0;
	int m;
	char tempbuf[20]={0},tempindex=0;
	static int ret;
	//char buff[500];/* Local variable */
	int *buff;
	buff = malloc(500 * sizeof(char));
  //  for(n=0;n<=20;n++)
    {
    	char *s;

	///////////4.x.7 changes///////////////////
		if(strcmp_1(Rec1[1],HeartBeat_Res) == 0)
		{
			char *j;
				WaitForResponse = false;

						j = strstr_1(Rec1[2], "currentTime");
						if (j != NULL)
						{
								process_time(Rec1[2]);
						}
						j= NULL;
		}
		else if(strcmp_1(Rec1[1],charger_status_G1.stop_transaction) == 0)
    			{
    				status =0;
					for(int i=2;i<=8;i++)
					{
						if(strstr_1(Rec1[i], "status"))
						{
							status = IDtagValidation(Rec1[i]);
							break;
						}
					}
    	    		if(status == 1)
    	    		{
    	    			charger_status_G1.ocpp_status = StopTransaction_Success;
    	    			charger_status_G1.timer = 0;
    	    		    //AC001_OCPP_Charger_Status = G_StatusNotification;

    	    		}
    	    		else
    				{/////V3.3.1/////////////////////////////////
    					//charger_status_G1.ocpp_status = StopTranscation_Fail;
    				}//////////////////////////////////////////////////

    	    		if(Ocpp_Setting.StopTxInvalidId == true)
    				{
    	    			charger_status_G1.ocpp_status = StopTransaction_Success;
    	    			charger_status_G1.timer = 0;
    				}
    	    		charger_status_G1.ocpp_status = StopTransaction_Success;
    			}
    	    	else if(strcmp_1(Rec1[1],charger_status_G1.Authorised) == 0)
    			{
    	    		status =0;
					for(int i=2;i<=8;i++)
					{
						if(strstr_1(Rec1[i], "status"))
						{
							status = IDtagValidation(Rec1[i]);
							break;
						}
					}
    	    		if(status == 1)
    	    		{
    	    			charger_status_G1.ocpp_status = Authorise_Success;
    	    			charger_status_G1.timer = 0;
    	    		}
    	    		else
    				{////////////////////////V3.3.1////////////////////////////
    					charger_status_G1.ocpp_status = Authorise_Fail;
    				}///////////////////////////////////////
    			}
    	else if(strcmp_1(Rec1[1],charger_status_G1.start_transaction) == 0)
		{
    		ret = -1;
    		for(int i=2;i<=12;i++)
			{
    			if(strstr_1(Rec1[i], "expiryDate"))
				{
					ret = ExpiryDate(Rec1[i]);
				}
				else if(strstr_1(Rec1[i], "status"))
				{
					status = IDtagValidation(Rec1[i]);
				}
				else if(strstr_1(Rec1[i], "transactionId"))
				{
					charger_status_G1.transaction_id = process_transId(Rec1[i]);
				}

			}
    		//status = IDtagValidation(Rec1);
    		if(status == 1)
    		{
    			if(ret != -1)
    			{
    				ret = Time_calculation(DC001_OCPP_timestamp1,ExpiryDifferanceTime);
    				if(ret == -1)
    				{
    					charger_status_G1.charge_by_automatic = 1;
    				}
    				else
    				{
    					if(ret < 15 ) //// V4.1.3
						{
							charger_status_G1.charge_by_automatic = 1;
						}
    					else
    					{
    						charger_status_G1.charge_by_time =  (unsigned int)ret+10;	//V5.0.0 - added 10minutes
    						charger_status_G1.charge_by_automatic =0;

    					}

    				}
    			}
    			else
    			{
    				charger_status_G1.charge_by_automatic = 1;
    			}
    			charger_status_G1.ocpp_status = StartTransaction_Success;
    			charger_status_G1.timer = 0;
    		}
    		else
    		{
    			charger_status_G1.ocpp_status = StartTransaction_Fail;
    		}
		}

    	else if(strcmp_1(Rec1[1],Statusnotification) == 0)
		{
    		//return 0;   //4.X.8
		}
    	else if(strcmp_1(Rec1[1],metervalue) == 0)
		{
    		//return 0;	//4.X.8
		}
    	else if(strcmp_1(Rec1[1],Bootnotification) == 0)
        	{

    //   		n=2;
    //    		return;
        		for(n=0;((Rec1[2][n] != '\0') && (Rec1[2][n] != '}'));n++)
        		{
        			Array1[0][n] = Rec1[2][n];
        		}
        		Array1[0][n] = '\0';

        		for(m=0;((Rec1[3][m] != '\0') && (Rec1[3][m] != '}'));m++)
    			{
    				Array1[1][m] = Rec1[3][m];
    			}
        		    Array1[1][m] = '\0';

    			for(k=0;((Rec1[4][k] != '\0') && (Rec1[4][k] != '}'));k++)
    			 {
    				Array1[2][k] = Rec1[4][k];
    			 }
    			 Array1[2][k] = '\0';

    				 BootNotification_res = 1;
    				// return;                   //4.X.8
        	}
        	else if( strstr_1(Rec1[2], "RemoteStartTransaction"))
        	{
        		uint8_t conn;
        		char *tagid;
        		strcpy(Msg_Id,Rec1[1]);
//        		memcpy(Msg_Id,Rec1[1],strlen_1(Rec1[1])); //
        		for(n=3;n<=6;n++)
    			{
    				s = strstr_1(Rec1[n], "connectorId");
    				if(s != NULL)
    				{
    					for(k=0;((Rec1[n][k] != '\0') && (Rec1[n][k] != '}'));k++)
    					{
    						Array1[0][k] = Rec1[n][k];
    					}
    					Array1[0][k] = '\0';
    				}
    			}

    			for(m=3;m<=7;m++)
    			{
    				s = strstr_1(Rec1[m], "idTag");
    				if(s != NULL)
    				{
    					for(k=0;((Rec1[m][k] != '\0') && (Rec1[m][k] != '}'));k++)
    					{
    						Array1[1][k] = Rec1[m][k];
    					}
    					Array1[1][k] = '\0';
    					break;
    				}
    			}
    			RemoteStarttx_res = 1;
    		//	return;       //4.X.8
        }
    	else if(strstr_1(Rec1[2], "RemoteStopTransaction"))
    	{
    		uint32_t tr_id,remote_stop=0;
    		strcpy(Msg_Id,Rec1[1]);
//    		memcpy(Msg_Id,Rec1[1],strlen_1(Rec1[1])); //
    		for(n=2;n<=20;n++)
    		{
				s = strstr_1(Rec1[n], "transactionId");
				if(s!=NULL)
				{
					tr_id = process_transId(Rec1[n]);
					if((tr_id == charger_status_G1.transaction_id) && (charger_status_G1.start == Started || charger_status_G1.charging_status == Charging_ChargerPoint))
					{
#if defined(ioncharge)
						AC_01 = false;
#endif
						charger_status_G1.start = Started;
						charger_status_G1.stop = Try_To_Stop;
						charger_status_G1.timer =0;
						remote_stop =1;
						charger_status_G1.charging_status = Finishing_ChargerPoint;
					}
					else
					{

						for(d=0; d<9 ;d++)
						{
							if(Cash_Memory.transaction_id[d] == tr_id )
							{
								remote_stop = 1;
								Cash_Memory.dummy = d;
								enQueue(Stop_Tx_On_Cach_Memory);
								break;
							}
						}
						if(d > 9)
						{
							remote_stop = 0;
						}
					}

					///////////////////////////////////////////////////////////////////
					memset((unsigned char*)fourGtxBuffer,0x00,sizeof(fourGtxBuffer));
					memset((unsigned char*)buff,0x00,sizeof(buff));

					fourgtxBufferIndex =0;
					fourGtxBuffer[fourgtxBufferIndex++]=0x02;//start byte //0
					fourGtxBuffer[fourgtxBufferIndex++]=0x94;//frame info firmware info //1
					fourGtxBuffer[fourgtxBufferIndex++]=0x01;//sub frame  //2
					fourGtxBuffer[fourgtxBufferIndex++]=0x01;//length high //3
					fourGtxBuffer[fourgtxBufferIndex++]=0x01;//length Low  //4

					if(remote_stop == 1)
					{
						stringlen=	sprintf(buff,"[3,%s,{\"status\":\"Accepted\"}]",Msg_Id); //Fill data in buffer
//						HAL_UART_Transmit_DMA(&huart2, (uint8_t*)buff, strlen(buff));
					}
					else
					{
						stringlen=	sprintf(buff,"[3,%s,{\"status\":\"Rejected\"}]",Msg_Id); //Fill data in buffer
//						HAL_UART_Transmit_DMA(&huart2, (uint8_t*)buff, strlen(buff));
					}
					memcpy(&fourGtxBuffer[fourgtxBufferIndex],buff,stringlen); //6 &7

				fourgtxBufferIndex+=stringlen;

				fourGtxBuffer[fourgtxBufferIndex++]=0x03;//end byte //8

				fourGtxBuffer[3]=((fourgtxBufferIndex-6)/256);  //3
				fourGtxBuffer[4]= (fourgtxBufferIndex-6) % 256;   //4
				HAL_UART_Transmit(&huart2, (uint8_t*)fourGtxBuffer,fourgtxBufferIndex,0xffff);
			//////////////////////////////////////////////////////////////////
					remote_stop  = 0;
					break;
				}
					//remote_stop = 1;
			}
    	}
    	else if(strstr_1(Rec1[2], "ChangeConfiguration"))
    	{
    		strcpy(Msg_Id,Rec1[1]);
    		//memcpy(Msg_Id,Rec1[1],strlen_1(Rec1[1])); //

    		///////////////////////////////////////////////////////////////////
			memset((unsigned char*)fourGtxBuffer,0x00,sizeof(fourGtxBuffer));
			memset((unsigned char*)buff,0x00,sizeof(buff));

			fourgtxBufferIndex =0;
			fourGtxBuffer[fourgtxBufferIndex++]=0x02;//start byte //0
			fourGtxBuffer[fourgtxBufferIndex++]=0x94;//frame info firmware info //1
			fourGtxBuffer[fourgtxBufferIndex++]=0x01;//sub frame  //2
			fourGtxBuffer[fourgtxBufferIndex++]=0x01;//length high //3
			fourGtxBuffer[fourgtxBufferIndex++]=0x01;//length Low  //4

			if(strstr_1(Rec1[3],"{\"key\":\"HeartbeatInterval\""))  //{"key":["AuthorizationRequired"]}
			{
				s = strstr_1(Rec1[4], "value");
				if(s!=NULL)
				{
					Ocpp_Setting.HeartbeatIntvl = (unsigned int)process_Value(Rec1[4]);
					Store_Key_Parameter =1;
				}

				stringlen=	sprintf(buff,"[3,%s,{\"status\":\"Accepted\"}]",Msg_Id); //Fill data in buffer
//				HAL_UART_Transmit_DMA(&huart2, (uint8_t*)buff, strlen(buff));
			}
			else if(strstr_1(Rec1[3],"{\"key\":\"MeterValueSampleInterval\""))  //{"key":["AuthorizationRequired"]}
			{
				s = strstr_1(Rec1[4], "value");
				if(s!=NULL)
				{
					Ocpp_Setting.MeterIntvl = (unsigned int)process_Value(Rec1[4]);
					Store_Key_Parameter =1;
				}
				stringlen=	sprintf(buff,"[3,%s,{\"status\":\"Accepted\"}]",Msg_Id); //Fill data in buffer
//				HAL_UART_Transmit_DMA(&huart2, (uint8_t*)buff, strlen(buff));
			}
			else if(strstr_1(Rec1[3],"{\"key\":\"MinimumStatusDuration\""))
			{
				s = strstr_1(Rec1[4], "value");
				if(s!=NULL)
				{
					Ocpp_Setting.StatusDuration = (unsigned int)process_Value(Rec1[4]);
					Store_Key_Parameter =1;
				}
				stringlen=	sprintf(buff,"[3,%s,{\"status\":\"Accepted\"}]",Msg_Id); //Fill data in buffer
//				HAL_UART_Transmit_DMA(&huart2, (uint8_t*)buff, strlen(buff));
			}
			else if(strstr_1(Rec1[3],"{\"key\":\"CpCount\""))
			{
				s = strstr_1(Rec1[4], "value");
				if(s!=NULL)
				{
					Ocpp_Setting.count = (unsigned char)process_Value(Rec1[4]);
					Store_Key_Parameter =1;
				}
				stringlen=	sprintf(buff,"[3,%s,{\"status\":\"Accepted\"}]",Msg_Id); //Fill data in buffer
//				HAL_UART_Transmit_DMA(&huart2, (uint8_t*)buff, strlen(buff));
			}
			else if(strstr_1(Rec1[3],"{\"key\":\"CpOffset\""))
			{
				s = strstr_1(Rec1[4], "value");
				if(s!=NULL)
				{
					Ocpp_Setting.offset = (unsigned char)process_Value(Rec1[4]);
					Store_Key_Parameter =1;
				}
				stringlen=	sprintf(buff,"[3,%s,{\"status\":\"Accepted\"}]",Msg_Id); //Fill data in buffer
//				HAL_UART_Transmit_DMA(&huart2, (uint8_t*)buff, strlen(buff));
			}
//------------------------------------------------------------------------------------------
			else if(strstr_1(Rec1[3],"{\"key\":\"CpStateA\""))
			{
				s = strstr_1(Rec1[4], "value");
				if(s!=NULL)
				{
					OCPP.STATE_A_LEVEL = (unsigned int)process_Value(Rec1[4]);
					write_para =1;
				}
				stringlen=	sprintf(buff,"[3,%s,{\"status\":\"Accepted\"}]",Msg_Id); //Fill data in buffer
			}
			else if(strstr_1(Rec1[3],"{\"key\":\"CpStateB\""))
			{
				s = strstr_1(Rec1[4], "value");
				if(s!=NULL)
				{
					OCPP.STATE_B_LEVEL = (unsigned int)process_Value(Rec1[4]);
					write_para =1;
				}
				stringlen=	sprintf(buff,"[3,%s,{\"status\":\"Accepted\"}]",Msg_Id); //Fill data in buffer
			}
			else if(strstr_1(Rec1[3],"{\"key\":\"CpStateC\""))
			{
				s = strstr_1(Rec1[4], "value");
				if(s!=NULL)
				{
					OCPP.STATE_C_LEVEL = (unsigned int)process_Value(Rec1[4]);

					write_para =1;
				}
				stringlen=	sprintf(buff,"[3,%s,{\"status\":\"Accepted\"}]",Msg_Id); //Fill data in buffer
			}
#if(multipyfact)
			else if(strstr_1(Rec1[3],"{\"key\":\"multiplyfactor\""))
			{
				s = strstr_1(Rec1[4], "value");
				if(s!=NULL)
				{
					OCPP.auxinput = (unsigned int)process_Value(Rec1[4]);
					meter1whclear = meter2whclear = meter3whclear=1;
					write_para =1;
				}
				stringlen=	sprintf(buff,"[3,%s,{\"status\":\"Accepted\"}]",Msg_Id); //Fill data in buffer
			}
#endif
//--------------------------------------------------------------------------------
			else if(strstr_1(Rec1[3],"{\"key\":\"ResetRetries\""))
			{
				s = strstr_1(Rec1[4], "value");
				if(s!=NULL)
				{
					Ocpp_Setting.ResetRetry = (unsigned int)process_Value(Rec1[4]);
					Store_Key_Parameter =1;
				}

				stringlen=	sprintf(buff,"[3,%s,{\"status\":\"Accepted\"}]",Msg_Id); //Fill data in buffer
//				HAL_UART_Transmit_DMA(&huart2, (uint8_t*)buff, strlen(buff));
			}
			else if(strstr_1(Rec1[3],"{\"key\":\"TransactionMessageRetryInterval\""))
			{
				s = strstr_1(Rec1[4], "value");
				if(s!=NULL)
				{
					Ocpp_Setting.FailedTx_Intvl = (unsigned int)process_Value(Rec1[4]);
					Store_Key_Parameter =1;
				}


				stringlen=	sprintf(buff,"[3,%s,{\"status\":\"Accepted\"}]",Msg_Id); //Fill data in buffer
//				HAL_UART_Transmit_DMA(&huart2, (uint8_t*)buff, strlen(buff));
			}
			else if(strstr_1(Rec1[3],"{\"key\":\"ClockAlignedDataInterval\""))
			{
				s = strstr_1(Rec1[4], "value");
				if(s!=NULL)
				{
					Ocpp_Setting.ClkAlgnIntvl = (unsigned int)process_Value(Rec1[4]);
					Store_Key_Parameter =1;
				}


				stringlen=	sprintf(buff,"[3,%s,{\"status\":\"Accepted\"}]",Msg_Id); //Fill data in buffer
//				HAL_UART_Transmit_DMA(&huart2, (uint8_t*)buff, strlen(buff));
			}
			else if(strstr_1(Rec1[3],"{\"key\":\"TransactionMessageAttempts\""))
			{
				s = strstr_1(Rec1[4], "value");
				if(s!=NULL)
				{
					Ocpp_Setting.FailedAttempt = (unsigned int)process_Value(Rec1[4]);
					Store_Key_Parameter =1;
				}


				stringlen=	sprintf(buff,"[3,%s,{\"status\":\"Accepted\"}]",Msg_Id); //Fill data in buffer
//				HAL_UART_Transmit_DMA(&huart2, (uint8_t*)buff, strlen(buff));
			}
			else if(strstr_1(Rec1[3],"{\"key\":\"StopTransactionOnInvalidId\""))
			{
				s = strstr_1(Rec1[4], "value");
				if(s!=NULL)
				{
					s = strstr_1(Rec1[4], "true");
					if(s!=NULL)
					{
						Ocpp_Setting.StopTxInvalidId = 1;
					}
					else
					{
						s = strstr_1(Rec1[4], "false");
						if(s!=NULL)
						{
							Ocpp_Setting.StopTxInvalidId = 0;
						}

					}
					Store_Key_Parameter =1;
				}

				stringlen=	sprintf(buff,"[3,%s,{\"status\":\"Accepted\"}]",Msg_Id); //Fill data in buffer
//				HAL_UART_Transmit_DMA(&huart2, (uint8_t*)buff, strlen(buff));
			}
			else if(strstr_1(Rec1[3],"{\"key\":\"LocalPreAuthorize\""))
			{
				s = strstr_1(Rec1[4], "value");
				if(s!=NULL)
				{
					s = strstr_1(Rec1[4], "true");
					if(s!=NULL)
					{
						Ocpp_Setting.LocalPreAuth = 1;
					}
					else
					{
						s = strstr_1(Rec1[4], "false");
						if(s!=NULL)
						{
							Ocpp_Setting.LocalPreAuth = 0;
						}
					}
					Store_Key_Parameter =1;
				}

				stringlen=	sprintf(buff,"[3,%s,{\"status\":\"Accepted\"}]",Msg_Id); //Fill data in buffer
//				HAL_UART_Transmit_DMA(&huart2, (uint8_t*)buff, strlen(buff));
			}
			else if(strstr_1(Rec1[3],"{\"key\":\"LocalAuthorizeOffline\""))
			{
				s = strstr_1(Rec1[4], "value");
				if(s!=NULL)
				{
					s = strstr_1(Rec1[4], "true");
					if(s!=NULL)
					{
						Ocpp_Setting.LocalAuthOffln = 1;
					}
					else
					{
						s = strstr_1(Rec1[4], "false");
						if(s!=NULL)
						{
							Ocpp_Setting.LocalAuthOffln = 0;
						}
					}
					Store_Key_Parameter =1;
				}

				stringlen=	sprintf(buff,"[3,%s,{\"status\":\"Accepted\"}]",Msg_Id); //Fill data in buffer
//				HAL_UART_Transmit_DMA(&huart2, (uint8_t*)buff, strlen(buff));
			}
			else if(strstr_1(Rec1[3],"{\"key\":\"AuthorizeRemoteTxRequests\""))
			{
				s = strstr_1(Rec1[4], "value");
				if(s!=NULL)
				{
					s = strstr_1(Rec1[4], "true");
					if(s!=NULL)
					{
						Ocpp_Setting.AuthRemotTx = 1;
					}
					else
					{
						s = strstr_1(Rec1[4], "false");
						if(s!=NULL)
						{
							Ocpp_Setting.AuthRemotTx = 0;
						}
					}
					Store_Key_Parameter =1;
				}

				stringlen=	sprintf(buff,"[3,%s,{\"status\":\"Accepted\"}]",Msg_Id); //Fill data in buffer
//				HAL_UART_Transmit_DMA(&huart2, (uint8_t*)buff, strlen(buff));
			}
			else if(strstr_1(Rec1[3],"{\"key\":\"AuthorizationCacheEnabled\""))
			{
				s = strstr_1(Rec1[4], "value");
				if(s!=NULL)
				{
					s = strstr_1(Rec1[4], "true");
					if(s!=NULL)
					{
						Ocpp_Setting.AuthCachEnable = 1;
					}
					else
					{
						s = strstr_1(Rec1[4], "false");
						if(s!=NULL)
						{
							Ocpp_Setting.AuthCachEnable = 0;
						}
					}
					Store_Key_Parameter =1;
				}

				stringlen=	sprintf(buff,"[3,%s,{\"status\":\"Accepted\"}]",Msg_Id); //Fill data in buffer
//				HAL_UART_Transmit_DMA(&huart2, (uint8_t*)buff, strlen(buff));
			}
			//else if(strstr_1(Rec1[3],"{\"key\":\"AllowOfflineTxForUnknownId\""))
			else if(strstr_1(Rec1[3],"{\"key\":\"GroundFaultDetection\""))
			{
				s = strstr_1(Rec1[4], "value");
				if(s!=NULL)
				{
					s = strstr_1(Rec1[4], "true");
					if(s!=NULL)
					{
						// Ocpp_Setting.AllowOfflineTXUnknownId = 1;
						Ocpp_Setting.GroundFaultDetection = 1;
					}
					else
					{
						s = strstr_1(Rec1[4], "false");
						if(s!=NULL)
						{
							// Ocpp_Setting.AllowOfflineTXUnknownId = 0;
							Ocpp_Setting.GroundFaultDetection = 0;
						}
					}
					Store_Key_Parameter =1;
				}

				stringlen=	sprintf(buff,"[3,%s,{\"status\":\"Accepted\"}]",Msg_Id); //Fill data in buffer
//				HAL_UART_Transmit_DMA(&huart2, (uint8_t*)buff, strlen(buff));
			}
			else
			{
				stringlen=	sprintf(buff,"[3,%s,{\"status\":\"NotSupported\"}]",Msg_Id);
			}


			memcpy(&fourGtxBuffer[fourgtxBufferIndex],buff,stringlen); //6 &7

			fourgtxBufferIndex+=stringlen;

			fourGtxBuffer[fourgtxBufferIndex++]=0x03;//end byte //8

			fourGtxBuffer[3]=((fourgtxBufferIndex-6)/256);  //3
			fourGtxBuffer[4]= (fourgtxBufferIndex-6) % 256;   //4

			HAL_UART_Transmit_DMA(&huart2, (uint8_t*)fourGtxBuffer,fourgtxBufferIndex);

			//////////////////////////////////////////////////////////////////
    	}
    	else if(strstr_1(Rec1[2], "GetConfiguration"))
    	{
    		memset((unsigned char*)buff,0x00,sizeof(buff));
    		strcpy(Msg_Id,Rec1[1]);
//    		memcpy(Msg_Id,Rec1[1],strlen_1(Rec1[1])); //

			if (((strcmp_1(Rec1[3], "{\"key\":[]}")) == 0) || ((strcmp_1(Rec1[3], "{\"key\":\"ChargePointVendor\"}")) == 0))
				{
					getconfig_response(Msg_Id,Ocpp_Setting.HeartbeatIntvl);

					 free(buff);
					 buff = NULL;
					 return; //4.X.8
				}
				else if(strstr_1(Rec1[3],"{\"key\":[\"NumberOfConnectors\"]}"))  //{"key":["AuthorizationRequired"]}
				{
#if gunno == three
					stringlen = sprintf(buff,"[3,%s,{\"configurationKey\":[{\"key\":\"NumberOfConnectors\",\"readonly\":true,\"value\":\"3\"}],\"unknownKey\":[\"\"]}]",Msg_Id);
#else
					stringlen = sprintf(buff,"[3,%s,{\"configurationKey\":[{\"key\":\"NumberOfConnectors\",\"readonly\":true,\"value\":\"1\"}],\"unknownKey\":[\"\"]}]",Msg_Id);
#endif
					//			HAL_UART_Transmit_DMA(&huart2, (uint8_t*)buff, strlen(buff));
				}
				else if(strstr_1(Rec1[3],"{\"key\":[\"MeterValueSampleInterval\"]}"))
				{
					stringlen = sprintf(buff,"[3,%s,{\"configurationKey\":[{\"key\":\"MeterValueSampleInterval\",\"readonly\":false,\"value\":\"%d\"}],\"unknownKey\":[\"\"]}]",Msg_Id,Ocpp_Setting.MeterIntvl);
			//		HAL_UART_Transmit_DMA(&huart2, (uint8_t*)buff, strlen(buff));
				}
				else if(strstr_1(Rec1[3],"{\"key\":[\"HeartbeatInterval\"]}")) ////{"key":["AuthorizationRequired"]}
				{
					stringlen = sprintf(buff,"[3,%s,{\"configurationKey\":[{\"key\":\"HeartbeatInterval\",\"readonly\":false,\"value\":\"%d\"}],\"unknownKey\":[\"\"]}]",Msg_Id,Ocpp_Setting.HeartbeatIntvl);
				//	HAL_UART_Transmit_DMA(&huart2, (uint8_t*)buff, strlen(buff));
				}
				else if(strstr_1(Rec1[3],"{\"key\":[\"MeterValuesSampledDataMaxLength\"]}"))
				{
					stringlen = sprintf(buff,"[3,%s,{\"configurationKey\":[{\"key\":\"MeterValuesSampledDataMaxLength\",\"readonly\":false,\"value\":\"4\"}],\"unknownKey\":[\"\"]}]",Msg_Id);
				//	HAL_UART_Transmit_DMA(&huart2, (uint8_t*)buff, strlen(buff));
				}
				else if(strstr_1(Rec1[3],"{\"key\":[\"MinimumStatusDuration\"]}"))
				{
					stringlen = sprintf(buff,"[3,%s,{\"configurationKey\":[{\"key\":\"MinimumStatusDuration\",\"readonly\":false,\"value\":\"%d\"}],\"unknownKey\":[\"\"]}]",Msg_Id,Ocpp_Setting.StatusDuration);
				//	HAL_UART_Transmit_DMA(&huart2, (uint8_t*)buff, strlen(buff));
				}
				else if(strstr_1(Rec1[3],"{\"key\":[\"ResetRetries\"]}"))
				{
					stringlen = sprintf(buff,"[3,%s,{\"configurationKey\":[{\"key\":\"ResetRetries\",\"readonly\":false,\"value\":\"%d\"}],\"unknownKey\":[\"\"]}]",Msg_Id,Ocpp_Setting.ResetRetry);
					//HAL_UART_Transmit_DMA(&huart2, (uint8_t*)buff, strlen(buff));
				}
				else if(strstr_1(Rec1[3],"{\"key\":[\"AuthorizationCacheEnabled\"]}"))
				{
					stringlen = sprintf(buff,"[3,%s,{\"configurationKey\":[{\"key\":\"AuthorizationCacheEnabled\",\"readonly\":false,\"value\":\"False\"}],\"unknownKey\":[\"\"]}]",Msg_Id);
					//HAL_UART_Transmit_DMA(&huart2, (uint8_t*)buff, strlen(buff));
				}
				else if(strstr_1(Rec1[3],"{\"key\":[\"LocalPreAuthorize\"]}"))
				{
					stringlen = sprintf(buff,"[3,%s,{\"configurationKey\":[{\"key\":\"LocalPreAuthorize\",\"readonly\":true,\"value\":\"%s\"}],\"unknownKey\":[\"\"]}]",Msg_Id,Ocpp_Setting.LocalPreAuth == 1 ? "true" : "false");
					// HAL_UART_Transmit_DMA(&huart2, (uint8_t*)buff, strlen(buff));
				}
				else if(strstr_1(Rec1[3],"{\"key\":[\"ReserveConnectorZeroSupported\"]}"))
				{
					stringlen = sprintf(buff,"[3,%s,{\"configurationKey\":[{\"key\":\"ReserveConnectorZeroSupported\",\"readonly\":true,\"value\":\"False\"}],\"unknownKey\":[\"\"]}]",Msg_Id);
				//	HAL_UART_Transmit_DMA(&huart2, (uint8_t*)buff, strlen(buff));
				}
				else if(strstr_1(Rec1[3],"{\"key\":[\"SendLocalListMaxLength\"]}"))
				{
					stringlen = sprintf(buff,"[3,%s,{\"configurationKey\":[{\"key\":\"SendLocalListMaxLength\",\"readonly\":true,\"value\":\"10\"}],\"unknownKey\":[\"\"]}]",Msg_Id);
				//	HAL_UART_Transmit_DMA(&huart2, (uint8_t*)buff, strlen(buff));
				}
				else if(strstr_1(Rec1[3],"{\"key\":[\"LocalAuthListMaxLength\"]}"))
				{
					stringlen = sprintf(buff,"[3,%s,{\"configurationKey\":[{\"key\":\"LocalAuthListMaxLength\",\"readonly\":true,\"value\":\"100\"}],\"unknownKey\":[\"\"]}]",Msg_Id);
				//	HAL_UART_Transmit_DMA(&huart2, (uint8_t*)buff, strlen(buff));
				}
				else if(strstr_1(Rec1[3],"{\"key\":[\"LocalAuthListEnabled\"]}"))
				{
					stringlen = sprintf(buff,"[3,%s,{\"configurationKey\":[{\"key\":\"LocalAuthListEnabled\",\"readonly\":false,\"value\":\"false\"}],\"unknownKey\":[\"\"]}]",Msg_Id);
				//	HAL_UART_Transmit_DMA(&huart2, (uint8_t*)buff, strlen(buff));
				}
				else if(strstr_1(Rec1[3],"{\"key\":[\"WebSocketPingInterval\"]}"))
				{
					stringlen = sprintf(buff,"[3,%s,{\"configurationKey\":[{\"key\":\"WebSocketPingInterval\",\"readonly\":true,\"value\":\"300\"}],\"unknownKey\":[\"\"]}]",Msg_Id);
				//	HAL_UART_Transmit_DMA(&huart2, (uint8_t*)buff, strlen(buff));
				}
				else if(strstr_1(Rec1[3],"{\"key\":[\"TransactionMessageRetryInterval\"]}"))
				{
					stringlen = sprintf(buff,"[3,%s,{\"configurationKey\":[{\"key\":\"TransactionMessageRetryInterval\",\"readonly\":false,\"value\":\"%d\"}],\"unknownKey\":[\"\"]}]",Msg_Id, Ocpp_Setting.FailedTx_Intvl);
				//	HAL_UART_Transmit_DMA(&huart2, (uint8_t*)buff, strlen(buff));
				}
				else if(strstr_1(Rec1[3],"{\"key\":[\"TransactionMessageAttempts\"]}"))
				{
					stringlen = sprintf(buff,"[3,%s,{\"configurationKey\":[{\"key\":\"TransactionMessageAttempts\",\"readonly\":false,\"value\":\"%d\"}],\"unknownKey\":[\"\"]}]",Msg_Id,Ocpp_Setting.FailedAttempt);
					//HAL_UART_Transmit_DMA(&huart2, (uint8_t*)buff, strlen(buff));
				}
				else if(strstr_1(Rec1[3],"{\"key\":[\"StopTxnSampledDataMaxLength\"]}"))
				{
					stringlen = sprintf(buff,"[3,%s,{\"configurationKey\":[{\"key\":\"StopTxnSampledDataMaxLength\",\"readonly\":true,\"value\":\"1\"}],\"unknownKey\":[\"\"]}]",Msg_Id);
				//	HAL_UART_Transmit_DMA(&huart2, (uint8_t*)buff, strlen(buff));
				}
				else if(strstr_1(Rec1[3],"{\"key\":[\"StopTxnSampledData\"]}"))
				{
					stringlen = sprintf(buff,"[3,%s,{\"configurationKey\":[{\"key\":\"StopTxnSampledData\",\"readonly\":true,\"value\":\"Energy.Active.Import.Register\"}],\"unknownKey\":[\"\"]}]",Msg_Id);
			//		HAL_UART_Transmit_DMA(&huart2, (uint8_t*)buff, strlen(buff));
				}
				else if(strstr_1(Rec1[3],"{\"key\":[\"StopTxnAlignedDataMaxLength\"]}"))
				{
					stringlen = sprintf(buff,"[3,%s,{\"configurationKey\":[{\"key\":\"StopTxnAlignedDataMaxLength\",\"readonly\":true,\"value\":\"1\"}],\"unknownKey\":[\"\"]}]",Msg_Id);
				//	HAL_UART_Transmit_DMA(&huart2, (uint8_t*)buff, strlen(buff));
				}
				else if(strstr_1(Rec1[3],"{\"key\":[\"StopTxnAlignedData\"]}"))
				{
					stringlen = sprintf(buff,"[3,%s,{\"configurationKey\":[{\"key\":\"StopTxnAlignedDataMaxLength\",\"readonly\":true,\"value\":\"Energy.Active.Import.Register\"}],\"unknownKey\":[\"\"]}]",Msg_Id);
				//	HAL_UART_Transmit_DMA(&huart2, (uint8_t*)buff, strlen(buff));
				}
				else if(strstr_1(Rec1[3],"{\"key\":[\"StopTransactionOnInvalidId\"]}"))
				{
					stringlen = sprintf(buff,"[3,%s,{\"configurationKey\":[{\"key\":\"StopTransactionOnInvalidId\",\"readonly\":false,\"value\":\"%s\"}],\"unknownKey\":[\"\"]}]",Msg_Id,Ocpp_Setting.StopTxInvalidId == 1 ? "true" : "false");
				//	HAL_UART_Transmit_DMA(&huart2, (uint8_t*)buff, strlen(buff));
				}
				else if(strstr_1(Rec1[3],"{\"key\":[\"StopTransactionOnEVSideDisconnect\"]}"))
				{
					stringlen = sprintf(buff,"[3,%s,{\"configurationKey\":[{\"key\":\"StopTransactionOnEVSideDisconnect\",\"readonly\":false,\"value\":\"true\"}],\"unknownKey\":[\"\"]}]",Msg_Id);
				//	HAL_UART_Transmit_DMA(&huart2, (uint8_t*)buff, strlen(buff));
				}
				else if(strstr_1(Rec1[3],"{\"key\":[\"MeterValuesSampledData\"]}"))
				{
					stringlen = sprintf(buff,"[3,%s,{\"configurationKey\":[{\"key\":\"MeterValuesSampledData\",\"readonly\":false,\"value\": \"Current.Import\",\"Power.Active.Import\",\"Voltage\",\"Energy.Active.Import.Register\"}],\"unknownKey\":[\"\"]}]",Msg_Id);
				//	HAL_UART_Transmit_DMA(&huart2, (uint8_t*)buff, strlen(buff));
				}
				else if(strstr_1(Rec1[3],"{\"key\":[\"MeterValuesAlignedDataMaxLength\"]}"))
				{
					stringlen = sprintf(buff,"[3,%s,{\"configurationKey\":[{\"key\":\"MeterValuesAlignedDataMaxLength\",\"readonly\":false,\"value\":\"4\"}],\"unknownKey\":[\"\"]}]",Msg_Id);
				//	HAL_UART_Transmit_DMA(&huart2, (uint8_t*)buff, strlen(buff));
				}
				else if(strstr_1(Rec1[3],"{\"key\":[\"MeterValuesAlignedData\"]}"))
				{
					stringlen = sprintf(buff,"[3,%s,{\"configurationKey\":[{\"key\":\"MeterValuesAlignedData\",\"readonly\":false,\"value\": \"Current.Import\",\"Power.Active.Import\",\"Voltage\",\"Energy.Active.Import.Register\"}],\"unknownKey\":[\"\"]}]",Msg_Id);
				//	HAL_UART_Transmit_DMA(&huart2, (uint8_t*)buff, strlen(buff));
				}
				else if(strstr_1(Rec1[3],"{\"key\":[\"MaxEnergyOnInvalidId\"]}"))
				{
					stringlen = sprintf(buff,"[3,%s,{\"configurationKey\":[{\"key\":\"MaxEnergyOnInvalidId\",\"readonly\":false,\"value\":\"0\"}],\"unknownKey\":[\"\"]}]",Msg_Id);
					//HAL_UART_Transmit_DMA(&huart2, (uint8_t*)buff, strlen(buff));
				}
				else if(strstr_1(Rec1[3],"{\"key\":[\"LocalAuthorizeOffline\"]}"))
				{
					if(Ocpp_Setting.LocalAuthOffln == 1)
					{
						stringlen = sprintf(buff,"[3,%s,{\"configurationKey\":[{\"key\":\"LocalAuthorizeOffline\",\"readonly\":false,\"value\":\"true\"}],\"unknownKey\":[\"\"]}]",Msg_Id);
					}
					else
					{
						stringlen = sprintf(buff,"[3,%s,{\"configurationKey\":[{\"key\":\"LocalAuthorizeOffline\",\"readonly\":false,\"value\":\"false\"}],\"unknownKey\":[\"\"]}]",Msg_Id);
					}
				//	HAL_UART_Transmit_DMA(&huart2, (uint8_t*)buff, strlen(buff));
				}
				else if(strstr_1(Rec1[3],"{\"key\":[\"ConnectionTimeOut\"]}"))
				{
					stringlen = sprintf(buff,"[3,%s,{\"configurationKey\":[{\"key\":\"ConnectionTimeOut\",\"readonly\":true,\"value\":\"0\"}],\"unknownKey\":[\"\"]}]",Msg_Id);
				//	HAL_UART_Transmit_DMA(&huart2, (uint8_t*)buff, strlen(buff));
				} //-----------------------------
				else if(strstr_1(Rec1[3],"{\"key\":[\"CpCount\"]}"))
				{
					stringlen = sprintf(buff,"[3,%s,{\"configurationKey\":[{\"key\":\"CpCount\",\"readonly\":false,\"value\":\"%d\"}],\"unknownKey\":[\"\"]}]",Msg_Id,Ocpp_Setting.count);
			//		HAL_UART_Transmit_DMA(&huart2, (uint8_t*)buff, strlen(buff));
				}
    		//-----------------------------------------------------//
				else if(strstr_1(Rec1[3],"{\"key\":[\"CpOffset\"]}"))
				{
					stringlen = sprintf(buff,"[3,%s,{\"configurationKey\":[{\"key\":\"CpOffset\",\"readonly\":false,\"value\":\"%d\"}],\"unknownKey\":[\"\"]}]",Msg_Id,Ocpp_Setting.offset);
			//		HAL_UART_Transmit_DMA(&huart2, (uint8_t*)buff, strlen(buff));
				}
    		//------------------------------------------------------------//
				else if(strstr_1(Rec1[3],"{\"key\":[\"CpStateA\"]}"))
				{
					stringlen = sprintf(buff,"[3,%s,{\"configurationKey\":[{\"key\":\"CpStateA\",\"readonly\":false,\"value\":\"%d\"}],\"unknownKey\":[\"\"]}]",Msg_Id,OCPP.STATE_A_LEVEL);
			//		HAL_UART_Transmit_DMA(&huart2, (uint8_t*)buff, strlen(buff));
				}
    		//--------------------------------------------------------------------------------
				else if(strstr_1(Rec1[3],"{\"key\":[\"CpStateB\"]}"))
				{
					stringlen = sprintf(buff,"[3,%s,{\"configurationKey\":[{\"key\":\"CpStateB\",\"readonly\":false,\"value\":\"%d\"}],\"unknownKey\":[\"\"]}]",Msg_Id,OCPP.STATE_B_LEVEL);
			//		HAL_UART_Transmit_DMA(&huart2, (uint8_t*)buff, strlen(buff));
				}
    		//--------------------------------------------------------------------------
				else if(strstr_1(Rec1[3],"{\"key\":[\"CpStateC\"]}"))
				{
					stringlen = sprintf(buff,"[3,%s,{\"configurationKey\":[{\"key\":\"CpStateC\",\"readonly\":false,\"value\":\"%d\"}],\"unknownKey\":[\"\"]}]",Msg_Id,OCPP.STATE_C_LEVEL);
			//		HAL_UART_Transmit_DMA(&huart2, (uint8_t*)buff, strlen(buff));
				}
#if(multipyfact)
				else if(strstr_1(Rec1[3],"{\"key\":[\"multiplyfactor\"]}"))
				{
					stringlen = sprintf(buff,"[3,%s,{\"configurationKey\":[{\"key\":\"multiplyfactor\",\"readonly\":false,\"value\":\"%d\"}],\"unknownKey\":[\"\"]}]",Msg_Id,OCPP.auxinput);
			//		HAL_UART_Transmit_DMA(&huart2, (uint8_t*)buff, strlen(buff));
				}
#endif
    		//-----------------------------------------------------------------------
				else if(strstr_1(Rec1[3],"{\"key\":[\"ClockAlignedDataInterval\"]}"))
				{
					stringlen = sprintf(buff,"[3,%s,{\"configurationKey\":[{\"key\":\"ClockAlignedDataInterval\",\"readonly\":false,\"value\":\"%d\"}],\"unknownKey\":[\"\"]}]",Msg_Id,Ocpp_Setting.ClkAlgnIntvl);
			//		HAL_UART_Transmit_DMA(&huart2, (uint8_t*)buff, strlen(buff));
				}
				else if(strstr_1(Rec1[3],"{\"key\":[\"AuthorizeRemoteTxRequests\"]}"))
				{
					if(Ocpp_Setting.AuthRemotTx == 1)
					{
						stringlen = sprintf(buff,"[3,%s,{\"configurationKey\":[{\"key\":\"AuthorizeRemoteTxRequests\",\"readonly\":false,\"value\":\"true\"}],\"unknownKey\":[\"\"]}]",Msg_Id);
					}
					else
					{
						stringlen = sprintf(buff,"[3,%s,{\"configurationKey\":[{\"key\":\"AuthorizeRemoteTxRequests\",\"readonly\":false,\"value\":\"false\"}],\"unknownKey\":[\"\"]}]",Msg_Id);
					}
				//	HAL_UART_Transmit_DMA(&huart2, (uint8_t*)buff, strlen(buff));
				}
				// else if(strstr_1(Rec1[3],"{\"key\":[\"AllowOfflineTxForUnknownId\"]}"))
				else if(strstr_1(Rec1[3],"{\"key\":[\"GroundFaultDetection\"]}"))
				{
					// if(Ocpp_Setting.AllowOfflineTXUnknownId == 1)
					if(Ocpp_Setting.GroundFaultDetection == 1)
					{
						// stringlen = sprintf(buff,"[3,%s,{\"configurationKey\":[{\"key\":\"AllowOfflineTxForUnknownId\",\"readonly\":false,\"value\":\"true\"}],\"unknownKey\":[\"\"]}]",Msg_Id);
						stringlen = sprintf(buff,"[3,%s,{\"configurationKey\":[{\"key\":\"GroundFaultDetection\",\"readonly\":false,\"value\":\"true\"}],\"unknownKey\":[\"\"]}]",Msg_Id);
					}
					else
					{
						// stringlen = sprintf(buff,"[3,%s,{\"configurationKey\":[{\"key\":\"AllowOfflineTxForUnknownId\",\"readonly\":false,\"value\":\"false\"}],\"unknownKey\":[\"\"]}]",Msg_Id);
						stringlen = sprintf(buff,"[3,%s,{\"configurationKey\":[{\"key\":\"GroundFaultDetection\",\"readonly\":false,\"value\":\"false\"}],\"unknownKey\":[\"\"]}]",Msg_Id);
					}
				//	HAL_UART_Transmit_DMA(&huart2, (uint8_t*)buff, strlen(buff));
				}
				else
				{
					if(strstr_1(Rec1[3],"{\"key\":[\""))
					{
						if(Rec1[13] == "\"")
						{
							for(;Rec1[13+tempindex] != "\"";tempindex++ )
							{
								tempbuf[tempindex] =Rec1[13+tempindex];
							}
						}
					}

					stringlen= sprintf(buff,"[3,%s,{\"configurationKey\":[{\"key\":\"%s\",\"readonly\":false,\"value\":\"NotSupported\"}],\"unknownKey\":[\"\"]}]",Msg_Id,tempbuf);
					//reset_response(Msg_Id,"NotSupported"); // V3.3.1
				}
    		///////////////////////////////////////////////////////////////////
			memset((unsigned char*)fourGtxBuffer,0x00,sizeof(fourGtxBuffer));
			fourgtxBufferIndex =0;
			fourGtxBuffer[fourgtxBufferIndex++]=0x02;//start byte //0
			fourGtxBuffer[fourgtxBufferIndex++]=0x94;//frame info firmware info //1
			fourGtxBuffer[fourgtxBufferIndex++]=0x01;//sub frame  //2
			fourGtxBuffer[fourgtxBufferIndex++]=0x01;//length high //3
			fourGtxBuffer[fourgtxBufferIndex++]=0x01;//length Low  //4

			memcpy(&fourGtxBuffer[fourgtxBufferIndex],buff,stringlen); //6 &7

			fourgtxBufferIndex+=stringlen;

			fourGtxBuffer[fourgtxBufferIndex++]=0x03;//end byte //8

			fourGtxBuffer[3]=((fourgtxBufferIndex-6)/256);  //3
			fourGtxBuffer[4]= (fourgtxBufferIndex-6) % 256;   //4

			HAL_UART_Transmit(&huart2, (uint8_t*)fourGtxBuffer,fourgtxBufferIndex,0xffff);
			//////////////////////////////////////////////////////////////////
    	}
    	else if(strstr_1(Rec1[2], "Reset"))
		{
    		///////////////////V3.3.1//////////////////
			strcpy(Msg_Id,Rec1[1]);
//			memcpy(Msg_Id,Rec1[1],strlen_1(Rec1[1])); //
			if(strstr_1(Rec1[3], "Soft"))
			{
				if(charger_status_G1.start == Started)
				{
					charger_status_G1.stop = Try_To_Stop;
					charger_status_G1.reson = SoftReset;
					charger_status_G1.charging_status = SuspendedEVSE_ChargerPoint;
				}


			}
			else if(strstr_1(Rec1[3], "Hard"))
			{
				hard_reset = 1;
				if(charger_status_G1.start == Started)
				{
					charger_status_G1.stop = Try_To_Stop;
					//charger_status_G1.timer = 0;
					charger_status_G1.reson = HardReset;
					charger_status_G1.charging_status = SuspendedEVSE_ChargerPoint;
				}

			}
			reset_response(Msg_Id,"Accepted");
			///////////////////////////////////////////////////
		}
    	else if(strstr_1(Rec1[2], "ChangeAvailability"))
		{
    		uint8_t conn =0,operative;
    		strcpy(Msg_Id,Rec1[1]);
    		for(char i=3;i<5;i++)
			{
				if(strstr_1(Rec1[i], "connectorId"))
				{
					conn = connectorid(Rec1[i]);
				}
				else if(strstr_1(Rec1[i], "Operative"))
				{
					operative = Available_ChargerPoint;
				}
				else if(strstr_1(Rec1[i], "Inoperative"))
				{
					operative = Unavailable_ChargerPoint;
				}
			}

			if(conn == 0)
			{
				if(operative == Available_ChargerPoint)
				{
					Ocpp_Setting.Operative[0] = Available_ChargerPoint;
					Ocpp_Setting.Operative[1] = Available_ChargerPoint;
					Ocpp_Setting.Operative[2] = Available_ChargerPoint;
					Ocpp_Setting.Operative[3] = Available_ChargerPoint;
				}
				if(operative == Unavailable_ChargerPoint)
				{
					Ocpp_Setting.Operative[0] = Unavailable_ChargerPoint;
					Ocpp_Setting.Operative[1] = Unavailable_ChargerPoint;
					Ocpp_Setting.Operative[2] = Unavailable_ChargerPoint;
					Ocpp_Setting.Operative[3] = Unavailable_ChargerPoint;
				}
			}
			else if(conn == 1)
			{
				if(operative == Available_ChargerPoint)
				{
					if(Ocpp_Setting.Operative[1] == Unavailable_ChargerPoint)
					{

						Ocpp_Setting.Operative[1] = Available_ChargerPoint;
						charger_status_G1.charging_status = Available_ChargerPoint;
						charger_status_G1.timer = Ocpp_Setting.StatusDuration;
					}
				}
				if(operative == Unavailable_ChargerPoint)
				{
					Ocpp_Setting.Operative[1] = Unavailable_ChargerPoint;

				}
			}
			reset_response(Msg_Id,"Accepted");
			Store_Key_Parameter =1; //V4.1.3
		}
    	else if(strstr_1(Rec1[2],"TriggerMessage"))
		{
    		///////////////////V3.3.1//////////////////
		uint8_t conn;
		strcpy(Msg_Id,Rec1[1]);

//		memcpy(Msg_Id,Rec1[1],strlen_1(Rec1[1])); //

		for(n=4;n<=20;n++)
		{
			s = strstr_1(Rec1[n], "connectorId");

			if(s!=NULL)
			{
			   conn = connectorid(Rec1[n]);
			   break;
			}
		}
		for(n=3;n<=20;n++)
		{
			if(strstr_1(Rec1[n],"requestedMessage"))
			{
				if(strstr_1(Rec1[n],"BootNotification"))
				{

					enQueue(initialisation_ocpp);
				}
				else if(strstr_1(Rec1[n],"DiagnosticsStatusNotification"))
				{

				}
				else if(strstr_1(Rec1[n],"FirmwareStatusNotification"))
				{
					enQueue(FirmwareStatusNotification);
				}
				else if(strstr_1(Rec1[n],"Heartbeat"))
				{
					enQueue(Heartbeat_ocpp);
				}
				else if(strstr_1(Rec1[n],"MeterValues"))
				{
					if(conn == 1)
					{
						enQueue(G1_MeterValue_ClockAlign);
					}
					else if(conn == 2)
					{
						enQueue(G2_MeterValue_ClockAlign);
					}
					else if(conn == 3)
					{
						enQueue(G3_MeterValue_ClockAlign);
					}
					else if(conn == 0)
					{
						enQueue(G_MeterValue_ClockAlign);
					}
				}
				else if(strstr_1(Rec1[n],"StatusNotification"))
				{
					if(conn == 1)
					{
						enQueue(G1_StatusNotification);
					}
					else if(conn == 2)
					{
						enQueue(G2_StatusNotification);
					}
					else if(conn == 3)
					{
						enQueue(G3_StatusNotification);
					}
				}
			}
			break;
		}
		reset_response(Msg_Id,"Accepted");
		////////////////////////////////////////////////

		}
    	else if(strstr_1(Rec1[2],"GetLocalListVersion"))
    	{
    		strcpy(Msg_Id,Rec1[1]);

    		memset((unsigned char*)fourGtxBuffer,0x00,sizeof(fourGtxBuffer));
    				memset((unsigned char*)buff,0x00,sizeof(buff));

    			//		       	sprintf(&buff,"%u",content_length);
    				fourgtxBufferIndex =0;
    				fourGtxBuffer[fourgtxBufferIndex++]=0x02;//start byte //0
    				fourGtxBuffer[fourgtxBufferIndex++]=0x94;//frame info firmware info //1
    				fourGtxBuffer[fourgtxBufferIndex++]=0x01;//sub frame  //2
    				fourGtxBuffer[fourgtxBufferIndex++]=0x01;//length high //3
    				fourGtxBuffer[fourgtxBufferIndex++]=0x01;//length Low  //4


    				stringlen=	sprintf(buff,"[3,%s,{\"listVersion\": %d}]",Msg_Id,rfid_pointer.verion);
    				memcpy(&fourGtxBuffer[fourgtxBufferIndex],buff,stringlen); //6 &7

    				fourgtxBufferIndex+=stringlen;

    				fourGtxBuffer[fourgtxBufferIndex++]=0x03;//end byte //8

    				fourGtxBuffer[3]=((fourgtxBufferIndex-6)/256);  //3
    				fourGtxBuffer[4]= (fourgtxBufferIndex-6) % 256;   //4

    				HAL_UART_Transmit_DMA(&huart2, (uint8_t*)fourGtxBuffer,fourgtxBufferIndex);
///////////////////////////////////////////////////////////////////
    	}
    	else if(strstr_1(Rec1[2],"SendLocalList"))
    			{
    				char *tagid, k , i;

    				strcpy(Msg_Id,Rec1[1]);
    				if(Ocpp_Setting.LocalAuthListEnbl == 1)
    				{
    	//						if(strstr_1(Rec1[3],"listVersion"))
    	//						{
    	//							//	rfid_pointer.verion = process_transId(Rec1[3]);
    	//						}
    					if(strstr_1(Rec1[4],"localAuthorizationList"))
    					{
    				//		char ADD=0;
    						LocalListAdding = 1;
    						for( i = 4;i < 30;i++)
    						{
    							if(strstr_1(Rec1[i],"\"idTag\":"))
    							{
    								tagid = process_otp(Rec1[i]);
    								strcpy(rfid_data.TagId[LocalListAdding],tagid);
    								i++;

    								for( k=i ; k < i+3 /* strstr_1(Rec1[k],"}}" ) != NULL */; k++)
    								{
    									if(strstr_1(Rec1[k],"idTagInfo"))
    									{
    										i++;
    										rfid_data.status[LocalListAdding] = IDtagValidation(Rec1[k]);
    									}
    									else if(strstr_1(Rec1[k],"expiryDate"))
    									{
    										i++;
    										ret = ExpiryDate(Rec1[k]);
    										strcpy(rfid_data.expiery_time[LocalListAdding],ExpiryDifferanceTime);
    									}
    									else if(strstr_1(Rec1[k],"parentIdTag"))
    									{
    										i++;
    									}

    									if(strstr_1(Rec1[k],"}}"))
    									{
    		//								k = i+3;
    		//								continue;
    										i--;
    										break;
    									}
    								}
    								LocalListAdding++;
    							}
    							else if(strstr_1(Rec1[i],"updateType"))
    							{
    								if(strstr_1(Rec1[i],"Full"))
    								{
    									rfid_pointer.Added_rfid = 0; //LocalListAdding;
    									LocalListAdding = LocalListAdding-1;//4.1.4
    									rfid_pointer.lastPointer = 3816*4096;
    									Local_List_Update = 1;
    									reset_response(Msg_Id,"Accepted");
    									rfid_pointer.verion =  process_transId(Rec1[3]);
    								}
    								else if(strstr_1(Rec1[i],"Differential"))
    								{
    									if(rfid_pointer.verion ==  process_transId(Rec1[3]))
    									{
    										//rfid_pointer.Added_rfid += LocalListAdding;
    										  Local_List_Update = 1;
    										  reset_response(Msg_Id,"Accepted");
    									}
    									else
    									{
    										reset_response(Msg_Id,"VersionMismatch");
    									}

    								}

    								break;
    							}
    						}
    					}
    				}
    				else
    				{
    					reset_response(Msg_Id,"NotSupported");
    				}
    			}
    	else if(strstr_1(Rec1[2],"UnlockConnector"))
    	{
    		//////////////V3.3.1//////////////////
			uint8_t conn;
			strcpy(Msg_Id,Rec1[1]);
			s = strstr_1(Rec1[3], "connectorId");
			if(s!=NULL)
			{
			   conn = connectorid(Rec1[3]);
			}

			if(conn == 1)
			{
				if(charger_status_G1.start == Started)
				{
					reset_response(Msg_Id,"UnlockFailed");
				}
				else
				{
					reset_response(Msg_Id,"Unlock");
				}
			}


		////////////////////////////////////////////////
    	}
    	else if(strstr_1(Rec1[2],"UpdateFirmware"))
		{
			strcpy(Msg_Id,Rec1[1]);
			for(char i=3;i<5;i++)
			{
				if(strstr_1(Rec1[i], "location"))
				{
					status = Parse_fw_uri(Rec1[i]);
					break;
				}
			}

			if(status == 1)
			{
				reset_response(Msg_Id,"Downloading");
			}
			else
			{
				reset_response(Msg_Id,"DownloadFailed");
			}
		}
    }
    free(buff);
    buff = NULL;
 }

/**
 * @brief Process the received time information from the server.
 *
 * @param CheckString String containing time information.
 * @return None.
 */
void process_time(String CheckString)
{
	int k = 0;/* Local variable */
	int r = 0;
	for(r=0;r<=100;r++)
	{
		if (CheckString[r] == ':')/* If colon detected */
		{
			for(k=0;k<55;k++)
			{
				AC001_OCPP_Con1_timestamp[k] = CheckString[k+(r+1)];/* Assign the timestamp con 1 */
			//	AC001_OCPP_Con2_timestamp[k] = CheckString[k+(r+1)];/* Assign the timestamp con 2 */
			//	AC001_OCPP_Con2_timestamp[k] = CheckString[k+(r+1)];/* Assign the timestamp con 3 */
			}
			AC001_OCPP_Con1_timestamp[k] = '\0';
			break;
		}
	}

	//HAL_UART_Transmit(&huart1, (uint8_t*)AC001_OCPP_Con1_timestamp,strlen(AC001_OCPP_Con1_timestamp),0xffff);
	rtc_calibration(AC001_OCPP_Con1_timestamp);
}

/**
 * @brief Process the interval information from the server string.
 *
 * @param TransString String containing interval information.
 * @return The processed interval.
 */

int process_interval(String TransString)
{
    int k = 0;/* Local variable */
	int r = 0;
	uint8_t temp_1[15];/* Local variable */
	int p,m,interval;/* Local variable */
	interval = 1u;/* Clear the transactionId */
	for(r=0;r<=100;r++)
	{
		if (TransString[r] == ':')/* If colon detected */
		{
			++r;
			while((TransString[r] != '}') && (TransString[r] != '\0') )
			{
				temp_1[k]=TransString[r];
				k++;
				++r;
			}

			for(p=1,m=k;m>0;p=p*10)
			{
				interval = (uint32_t)(temp_1[m-1]-'0')*p+(uint32_t)interval;
				m--;
			}
			break;
		}
	}
	interval--;
	return interval;
//	UART_Printf("Transaction Id Integer: %d \r\n",Type2_OCPP_TransactionId);
}

/**
 * @brief Validate the ID tag status from the server response.
 *
 * @param data Server response string containing ID tag status.
 * @return ID tag status:
 *         - 1: Accepted
 *         - 2: Blocked
 *         - 3: Expired
 *         - 4: Invalid
 *         - 5: ConcurrentTx
 *         - -1: Not Found or Unknown Status
 */
char IDtagValidation(char *data)
{
	char *s,status = -1;
		s = strstr_1(data, "status");
		if (s != NULL)
		{
			if (strstr_1(data, "Accepted"))
			{
				status = 1;
			}
			else if(strstr_1(data, "Blocked"))
			{
				status = 2;
			}
			else if(strstr_1(data, "Expired"))
			{
				status = 3;
			}
			else if(strstr_1(data, "Invalid"))
			{
				status = 4;
			}
			else if(strstr_1(data, "ConcurrentTx"))
			{
				status = 5;
			}
		}
	return status;
}
/**
* @brief Extract the expiry date from the server response.
*
* @param Rec1 Server response string.
* @return Status:
*         - 2: Expiry date extracted successfully
*         - -1: Expiry date not found or invalid format
*/
char ExpiryDate(char Rec1[100])
{
	char n,*s,k,r;

	for(r=0;r<=100;r++)
	{
		if ((Rec1[r] == ':') && (Rec1[r+1] != '{')) /* If colon detected */
		{
			++r;

			for(k=0;k<30;k++)
			{
				if ((Rec1[r + k] == '\0') || (Rec1[r + k] == 'Z') || (Rec1[r + k] == '+'))
				{
					if(k < 9)
					{
						break;
					}
				}
				else if(Rec1[k+(r+1)] != '"')
				{
					ExpiryDifferanceTime[k] = Rec1[k+(r+1)]; /* Assign the timestamp con 1 */
				}
			}
			ExpiryDifferanceTime[k] = '\0';
			break;
		}
	}

	if(k < 9)
	{
		return -1;
	}
	return 2;
}

/**
 * @brief Calculate the time difference in minutes between two date-time values.
 *
 * This function calculates the time difference in minutes between the expiration
 * time and the current time.
 *
 * @param rtc Current date-time.
 * @param expiery Expiration date-time.
 * @return The time difference in minutes. Returns -1 in case of errors.
 *         If the expiration date is less than the current date, -1 is returned.
 */
int Time_calculation(String rtc , String expiery)
{
	char * found;
	int Min=0,diff;// = exp_Hour - rtc_Hour;
	uint8_t rtc_Day,rtc_Month,rtc_Year,rtc_Hour,rtc_Min,rtc_Sec;
	uint8_t exp_Day,exp_Month,exp_Year,exp_Hour,exp_Min,exp_Sec;

	//found = strtok(rtc,"T");

	{
		rtc_Day = (((rtc[8]-48)*10) + (rtc[9]-48));

		rtc_Month = (((rtc[5]-48)*10) + (rtc[6]-48));

		rtc_Year = (((rtc[2]-48)*10) + (rtc[3]-48));

		//found = strtok(NULL,"*");
		//if(found != NULL)

		rtc_Hour = (((rtc[11]-48)*10) + (rtc[12]-48));

		rtc_Min = (((rtc[14]-48)*10) + (rtc[15]-48));

		rtc_Sec = (((rtc[17]-48)*10) + (rtc[18]-48));

	}
//	found = strtok(expiery,"T");
//	if(found != NULL)
	{
		exp_Day = (((expiery[8]-48)*10) + (expiery[9]-48));

		exp_Month = (((expiery[5]-48)*10) + (expiery[6]-48));

		exp_Year = (((expiery[2]-48)*10) + (expiery[3]-48));

		{
			exp_Hour = (((expiery[11]-48)*10) + (expiery[12]-48));

			exp_Min = (((expiery[14]-48)*10) + (expiery[15]-48));

			exp_Sec = (((expiery[17]-48)*10) + (expiery[18]-48));
		}
	}

	if(exp_Day == rtc_Day)
	{
		diff = exp_Hour - rtc_Hour;
		if(diff < 0)
		{
			return -1;
		}

		if(diff > 0)
		{
			Min = diff*60;
		}

		diff = exp_Min -rtc_Min;
		if(diff >= 0)
		{
			Min += diff;
		}
		else if(diff < 0)
		{
			Min += diff;
		}

		return Min;
	}
	else if((exp_Day - rtc_Day) == 1)
	{

		diff = exp_Hour - rtc_Hour;

		if(diff < 0)
		{
			Min = (24 + diff) * 60;
		}

		if(diff > 0)
		{
			Min = diff*60;
		}

		diff = exp_Min -rtc_Min;
		if(diff >= 0)
		{
			Min += diff;
		}
		else if(diff < 0)
		{
			Min += diff;
		}

		return Min;

	}
	else
	{
		return -1;
	}
}

/**
 * @brief Parse the Boot Notification response from the server.
 *
 * This function parses the Boot Notification response received from the server
 * and extracts relevant information like current time, interval, and status.
 * It updates the system configuration and status accordingly.
 *
 * @param Array An array containing Boot Notification response strings.
 *
 * @retun NA
 */
void parse_BootNotification(char Array[5][50])
{
	char *s;
	for(int i=0;i<5;i++)
	{
		s = strstr_1(Array1[i], "currentTime");
		if (s != NULL)
		{
			//if(ocpp_boot_status != 1)
			{
				//HAL_UART_Transmit(&huart1, (uint8_t*)Rec1[n],strlen(Rec1[n]),0xffff);
				process_time(Array1[i]);
				//ocpp_boot_status = 1;
				break;
			}
		}
	}
	for(int j=0;j<5;j++)
	{
		s = strstr_1(Array1[j], "interval");
		if (s != NULL)
		{
			Ocpp_Setting.HeartbeatIntvl = process_interval(Array1[j]);
			break;
		}
	}
	for(int k=0;k<5;k++)
	{
		s = strstr_1(Array1[k], "status");
		if (s != NULL)
		{
			s = strstr_1(Array1[k], "Accepted");
			if (s != NULL)
			{
				ocpp_boot_status = 1;
				//charger_status_G1.ocpp_status = Boot_Success;
				//charger_status_G2.ocpp_status = Boot_Success;
				//charger_status_G3.ocpp_status = Boot_Success;
				//	AC001_OCPP_Charger_Status = G_StatusNotification; //ONLY for Applle energy
				//charger_status_G3.timer = charger_status_G2.timer = charger_status_G1.timer = 0;
				break;
			}
		}
	}
}

/**
 * @brief Parse the response for Remote Start Transaction and update charger status.
 *
 * This function parses the response for Remote Start Transaction received from the server.
 * It extracts information such as connectorId and idTag, then updates the charger status accordingly.
 * Finally, it sends a response to the server based on the status of the remote start.
 *
 * @param Array An array containing Remote Start Transaction response strings.
 *              Array should be of size [5][50].
 *
 * @return N/A (Not Applicable) - No specific return value.
 */
void parse_remote_start_tx(char Array[5][50])
{
	uint8_t conn,n,m,buff[256];
	char *tagid,*s;
//strcpy(Msg_Id,Rec1[1]);

	for(n=0;n<5;n++)
	{
		s = strstr_1(Array1[n], "connectorId");

		if(s!=NULL)
		{
		   conn = connectorid(Array1[n]);
		   break;
		}
	}

	for(m=0;m<=6;m++)
	{
		s = strstr_1(Array1[m], "idTag");
		if(s != NULL)
		{
			tagid = process_otp(Array1[m]);
			break;
		}
	}

#if target == actype2
		if((conn == 1 )  && (CURRENT_STATE==STATE_B))
		{
			charger_status_G1.reson = Remote;
			charger_status_G1.charge_by_automatic =1;
			charger_status_G1.charge_by_time = 0;
			charger_status_G1.energy =0;
//			strcpy(charger_status_G3.start_tagid,tagid);
			charger_status_G1.reson = Remote;
			charger_status_G1.Authentication_done = 1;

			strcpy(charger_status_G1.start_tagid,tagid);

//			memcpy(charger_status_G3.start_tagid,tagid,strlen_1(tagid)); //
		}
#else
		if(conn == 1 && (charger_status_G1.charging_status == Available_ChargerPoint))	//V5.0.0 change
		{///////////////////V3.3.1//////////////////
			charger_status_G1.start = Try_To_Start;

			charger_status_G1.charge_by_automatic =1; //v4.1.3
			charger_status_G1.charge_by_time = 0;
			charger_status_G1.energy =0;
//			memcpy(charger_status_G1.start_tagid,tagid,strlen_1(tagid)); //
			charger_status_G1.reson = Remote;
			strcpy(charger_status_G1.start_tagid,tagid);

		}//////////////////////////////////////////////////
#endif



		else
		{

		}

		memset((unsigned char*)buff,0x00,sizeof(buff));

		if((charger_status_G1.reson == Remote))
		{
			stringlen=		sprintf(buff,"[3,%s,{\"status\":\"Accepted\"}]",Rec1[1]);
//			HAL_UART_Transmit(&huart2,(uint8_t*)buff, strlen(buff),0xffff);
			remote_start = 1;
		}

		else
		{
			stringlen=		sprintf(buff,"[3,%s,{\"status\":\"Rejected\"}]",Rec1[1]);
//			HAL_UART_Transmit(&huart2,(uint8_t*)buff, strlen(buff),0xffff);
			remote_start = 0;
		}
		memset((unsigned char*)fourGtxBuffer,0x00,sizeof(fourGtxBuffer));


		fourgtxBufferIndex =0;
		fourGtxBuffer[fourgtxBufferIndex++]=0x02;//start byte //0
		fourGtxBuffer[fourgtxBufferIndex++]=0x94;//frame info firmware info //1
		fourGtxBuffer[fourgtxBufferIndex++]=0x01;//sub frame  //2
		fourGtxBuffer[fourgtxBufferIndex++]=0x01;//length high //3
		fourGtxBuffer[fourgtxBufferIndex++]=0x01;//length Low  //4



		memcpy(&fourGtxBuffer[fourgtxBufferIndex],&buff,stringlen); //6 &7

		fourgtxBufferIndex+=stringlen;

		fourGtxBuffer[fourgtxBufferIndex++]=0x03;//end byte //8

		fourGtxBuffer[3]=((fourgtxBufferIndex-6)/256);  //3
		fourGtxBuffer[4]= (fourgtxBufferIndex-6) % 256;   //4

		HAL_UART_Transmit_DMA(&huart2, (uint8_t*)fourGtxBuffer,fourgtxBufferIndex);
	///////////////////////////////////////////////////////////////////
}

/**
 * @brief Process the Transaction ID from a string and return the integer value.
 *
 * This function extracts the Transaction ID from the input string and returns its integer value.
 *
 * @param TransString The input string containing the Transaction ID.
 * @return The integer value of the Transaction ID.
 */
unsigned long process_transId(String TransString)
{
	int k = 0;/* Local variable */
	int r = 0;
	uint8_t temp_1[15];/* Local variable */
	int p,m;/* Local variable */
	uint32_t Type2_OCPP_TransactionId = 1u;/* Clear the transactionId */
	for(r=0;r<=100;r++)
	{
		if (TransString[r] == ':')/* If colon detected */
		{
			r++;
			while((TransString[r] != '}') && (TransString[r] != '\0'))
			{
				temp_1[k]=TransString[r];
				k++;
				r++;
			}
		//	UART_Printf("Transaction ID string: %s \r\n",temp_1);

			for(p=1,m=k;m>0;p=p*10)
			{
				Type2_OCPP_TransactionId = (uint32_t)(temp_1[m-1]-'0')*p+(uint32_t)Type2_OCPP_TransactionId;
				m--;
			}

			break;
		}
	}

	Type2_OCPP_TransactionId--;
	return Type2_OCPP_TransactionId;

//	charger_status.transaction_id = Type2_OCPP_TransactionId;
//	charger_status.ocpp_status = StartTransaction_Success;

	//AC001_OCPP_Charger_Status = 3u;
	//UART_Printf("Transaction Id Integer: %d \r\n",Type2_OCPP_TransactionId);
}

/**
 * @brief Process the value from a string, extracting and converting it to an unsigned long.
 *
 * This function takes a string, searches for a colon, and extracts the numerical value
 * following it. The value is then converted to an unsigned long integer.
 *
 * @param TransString The input string containing the value.
 * @return The extracted value as an unsigned long.
 */
unsigned long process_Value(String TransString)
{
	int k = 0;/* Local variable */
	int r = 0;
	uint8_t temp_1[15];/* Local variable */
	int p,m;/* Local variable */
	uint32_t Type2_OCPP_TransactionId = 1u;/* Clear the transactionId */
	for(r=0;r<=100;r++)
	{
		if (TransString[r] == ':')/* If colon detected */
		{
			r++;
			while((TransString[r] != '}') && (TransString[r] != '\0'))
			{
				if(TransString[r] != '"')
				{
					temp_1[k] = TransString[r];
					k++;
				}
				r++;
			}
		//	UART_Printf("Transaction ID string: %s \r\n",temp_1);

			for(p=1,m=k;m>0;p=p*10)
			{
				Type2_OCPP_TransactionId = (uint32_t)(temp_1[m-1]-'0')*p+(uint32_t)Type2_OCPP_TransactionId;
				m--;
			}

			break;
		}
	}

	Type2_OCPP_TransactionId--;
	return Type2_OCPP_TransactionId;
}

/**
 * @brief Extract and return the connector ID from a string.
 *
 * This function searches for a colon in the input string and extracts the connector ID
 * following it. The extracted connector ID is returned as an unsigned char.
 *
 * @param TransString The input string containing the connector ID.
 * @return The extracted connector ID as an unsigned char.
 */
unsigned char connectorid(String TransString)
{
	int r = 0;
	uint8_t Type2_OCPP_ConnectorID = 1u;/* Clear the transactionId */
	for(r=0;r<=25;r++)
	{
		if (TransString[r] == ':')/* If colon detected */
		{
			Type2_OCPP_ConnectorID = TransString[r+1]-'0';
			break;
		}
	}
	return Type2_OCPP_ConnectorID;
}

/**
 * @brief Process the transaction ID from a string, extracting and converting it to an integer.
 *
 * This function takes a string, searches for a colon, and extracts the numerical transaction ID
 * following it. The value is then converted to an integer.
 *
 * @param TransString The input string containing the transaction ID.
 * @return The extracted transaction ID as an integer.
 */
int Remote_Stop_Tr(String TransString)
{
	int k = 0;/* Local variable */
	int r = 0;
	uint8_t temp_1[15];/* Local variable */
	int p,m;/* Local variable */
	uint32_t TransactionId = 1u;
	//Type2_OCPP_TransactionId = 1u;/* Clear the transactionId */
	for(r=0;r<=100;r++)
	{
		if (TransString[r] == ':')/* If colon detected */
		{
			while(TransString[++r] != '}')
			{
				temp_1[k]=TransString[r];
				k++;
			}

			for(p=1,m=k;m>0;p=p*10)
			{
				TransactionId = (uint32_t)(temp_1[m-1]-'0')*p+(uint32_t)TransactionId;
				m--;
			}

			break;
		}
	}
	TransactionId--;

	/*AC001_OCPP_Charger_Status = 6;
	if(TransactionId == Type2_OCPP_TransactionId)
	{
		//UART_Printf("Transaction Id Integer: %d \r\n",Type2_OCPP_TransactionId);
		return 1;
	}
	else
	{
		//UART_Printf("Transaction Id Integer: %d Type2_OCPP_TransactionId : %d \r\n",TransactionId,Type2_OCPP_TransactionId);
		return 0;
	}*/
}

/**
 * @brief Process the OTP (One-Time Password) from a string and return it as a character pointer.
 *
 * This function searches for a colon in the input string and extracts the OTP
 * (One-Time Password) following it. The extracted OTP is returned as a character pointer.
 *
 * @param TransString The input string containing the OTP.
 * @return The extracted OTP as a character pointer.
 */
char * process_otp(String TransString)
{
	int k = 0;/* Local variable */
	int r = 0;
	uint8_t temp_1[10];/* Local variable */
	int p,m;/* Local variable */
	uint32_t interval;
	interval = 1u;/* Clear the transactionId */
	for(r=0;r<=100;r++)
	{
		if ((TransString[r] == ':') && (TransString[r+1] != '['))
		{
			++r;
			while((TransString[r] != '}') && (TransString[r] != '\0'))
			{
				if(TransString[r] != '"' )
				{
					otp_ocpp[k]=TransString[r];
					k++;
				}
				++r;
			}
			otp_ocpp[k] = '\0';
			break;

			/*
			for(p=1,m=k;m>0;p=p*10)
			{
				interval = (uint32_t)(temp_1[m-1]-'0')*p+(uint32_t)interval;
				m--;
			}
			break;
			*/
		}
	}
	return otp_ocpp;
}

/**
 * @brief Calibrate the RTC (Real-Time Clock) based on the provided RTC string.
 *
 * This function extracts the day, month, year, hour, minute, and second from the
 * RTC string and sets the RTC accordingly. It also determines the time zone and UTC offset.
 *
 * @param rtc The input RTC string.
 * @return None.
 */
void rtc_calibration(String rtc) //V4.x.8
{
	char *found;
	char day,month,year,hour,min,sec,dow;


				day = (((rtc[9]-48)*10) + (rtc[10]-48));

				month = (((rtc[6]-48)*10) + (rtc[7]-48));

				year = (((rtc[3]-48)*10) + (rtc[4]-48));


				hour = (((rtc[12]-48)*10) + (rtc[13]-48));

				min = (((rtc[15]-48)*10) + (rtc[16]-48));

				sec = (((rtc[18]-48)*10) + (rtc[19]-48));

				RTC_Set(year,month,day,hour,min,sec,3);

					for(int i=19; ((rtc[i] != '\0') && (rtc[i] != '}')); i++)
					{
						if(rtc[i] == 'Z')
						{
							Time_Zone = 1;
							break;
						}
						else if(rtc[i] == '+')
						{
							offset[0] = rtc[i];   //+
							offset[1] = rtc[++i]; //0
							offset[2] = rtc[++i]; //5
							offset[3] = rtc[++i]; //:
							offset[4] = rtc[++i]; //3
							offset[5] = rtc[++i]; //0
							offset[6] = '\0'; //0
							Time_Zone = 2;
							break;
						}
					}
					if(Time_Zone == 0)
					{
						Time_Zone = 1;
					}


					//Get_Time();
					RTC_OCPP[8] = year;
					RTC_OCPP[9] = month;
					RTC_OCPP[10] = day;
					/*if(Time_Zone == 1)8
					{
						min= min+30;

						if(min > 59)
						{
							RTC_OCPP[12] =(min - 59);
							hour++;
						}
						else
						{
							RTC_OCPP[12] = min;
						}
						hour =5+hour;
						if(hour > 23)
						{
							RTC_OCPP[11] = hour - 23;
						}
						else
						{
							RTC_OCPP[11] = hour;
						}
						RTC_OCPP[13] = sec;

					}*/
					//else
					{
						RTC_OCPP[11] = hour;
						RTC_OCPP[12] = min;
						RTC_OCPP[13] = sec;
					}

}

/**
 * @brief Update the RTC (Real-Time Clock) with the provided date and time values.
 *
 * This function updates the RTC with the provided year, month, day, hour, minute, and second.
 *
 * @param year The year.
 * @param month The month.
 * @param day The day.
 * @param hour The hour.
 * @param min The minute.
 * @param sec The second.
 * @return None.
 */
void RTC_HMI(uint8_t year, uint8_t month, uint8_t day,uint8_t hour, uint8_t min, uint8_t sec)
{
	RTC_OCPP[8] = year;
	RTC_OCPP[9] = month;
	RTC_OCPP[10] = day;

	RTC_OCPP[11] = hour;
	RTC_OCPP[12] = min;
	RTC_OCPP[13] = sec;

}

/**
 * @brief Parse the firmware URI and extract server name, port, and URI information.
 *
 * This function takes a firmware URI and extracts the server name, port, and URI,
 * updating the OCPP structure with the parsed information.
 *
 * @param uri The input firmware URI.
 * @return Returns 1 if successful parsing, 0 otherwise.
 */
char Parse_fw_uri(char uri[200])
{
	int i,j;
	if(strstr_1(uri, "http://"))
	{
		for(i = 8; i < 200; i++)
		{
			if((uri[i] == '/') && (uri[i-1] == '/') && (uri[i-2] == ':'))
			{
				j = 0;
				if(uri[i] == '/')
				{
					i++;
					while(uri[i] != ':')
					{
						OCPP.fw_servername[j] = uri[i];
						if(++j > 29)
						{
							break;
						}
						i++;
					}
				}
				OCPP.fw_servername[j] = '\0';

				if(uri[i] == ':')
				{
					i++;
					j=0;

					while(uri[i] != '/')
					{
						OCPP.fw_Port[j] = uri[i];
						if(++j > 4)
						{
							break;
						}
						i++;
					}
					OCPP.fw_Port[j] = '\0';
				}
				else
				{
					break;
				}

				if(uri[i] == '/')
				{
					j = 0;

					while((uri[i] != '"') && (uri[i] != '\0') && (uri[i] != '}'))
					{
						OCPP.fw_uri[j] =  uri[i];
						if(++j > 98)
						{
							break;
						}
						++i;
					}
					OCPP.fw_uri[j] = '\0';
					OCPP.fw_status = 64;

					fw_update =1;
					write_para= 1;
					return 1;
				}
				else
				{
					break;
				}

			}
		}

	}
	return 0;
}

/**
 * @brief Calculate the length of the provided string, excluding '\0', '\r', and '\n'.
 *
 * This function calculates the length of the provided string until it encounters
 * '\0', '\r', or '\n', whichever comes first.
 *
 * @param data The input string.
 * @return The length of the string.
 */
int strlen_1(unsigned char *data)	//V4.x.8
{
	 int len = 0;

	while((*data != '\0') && (*data != '\r') && (*data != '\n'))
	{
		if(++len > 512)
		{
			return 0;
		}
		data++;
	}
	return len;
}

/**
 * @brief Compare two strings, excluding '\r' and '\n'.
 *
 * This function compares two strings character by character until it encounters
 * '\r', '\n', or '\0' in either of them. Returns 0 if the strings are identical,
 * 1 otherwise.
 *
 * @param a The first string.
 * @param b The second string.
 * @return Returns 0 if the strings are identical, 1 otherwise.
 */
int strcmp_1(unsigned char *b,unsigned char *a)	//V4.x.8
{
	int len=strlen_1(a);
	if( len == 0)
		{
			return 1;
		}
	while(*a != '\r' && *a != '\n' && *a != '\0' && len)
	{
		if(*a != *b)
		{
			return 1;

		}
		a++;
		b++;
		len--;
	}
	if( len == 0)
	{
		return 0;
	}
	else
	{
		return 1;
	}
}

/**
 * @brief Compare two strings to check if they are the same.
 *
 * This function compares two strings character by character until it encounters
 * '\0' in both strings. Returns true if the strings are identical, false otherwise.
 *
 * @param X The first string.
 * @param Y The second string.
 * @return Returns true if the strings are identical, false otherwise.
 */
int compare(const char *X, const char *Y)		//V4.x.8
{
    while (*X && *Y)
    {
        if (*X != *Y) {
            return 0;
        }
        X++;
        Y++;
    }

    return (*Y == '\0');
}

/**
 * @brief Implementation of the `strstr()` function.
 *
 * This function finds the first occurrence of the substring `Y` in the string `X`.
 *
 * @param X The input string.
 * @param Y The substring to search for.
 * @return Returns a pointer to the first occurrence of `Y` in `X`, or NULL if not found.
 */
const char* strstr_1(const char* X, const char* Y)
{
    while (*X != '\0' && (*X != '\r') && (*X != '\n'))
    {
        if ((*X == *Y) && compare(X, Y)) {
            return X;
        }
        X++;
    }
    return NULL;
}


///////////////////////////////////////////////////
