/*
 * 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 <stdlib.h>

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


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

/* Global variables*/
extern char gafw_status[30];
volatile uint8_t LocalListAdding,Local_List_Update;
uint8_t hard_reset;
char offset[8];
uint8_t Time_Zone;
char timestamp[100];
volatile uint8_t HMI_wifi_disconnect,HMI_websocket_connect,HMI_websocket_disconnect,HMI_wifi_connect;
uint8_t remote_start = 0;
uint8_t  RTC_OCPP[14];
//{0x5A, 0xA5 ,0x0B ,0x82 ,0x00,0x9c,0x5a ,0xA5 ,0x15, 0x09 ,0x11 ,0x0C ,0x0D ,0x00};
uint8_t Store_Key_Parameter;
uint8_t server_packet[1024];
volatile uint8_t inprocess =0,BootNotification_res,RemoteStarttx_res;
char meter1whclear=0, meter2whclear=0, meter3whclear=0;

char Array1[5][50];

struct Config_Parameter OCPP;
struct Config_Parameter_OCPP Ocpp_Setting;
struct Config_Parameter_Cach_Memory Cash_Memory;
struct gsm_Parameter GSM;
struct stFirmwareUpgrade FirmwareupdateTime;

/* Extern Data Declarations */

extern uint8_t ocpp_boot_status,CURRENT_STATE,CURRENT_STATE_1;
extern char fw_update,write_para;
extern int SEC;
extern volatile char DC001_OCPP_timestamp1[30];
extern uint8_t year,month,date,hour,min,sec;
extern uint8_t internet_connection;
extern char req_network_select,res_downlink,res_notfound,req_ocpp_status,GSMreq_network_select;;
extern char otp_ocpp[30];
extern char websocket_success;
extern char Bootnotification[15];
extern char Statusnotification[15];
extern char metervalue[15];
extern uint8_t gun_1,gun_2,gun_3;
extern unsigned char  fourGtxBuffer[1000];
extern unsigned short fourgtxBufferIndex;
extern char seperator;
extern char pwronFlag;
extern unsigned char WaitForResponse;	//v4.x.7 change
extern char HeartBeat_Res[15];
extern reset_cause_t reset_cause;	//V4.x.8
extern uint16_t hmicp_val,hmicp_val_1;
extern uint8_t WIFI_Setting;
//extern char WIFI_Setting;
extern char write_para;
extern char rtc_ocpp_flag;
extern char pwm_start_stop, pwm_start_stop_1;

/* Static Data Declarations */
static char Msg_Id[50];
String Rec1[30];
static int stringlen=0;
static String AC001_OCPP_Con1_timestamp = "";
//static String ExpiryDifferanceTime = "";
static char ExpiryDifferanceTime[28];
static uint8_t status = 0;
/***** 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(char Idtoken[21],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(char chargePointModel[], char chargePointVendor[], char Model[], int ChargerID, int connector, unsigned int RandumNumber, char 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


		stringlen= sprintf(buff, "[2,\"%u\",\"BootNotification\",{\"chargePointVendor\":\"%s\",\"chargePointModel\":\"%s\",\"chargePointSerialNumber\":\"%s\",\"firmwareVersion\":\"V5.0.2\"}]",RandumNumber,OCPP.vendor_id,"ACTYPE_2",OCPP.serial_no);/* 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;
}
/**
 * @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\":%d,\"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,char * status)
{
		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\":\"%s\"}]",RandumNumber,status); // @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 meter values to the server after the charger goes into the charging state.
 *
 * @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(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 */
}
/**
 * @brief Transfer data from the charger to the server.
 *
 * @param RandumNumber Random number.
 * @param vendorid Vendor ID.
 * @param MessageID Message ID.
 * @return NA
 */
#ifdef DATATRANSFER
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(char RandumNumber[50], 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 */
#else
#if defined(dualgun)
		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\":\"2\"},{\"key\":\"MeterValueSampleInterval\",\"readonly\":false,\"value\":\"60\"},{\"key\":\"MeterValuesSampledDataMaxLength\",\"readonly\":false,\"value\":\"4\"},{\"key\":\"HeartbeatInterval\",\"readonly\":false,\"value\":\"%d\"},{\"key\":\"TransactionMessageAttempts\",\"readonly\":false,\"value\":\"%d\"}],\"unknownKey\":[\"\"]}]",RandumNumber,interval,Ocpp_Setting.FailedAttempt);/* 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\":\"1\"},{\"key\":\"MeterValueSampleInterval\",\"readonly\":false,\"value\":\"60\"},{\"key\":\"MeterValuesSampledDataMaxLength\",\"readonly\":false,\"value\":\"4\"},{\"key\":\"HeartbeatInterval\",\"readonly\":false,\"value\":\"%d\"},{\"key\":\"TransactionMessageAttempts\",\"readonly\":false,\"value\":\"%d\"}],\"unknownKey\":[\"\"]}]",RandumNumber,interval,Ocpp_Setting.FailedAttempt);/* 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(&huart2, (uint8_t*)fourGtxBuffer,480,0XFFFF);

		HAL_UART_Transmit(&huart2, (uint8_t*)&fourGtxBuffer[480],(fourgtxBufferIndex-480),0XFFFF);

		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(char RandumNumber[50], String response)
{
//	char *buff;
//	buff = malloc(200 * sizeof(char));
	char buff[100];
	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(&huart2, (uint8_t*)fourGtxBuffer,fourgtxBufferIndex,0xffff);

//		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, char* status, char* datetime, char* error)
{
	char *buff;
	buff = malloc(600 * sizeof(char));
	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\",\"StatusNotification\",{\"connectorId\":%d,\"errorCode\":\"%s\",\"status\":\"%s\",\"timestamp\":\"%s\",\"vendorId\":\"LUBI-AC-2021\",\"vendorErrorCode\":\"%d\"}]",RandumNumber,connector,error,status,datetime,(connector == 1 ? hmicp_val : hmicp_val_1));/* Fill data in buffer */ //v4.x.8 -write eror code
	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;
				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;
				HMI_websocket_connect = 0;
				internet_connection = 255;
			}
		}
		else if(server_packet[1] == 0x83) // request OCPP uri (Internet connection)
		{
			if(server_packet[2] == 1)
			{
				wifi_connected = 1;
				HMI_wifi_connect = 1;
			}
			else if(server_packet[2] == 2)
			{
			    if(server_packet[5] == 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(charger_status_G1.ocpp_status == Current_Demand)
					{
						enQueue(initialisation_ocpp);
						enQueue(G1_StatusNotification_ocpp);
					}
					else
					{
						enQueue(initialisation_ocpp);

					}*/
					if(pwronFlag==1)	//4.1.5
					{
						pwronFlag=2;
						qClear();
						enQueue(initialisation_ocpp);
					}
					else if(pwronFlag==2)
					{
						ocpp_boot_status=1;
					}
					enQueue(G1_StatusNotification_ocpp);
#if defined(dualgun)
					enQueue(G2_StatusNotification_ocpp);
#endif
					charger_status_G1.timer = charger_status_G2.timer = 5;

					//charger_status_G1.ocpp_status = Not_Connect;
					//charger_status_G2.ocpp_status = Not_Connect;
					HMI_websocket_connect = 1; //hmi indication
					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;
					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];
						   //csq
					   }
					   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
								}
							}
						}
		//////////////////////////////////////////////////


	}
	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;
	static int ret;
	///4.1.1
	char *buff;
	buff = malloc(500 * sizeof(char));
	//char buff[500];/* Local variable */

  //  for(n=0;n<=20;n++)
    {
    	char *s;

    	///////////4.x.7 changes///////////////////
    			if(strcmp_1(Rec1[1],HeartBeat_Res) == 0)
    			{
    					WaitForResponse = false;
    				//	return; //4.X.8
    			}
    			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_G2.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_G2.ocpp_status = StopTransaction_Success;
    					//AC001_OCPP_Charger_Status = G_StatusNotification;
    					charger_status_G2.timer = 0;

    				}
    				else
    				{/////V3.3.1/////////////////////////////////
    					//charger_status_G2.ocpp_status = StopTranscation_Fail;
    				}//////////////////////////////////////////////////
    				if(Ocpp_Setting.StopTxInvalidId == true)
    				{
    					charger_status_G2.ocpp_status = StopTransaction_Success;
    					charger_status_G2.timer = 0;
    				}
    				charger_status_G2.ocpp_status = StopTransaction_Success;
    			}
    	    	else if(strcmp_1(Rec1[1],charger_status_G3.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_G3.ocpp_status = StopTransaction_Success;

    					//AC001_OCPP_Charger_Status = G_StatusNotification;
    					charger_status_G3.timer = 0;

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

    				if(Ocpp_Setting.StopTxInvalidId == true)
    				{
    					charger_status_G3.ocpp_status = StopTransaction_Success;
    					charger_status_G3.timer = 0;
    				}
    				charger_status_G3.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_G2.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_G2.ocpp_status = Authorise_Success;
    					charger_status_G2.timer = 0;
    				}
    				else
    				{////////////////////////V3.3.1////////////////////////////
    					charger_status_G2.ocpp_status = Authorise_Fail;
    				}///////////////////////////////////////
    			}
    	    	else if(strcmp_1(Rec1[1],charger_status_G3.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_G3.ocpp_status = Authorise_Success;
    				}
    				else
    				{////////////////////////V3.3.1////////////////////////////
    					charger_status_G3.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 < 15)
    				{
    					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;
    			strcpy(charger_status_G1.expiry_tag, ExpiryDifferanceTime);
    			//charger_status_G1.expiry_tag = ExpiryDifferanceTime;		//TODO ExpiryDifferanceTime store cache memory of gun1
    			//remove
    		}
    		else
			{
				charger_status_G1.ocpp_status = StartTransaction_Fail;
			}

		}
		else if(strcmp_1(Rec1[1],charger_status_G2.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_G2.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_G2.charge_by_automatic = 1;
					}
					else
					{
						charger_status_G2.charge_by_time =  (unsigned int)ret+10;	//V5.0.0 - added 10minutes
						charger_status_G2.charge_by_automatic = 0;
					}
				}
				else
				{
					charger_status_G2.charge_by_automatic = 1;
				}
				charger_status_G2.ocpp_status = StartTransaction_Success;
				charger_status_G2.timer = 0;
				strcpy(charger_status_G2.expiry_tag, ExpiryDifferanceTime);
				//charger_status_G2.expiry_tag = ExpiryDifferanceTime;	//TODO ExpiryDifferanceTime store cache memory of gun2

			}
			else
			{
				charger_status_G2.ocpp_status = StartTransaction_Fail;
			}
		}
		else if(strcmp_1(Rec1[1],charger_status_G3.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_G3.transaction_id = process_transId(Rec1[i]);
				}
			}

			if(status == 1)
			{
				if(ret != -1)
				{
					ret = Time_calculation(DC001_OCPP_timestamp1,ExpiryDifferanceTime);
					if(ret == -1)
					{
						charger_status_G3.charge_by_automatic = 1;
					}
					else
					{
						charger_status_G3.charge_by_time =(unsigned int)ret+10;	//V5.0.0 - added 10minutes
						charger_status_G3.charge_by_automatic = 0;
						strcpy(charger_status_G1.expiry_tag, ExpiryDifferanceTime);
						//charger_status_G3.expiry_tag = ExpiryDifferanceTime; 	//TODO ExpiryDifferanceTime store cache memory for gun3
					}
					 //  ExpiryDifferanceTime CACH MEMORY STORE TODO
				}
				else
				{
					charger_status_G3.charge_by_automatic = 1;
				}
				charger_status_G3.ocpp_status = StartTransaction_Success;
				charger_status_G3.timer = 0;
			}
			else
			{
				charger_status_G3.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]);
        		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"))      // search for string "hassasin" in buff
    	{
    		uint32_t tr_id,remote_stop=0;
    		strcpy(Msg_Id,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.stop = Try_To_Stop;
						charger_status_G1.timer =0;
						remote_stop =1;
						charger_status_G1.charging_status = Finishing_ChargerPoint;
					}
					else if((tr_id == charger_status_G2.transaction_id) && (charger_status_G2.start == Started))
					{

						charger_status_G2.stop = Try_To_Stop;
						remote_stop =1;
						charger_status_G2.timer =0;
						charger_status_G2.charging_status = Finishing_ChargerPoint;
					}
					else if((tr_id == charger_status_G3.transaction_id) && (charger_status_G3.start == Started))
					{
						charger_status_G3.stop = Try_To_Stop;
						charger_status_G3.timer =0;
						remote_stop =1;
						charger_status_G3.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);  // CHANGED BY RONAK
//								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_DMA(&huart2, (uint8_t*)fourGtxBuffer,fourgtxBufferIndex);
			//////////////////////////////////////////////////////////////////
					remote_stop  = 0;
					break;
				}
					//remote_stop = 1;
			}
    	}
    	else if(strstr_1(Rec1[2], "ChangeConfiguration"))
    	{
    		strcpy(Msg_Id,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\":\"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 defined(mulfactor)

			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 =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\":\"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\":\"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\""))
			{
				s = strstr_1(Rec1[4], "value");
				if(s!=NULL)
				{
					s = strstr_1(Rec1[4], "true");
					if(s!=NULL)
					{
						Ocpp_Setting.AllowOfflineTXUnknownId = 1;
					}
					else
					{
						s = strstr_1(Rec1[4], "false");
						if(s!=NULL)
						{
							Ocpp_Setting.AllowOfflineTXUnknownId = 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]);

    		if((strcmp_1(Rec1[3],"{\"key\":[]}")) == 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"]}
				{
					stringlen = sprintf(buff,"[3,%s,{\"configurationKey\":[{\"key\":\"NumberOfConnectors\",\"readonly\":true,\"value\":\"3\"}],\"unknownKey\":[\"\"]}]",Msg_Id);
		//			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\":true,\"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\"]}"))
				{
					if(Ocpp_Setting.AuthCachEnable == 1)
					{
						stringlen = sprintf(buff,"[3,%s,{\"configurationKey\":[{\"key\":\"AuthorizationCacheEnabled\",\"readonly\":false,\"value\":\"true\"}],\"unknownKey\":[\"\"]}]",Msg_Id);
					}
					else
					{
						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\"]}"))
				{
					if(Ocpp_Setting.LocalPreAuth == 1)
					{
						stringlen = sprintf(buff,"[3,%s,{\"configurationKey\":[{\"key\":\"LocalPreAuthorize\",\"readonly\":true,\"value\":\"true\"}],\"unknownKey\":[\"\"]}]",Msg_Id);
					}
					else
					{
						stringlen = sprintf(buff,"[3,%s,{\"configurationKey\":[{\"key\":\"LocalPreAuthorize\",\"readonly\":true,\"value\":\"False\"}],\"unknownKey\":[\"\"]}]",Msg_Id);
					}
					// 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\":\"true\"}],\"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\"]}"))
				{
					if(Ocpp_Setting.LocalPreAuth == 1)
					{
						stringlen = sprintf(buff,"[3,%s,{\"configurationKey\":[{\"key\":\"LocalAuthListEnabled\",\"readonly\":false,\"value\":\"true\"}],\"unknownKey\":[\"\"]}]",Msg_Id);
					}
					else
					{
						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.FailedAttempt);
				//	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\"]}"))
				{
					if(Ocpp_Setting.stoptransinternetLoss==1)
					{
						stringlen = sprintf(buff,"[3,%s,{\"configurationKey\":[{\"key\":\"StopTransactionOnInvalidId\",\"readonly\":false,\"value\":\"true\"}],\"unknownKey\":[\"\"]}]",Msg_Id);
					}
					else
					{
						stringlen = sprintf(buff,"[3,%s,{\"configurationKey\":[{\"key\":\"StopTransactionOnInvalidId\",\"readonly\":false,\"value\":\"False\"}],\"unknownKey\":[\"\"]}]",Msg_Id);
					}
				//	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\":true,\"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\":\"CpOffset\",\"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\":\"CpOffset\",\"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\":\"CpOffset\",\"readonly\":false,\"value\":\"%d\"}],\"unknownKey\":[\"\"]}]",Msg_Id,OCPP.STATE_C_LEVEL);
			//		HAL_UART_Transmit_DMA(&huart2, (uint8_t*)buff, strlen(buff));
				}
			//-----------------------------------------------------------------------
				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\"]}"))
				{
					if(Ocpp_Setting.AllowOfflineTXUnknownId == 1)
					{
						stringlen = sprintf(buff,"[3,%s,{\"configurationKey\":[{\"key\":\"AllowOfflineTxForUnknownId\",\"readonly\":false,\"value\":\"true\"}],\"unknownKey\":[\"\"]}]",Msg_Id);
					}
					else
					{
						stringlen = sprintf(buff,"[3,%s,{\"configurationKey\":[{\"key\":\"AllowOfflineTxForUnknownId\",\"readonly\":false,\"value\":\"false\"}],\"unknownKey\":[\"\"]}]",Msg_Id);
					}
				//	HAL_UART_Transmit_DMA(&huart2, (uint8_t*)buff, strlen(buff));
				}
				else
				{
					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]);
			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;
				}

				if(charger_status_G2.start == Started)
				{
					charger_status_G2.stop = Try_To_Stop;
					charger_status_G2.reson = SoftReset;
					charger_status_G2.charging_status = SuspendedEVSE_ChargerPoint;
				}

				if(charger_status_G3.start == Started)
				{
					charger_status_G3.stop = Try_To_Stop;
					charger_status_G3.reson = SoftReset;
					charger_status_G3.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;
				}

				if(charger_status_G2.start == Started)
				{
					charger_status_G2.stop = Try_To_Stop;
					//charger_status_G2.timer =0;
					charger_status_G2.reson = HardReset;
				//	charger_status_G2.charging_status = SuspendedEVSE_ChargerPoint;
				}

				if(charger_status_G3.start == Started)
				{
					charger_status_G3.stop = Try_To_Stop;
					//charger_status_G2.timer =0;
					charger_status_G3.reson = HardReset;
				//	charger_status_G3.charging_status = SuspendedEVSE_ChargerPoint;
				}
			}
			reset_response(Msg_Id,"Accepted");
			///////////////////////////////////////////////////
		}
    	else if(strstr_1(Rec1[2], "ChangeAvailability"))
		{
    		uint8_t conn =0,operative;
    		char ch_status[20];
    		strcpy(Msg_Id,Rec1[1]);
    		for(unsigned 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[0] = Available_ChargerPoint;
						Ocpp_Setting.Operative[1] = Available_ChargerPoint;
						charger_status_G1.charging_status = Available_ChargerPoint;
						// charger_status_G1.timer = Ocpp_Setting.StatusDuration;
						enQueue(G1_StatusNotification_ocpp);
					}
					strcpy(ch_status ,"Accepted");
				}
				if(operative == Unavailable_ChargerPoint)
				{
				//	Ocpp_Setting.Operative[0] = Unavailable_ChargerPoint;
					Ocpp_Setting.Operative[1] = Unavailable_ChargerPoint;
					 if(charger_status_G1.charging_status == Charging_ChargerPoint)
					{
						// charger_status_G1.charging_status = SuspendedEVSE_ChargerPoint;
						 strcpy(ch_status ,"Scheduled");

					}
					else
					{
						enQueue(G1_StatusNotification_ocpp);
						gun_1 = G_NoError;
						charger_status_G1.charging_status = Unavailable_ChargerPoint;
						strcpy(ch_status ,"Accepted");
					}
				}
			}

			else if(conn == 2)
			{
				if(operative == Available_ChargerPoint)
				{
					if(Ocpp_Setting.Operative[2] == Unavailable_ChargerPoint)
					{
						Ocpp_Setting.Operative[2] = Available_ChargerPoint;
//						charger_status_G2.timer = Ocpp_Setting.StatusDuration;
						enQueue(G2_StatusNotification_ocpp);
						charger_status_G2.charging_status = Available_ChargerPoint;
					}
					strcpy(ch_status ,"Accepted");
				}
				if(operative == Unavailable_ChargerPoint)
				{
					Ocpp_Setting.Operative[2] = Unavailable_ChargerPoint;
					if(charger_status_G2.charging_status == Charging_ChargerPoint)
					{
						// charger_status_G1.charging_status = SuspendedEVSE_ChargerPoint;
						strcpy(ch_status ,"Scheduled");
					}
					else
					{
						enQueue(G2_StatusNotification_ocpp);
						gun_2 = G_NoError;
						charger_status_G2.charging_status = Unavailable_ChargerPoint;
						strcpy(ch_status ,"Accepted");
					}
			}
		}
#ifdef GUN3

			else if(conn == 3)
			{
				if(operative == Available_ChargerPoint)
				{
					if(Ocpp_Setting.Operative[3] == Unavailable_ChargerPoint)
					{
						Ocpp_Setting.Operative[3] = Available_ChargerPoint;
						charger_status_G3.charging_status = Available_ChargerPoint;
						charger_status_G3.timer = Ocpp_Setting.StatusDuration;
					}
				}
				if(operative == Unavailable_ChargerPoint)
				{
					Ocpp_Setting.Operative[3] = Unavailable_ChargerPoint;
				}
			}
#endif
			reset_response(Msg_Id,ch_status);
			 Store_Key_Parameter = 1;
		}
    	else if(strstr_1(Rec1[2],"TriggerMessage"))
		{
    		///////////////////V3.3.1//////////////////
		uint8_t conn;
		strcpy(Msg_Id,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;
			unsigned char i, k;

			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.expiry_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"); // CHANGED BY RONAK JIOBP
//    				}
		}
    	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)
				{
					charger_status_G1.stop = Try_To_Stop;
					charger_status_G1.reson = UnlockCommand;
					charger_status_G1.charging_status = SuspendedEVSE_ChargerPoint;

				}
				else
				{
					//forcefully stopping the GUN1 PWM if it's not stopped already
					pwm_start_stop = 0;
				}
				reset_response(Msg_Id,"Unlock");
			}
			else if(conn == 2)
			{
				if(charger_status_G2.start == Started)
				{
					charger_status_G2.stop = Try_To_Stop;
					charger_status_G2.reson = UnlockCommand;
					charger_status_G2.charging_status = SuspendedEVSE_ChargerPoint;
				}
				else
				{
					//forcefully stopping the GUN2 PWM if it's not stopped already
					pwm_start_stop_1 = 0;
				}
				reset_response(Msg_Id,"Unlock");
			}
			else if(conn == 3)
			{
				if(charger_status_G3.start == Started)
				{
					charger_status_G3.stop = Try_To_Stop;
					charger_status_G3.reson = UnlockCommand;
					charger_status_G3.charging_status = SuspendedEVSE_ChargerPoint;
				}
				reset_response(Msg_Id,"Unlock");
			}

		////////////////////////////////////////////////
    	}
    	else if(strstr_1(Rec1[2],"UpdateFirmware"))
		{
			strcpy(Msg_Id,Rec1[1]);
			for(unsigned char i=3;i<5;i++)
			{
				if(strstr_1(Rec1[i], "location"))
				{
					status = Parse_fw_uri(Rec1[i]);
				}
				if(strstr_1(Rec1[i], "retrieveDate"))
				{
					if(firwareupdateTimecalculation(Rec1[i]) != 2)
					{
						FirmwareupdateTime.counter = 300;
						FirmwareupdateTime.status = 1;
					}
				}
			}

			if(status == 1)
			{
				reset_response(Msg_Id,"Accepted");
				strcpy((char *)gafw_status ,"Downloading");
				enQueue(FirmwareStatusNotification);
			}
			else
			{
				reset_response(Msg_Id,"Rejected");
			}
		}
    }
    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");      // search for string "hassasin" in buff
	if (s != NULL)                     // if successful then s now points at "hassasin"
	{
		if (strstr_1(data, "Accepted"))                     // if successful then s now points at "hassasin"
		{
			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[120])
{
	unsigned char k,r;
	//char *s, n;

	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 expiry)
{
	//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 = (((expiry[8]-48)*10) + (expiry[9]-48));

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

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

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

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

			exp_Sec = (((expiry[17]-48)*10) + (expiry[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");      // search for string "currentTime" in Array1
		if (s != NULL)                     // if successful then s now points at "currentTime"
		{
			//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");      // search for string "interval" in Array1
		if (s != NULL)                     // if successful then s now points at "interval"
		{
			Ocpp_Setting.HeartbeatIntvl = process_interval(Array1[j]);
			break;
		}
	}
	for(int k=0;k<5;k++)
	{
		s = strstr_1(Array1[k], "status");      // search for string "status" in Array1
		if (s != NULL)                     // if successful then s now points at "status"
		{
			s = strstr_1(Array1[k], "Accepted");      // search for string "Accepted" in Array1
			if (s != NULL)                     // if successful then s now points at "Accepted"
			{
				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((conn == 1)  && (CURRENT_STATE==STATE_B) && (Ocpp_Setting.Operative[1] == Available_ChargerPoint))
		{///////////////////V3.3.1//////////////////
			charger_status_G1.reson = Remote;
			charger_status_G1.charge_by_automatic = 1; //v4.1.3
			charger_status_G1.charge_by_time = 0;
			charger_status_G1.energy = 0;
			strcpy(charger_status_G1.start_tagid, tagid);
			charger_status_G1.Authentication_done = 1;
			strcpy(charger_status_G1.start_tagid, tagid);

		}//////////////////////////////////////////////////
		if((conn == 2) && (CURRENT_STATE_1 == STATE_B) && (Ocpp_Setting.Operative[2] == Available_ChargerPoint))
		{
			charger_status_G2.reson = Remote;
			charger_status_G2.charge_by_automatic = 1; //v4.1.3
			charger_status_G2.charge_by_time = 0;
			charger_status_G2.energy = 0;

			strcpy(charger_status_G2.start_tagid, tagid);
			charger_status_G2.Authentication_done = 1;
			strcpy(charger_status_G2.start_tagid, tagid);
			///////////////////V3.3.1//////////////////
//			charger_status_G2.start = Try_To_Start;
//			charger_status_G2.reson = Remote;
//			strcpy(charger_status_G2.start_tagid,tagid);
		}/////////////////////////////////////////////
		else if((conn == 3 ) )
		{
			charger_status_G3.reson = Remote;

			strcpy(charger_status_G3.start_tagid, tagid);
			//charger_status_G3.reson = Remote;
			charger_status_G3.Authentication_done = 1;
			strcpy(charger_status_G3.start_tagid, tagid);
		}
		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 if((charger_status_G2.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 if((charger_status_G3.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] == ':')/* If colon detected */
		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 = 0;
							break;
						}
					}
					RTC_HMI(year,month,day,hour,min,sec);
					//Get_Time();
//					RTC_OCPP[8] = year;
//					RTC_OCPP[9] = month; change by ronak
//					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;  // change by ronak
//					}
//					rtc_ocpp_flag = 1;
}
/**
 * @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[0] = 0x5A;
	RTC_OCPP[1] = 0xA5;
	RTC_OCPP[2] = 0x0B;
	RTC_OCPP[3] = 0x82;
	RTC_OCPP[4] = 0x00;
	RTC_OCPP[5] = 0x9c;   // change by ronak
	RTC_OCPP[6] = 0x5a;
	RTC_OCPP[7] = 0xa5;

	RTC_OCPP[8] = year;
	RTC_OCPP[9] = month;
	RTC_OCPP[10] = day;

	RTC_OCPP[11] = hour;
	RTC_OCPP[12] = min;
	RTC_OCPP[13] = sec;
	rtc_ocpp_flag = 1;
}
/**
 * @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];  // store in username
						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;
				}
			}
		}
	}
	else if( strstr_1(uri, "ftp://"))
	{
		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_username[j] = uri[i];  // store in username
						if(++j > 20)
						{
							break;
						}
						i++;
					}
				}
				OCPP.fw_username[j] = '\0';

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

					while(uri[i] != '@')
					{
						OCPP.fw_Password[j] = uri[i];
						if(++j > 20)
						{
							break;
						}
						i++;
					}
					OCPP.fw_Password[j] = '\0';
				}
				else
				{
					break;
				}

				if(uri[i] == '@')  // hostname
				{
					i++;
					j = 0;
					while((uri[i] != '/') && (uri[i] != '\0') && (uri[i] != ':'))
					{
						OCPP.fw_servername[j] =  uri[i];
						if(++j > 30)
						{
							break;
						}
						++i;
					}
					OCPP.fw_servername[j] = '\0';
				}
				else
				{
					break;
				}
				if(uri[i] == ':')  // port
				{
					j = 0;
					i++;
					while((uri[i] != '/') && (uri[i] != '\0') )
					{
						OCPP.fw_Port[j] =  uri[i];
						if(++j > 4)
						{
							break;
						}
						++i;
					}
					OCPP.fw_Port[j] = '\0';
				}

				if(uri[i] == '/') // path
				{
					j = 0;
					while((uri[i] != '"') && (uri[i] != '\0') && (uri[i] != '}') )
					{
						OCPP.fw_uri[j] =  uri[i];
						if(++j > 100)
						{
							break;
						}
						++i;
					}
					OCPP.fw_uri[j] = '\0';
					write_para= 1;
					return 1;
				}

			}
		}
	}
	return 0;
}
char firwareupdateTimecalculation(char date_time[100])
{
	//char n,*s;
	unsigned char k,r;
	RTC_TimeTypeDef time;
	RTC_DateTypeDef date;
	HAL_StatusTypeDef res;
	// uint32_t CurrentTimeStamp = 0;

		for(r=0;r<=100;r++)
		{
			if ((date_time[r] == ':') && (date_time[r+1] != '{')) /* If colon detected */
			{
				++r;
				for(k=0;k<30;k++)
				{
					if((date_time[r + k] == '\0') || (date_time[r + k] == 'Z') || (date_time[r + k] == '+'))
					{
						if(k < 9)
						{
							break;
						}
					}
					else if(date_time[k+(r+1)] != '"')
					{
						r++;
						r++;

						FirmwareupdateTime.expDate.year = (((date_time[k+(r+1)]-48)*10) + (date_time[k+(r+2)]-48));

						FirmwareupdateTime.expDate.month = (((date_time[k+(r+4)]-48)*10) + (date_time[k+(r+5)]-48));

						FirmwareupdateTime.expDate.date = (((date_time[k+(r+7)]-48)*10) + (date_time[k+(r+8)]-48));

						if(date_time[k+(r+9)] == 'T')
						{
							FirmwareupdateTime.expTime.Hour = (((date_time[k+(r+10)]-48)*10) + (date_time[k+(r+11)]-48));

							FirmwareupdateTime.expTime.Minute = (((date_time[k+(r+13)]-48)*10) + (date_time[k+(r+14)]-48));

							FirmwareupdateTime.expTime.Second = (((date_time[k+(r+16)]-48)*10) + (date_time[k+(r+17)]-48)); ///FirmwareupdateTime.expieryDate. = date_time[k+(r+1)];  /* Assign the timestamp con 1 */
						}
						break;
					}

				}
				break;
			}
		}
		 //	char buff[512];
		//internal_rtc_read = 1;
		res = HAL_RTC_GetTime(&hrtc, &time, RTC_FORMAT_BIN);
		if(res != HAL_OK) {
			return 0;
		}

		res = HAL_RTC_GetDate(&hrtc, &date, RTC_FORMAT_BIN);
		if(res != HAL_OK) {
			UART_Printf("HAL_RTC_GetDate failed: %d\r\n", res);
			return 0;
		}

		if((FirmwareupdateTime.expDate.year ==  date.Year) && (FirmwareupdateTime.expDate.month == date.Month) && (FirmwareupdateTime.expDate.date == date.Date))
		{
			FirmwareupdateTime.counter = (uint32_t)((FirmwareupdateTime.expTime.Hour - time.Hours)*3600);

			if(FirmwareupdateTime.expTime.Minute > time.Minutes)
			{
				FirmwareupdateTime.counter += ((FirmwareupdateTime.expTime.Minute - time.Minutes)*60);
			}
			else
			{
				if(FirmwareupdateTime.counter >= ((time.Minutes - FirmwareupdateTime.expTime.Minute)*60))
				{
					FirmwareupdateTime.counter -= ((time.Minutes - FirmwareupdateTime.expTime.Minute)*60);
				}
				else
				{
					FirmwareupdateTime.counter = 0;
				}
			}

			if(FirmwareupdateTime.expTime.Second > time.Seconds)
			{
				FirmwareupdateTime.counter += FirmwareupdateTime.expTime.Second - time.Seconds;
			}
			else
			{
				if(FirmwareupdateTime.counter >= (time.Seconds - FirmwareupdateTime.expTime.Second))
				{
					FirmwareupdateTime.counter -= (time.Seconds - FirmwareupdateTime.expTime.Second);
				}
				else
				{
					FirmwareupdateTime.counter = 0;
				}
				// FirmwareupdateTime.counter -= time.Seconds - FirmwareupdateTime.expTime.Second;
			}
			// FirmwareupdateTime.counter *= 10;
			FirmwareupdateTime.status = 1;
		}
		else
		{
			return 0;
		}
	return 2;
}
/**
 * @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;
}

