/* USER CODE BEGIN Header */
/**
   ******************************************************************************
   * @file           : main.c
   * @brief          : Main program body
   * current version V5.0.0B
   * date: 14-07-2023
   ******************************************************************************
   * Last modifications done on 25-08-2022
   * Added WIFI disconnect symbol update
   * In case of energy meter failure - charging stopped
   * In charging start event in gun 1 & gun 2 , automatic go to main page issue resolved
   * OCPP testing pending
   ******************************************************************************
   */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "cmsis_os.h"
#include "adc.h"
#include "dma.h"
#include "rng.h"
#include "rtc.h"
#include "spi.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"
#include "iwdg.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include<string.h>
#include <stdarg.h>
#include"OCPP.h"
#include"modbus.h"
#include "w25qxx.h"
#include "stdio.h"

/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#define ocpp_magic_value 0XAA79
#define ocpp_setting_magic_value 0XAA79
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */
/***** Data Type, Constant, and Macro Definitions *****/
osThreadId Task1Handle;
FlashInfo_t FlashInfo;
reset_cause_t reset_cause;	//v4.x.8
/* Global variables*/
unsigned char hmi_resetCause = 0;
uint8_t status_hal;
uint8_t powerfailure_flag = 0, change = 0;
uint8_t PWM_stop_flag;
uint8_t rfid_sts_update = 0, G070_sts_tx_frame = 0, logout = 0;
uint8_t adcFailed = 0;
char fw_update;
unsigned char fourGtxBuffer[1000] = { 0 };
unsigned short fourgtxBufferIndex = 0;
char seperator = 0x07;
char pwronFlag = 0;
const int testting = 10;
char timer_seconds = 0;
char G070_TXbuff[20];
int global_conversion[20] = { 0 };
char config_TXstruct = 0, config_RXstruct = 0, config_mode_start = 0, config_mode = 0;
volatile uint16_t hmicp_val;
volatile int adc_init = 0;
volatile uint8_t Emergency_stop = 0;
volatile char alarm;
uint8_t CURRENT_STATE = 0;
uint32_t adc1_dat[3];
uint8_t count_D = 0, count_C = 0, count_A = 0, count_B = 0, count_D_2 = 0, count_C_2 = 0, count_A_2 = 0, count_B_2 = 0;
uint16_t pp_val = 0, cp_val = 0;
char write_para;
volatile char read_flash = 0;
uint8_t relay_on = 0, Charging_time, ocpp_boot_status, billing_gun;
char req_network_select, res_downlink, req_ocpp_status, GSMreq_network_select;
uint16_t s6_counter1, s6_counter2, s6_counter3;
char ocpp_timer, seq, internal_rtc_read;
uint8_t update_variable, erage_chip;
volatile char Clear_Register;

#if defined(ioncharge)
unsigned char AC_01,AC_02,AC_03;
int PowerFailureOnStartTxInvl = 1000; // ioncharge
#endif
/* Extern Data Declarations */
extern const struct Config_Parameter default_params;
extern const struct Config_Parameter_OCPP default_params_ocpp;
extern struct Config_Parameter_Cach_Memory Cash_Memory;
extern struct Config_Parameter_Cach_Memory Cash_Memory;
extern const struct FormData default_params_form;

extern char websocket_success, boot_success;
extern char server_packet[1024];
extern String DC001_OCPP_timestamp1;
extern uint8_t rxmsg[50], hmi_buffer[100];
extern uint8_t id[15];
extern char tagid[15];
extern uint8_t internet_connection;
extern uint8_t rxBuffer, hmi_buff, WIFI_Setting;
extern char chip_erase;
extern volatile uint32_t energy, energy2, energy3;
extern unsigned char etherip[10], ethersm[10], ethergw[10], ssid[20], wifi_pass[20], ocpp_uri[100], ocpp_status;
extern uint16_t charge_by_time, automatic_charging, charging_unit;
extern volatile uint8_t HMI_wifi_disconnect, HMI_websocket_connect, HMI_websocket_disconnect, HMI_wifi_connect;
extern uint32_t byte_in;
extern uint32_t byte_out;
volatile extern uint8_t LocalListAdding, Local_List_Update;
extern uint8_t Type2_OCPP_Authorization_Flag;
extern uint8_t Store_Key_Parameter;
extern volatile char flash_writing;
extern uint8_t RCD1_stop, RCD2_stop, RCD3_stop;
extern char pwm_start_stop, update_CP_Count;
extern volatile uint8_t recieve_complete_2;
extern volatile uint8_t RemoteStarttx_res;
extern char Array1[5][50];
volatile extern uint8_t inprocess;
extern volatile uint8_t BootNotification_res;
extern uint8_t hard_reset;
extern unsigned char WaitForResponse;
extern uint8_t M_buff, Send_meter;
extern char recieve_complete, wifi_status;

/* Static Data Declarations */

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

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
void MX_FREERTOS_Init(void);
/* USER CODE BEGIN PFP */
extern char ether_connection_varify(void);
extern char wifi_connection_varify(void);
extern int validate_ip(unsigned char *ip);
extern void Write_Params(void);
void StartTask1(void const *argument);
extern void Read_Params(void);
void Billing(char i);
void AC001(void);
void adc_check(void);
void AC_TYPE2(void);
char Gun1_ocpp(void);
char Gun2_ocpp(void);
char Gun3_ocpp(void);
void Adding_Rfid(void);
char expiry_calculation(String rtc_time, String expiery_time);
extern int strcmp_1(unsigned char *b, unsigned char *a);
extern int strlen_1(unsigned char *data);
void send_data_g070(void);
void copy_formdata(void);
void ipStringToArray(char *ipString, int *ipArray);

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/**
 * @brief Remaps interrupt vector table to RAM.
 * @param None
 * @return None
 */
void Remap_Table(void)
{
	// Copy interrupt vector table to the RAM.
//    volatile uint32_t *VectorTable = (volatile uint32_t *)0x20000000;
//    uint32_t ui32_VectorIndex = 0;
//
//    for(ui32_VectorIndex = 0; ui32_VectorIndex < 48; ui32_VectorIndex++)
//    {
//        VectorTable[ui32_VectorIndex] = *(__IO uint32_t*)((uint32_t)0x08008000 + (ui32_VectorIndex << 2));
//    }
	__HAL_RCC_AHB1_FORCE_RESET();
	__HAL_RCC_AHB2_FORCE_RESET();
	//  Enable SYSCFG peripheral clock
	__HAL_RCC_SYSCFG_CLK_ENABLE();
	//   __HAL_RCC_AHB_RELEASE_RESET();
	__HAL_RCC_AHB1_RELEASE_RESET();
	__HAL_RCC_AHB2_RELEASE_RESET();
	// Remap RAM into 0x0000 0000
	__HAL_SYSCFG_REMAPMEMORY_SRAM();
}
/* USER CODE END 0 */

/**
 * @brief  The application entry point.
 * @retval int
 */
int main(void)
{
	/* USER CODE BEGIN 1 */
	Remap_Table();
	__enable_irq();
	/* USER CODE END 1 */

	/* MCU Configuration--------------------------------------------------------*/

	/* USER CODE BEGIN Init */
	/* Reset of all peripherals, Initializes the Flash interface and the Systick. */

	HAL_Init();

	/* USER CODE END Init */

	/* Configure the system clock */
	SystemClock_Config();

	/* USER CODE BEGIN SysInit */

	/* USER CODE END SysInit */

	/* Initialize all configured peripherals */
	MX_GPIO_Init();
	MX_DMA_Init();
	MX_USART2_UART_Init();
	MX_USART1_UART_Init();
	MX_RTC_Init();
	MX_USART3_UART_Init();
	//MX_USART6_UART_Init();
	MX_RNG_Init();
	MX_TIM2_Init();
	MX_SPI1_Init();
#if target == actype2
	MX_TIM1_Init();
	MX_TIM5_Init();
	MX_ADC1_Init();
#endif
	//MX_IWDG_Init();	//uncomment

//  MX_ADC2_Init();
	/* USER CODE BEGIN 2 */
	///////////4G/////////////
	GSMON;
	ESPON;

	////////////////////////////////
	HAL_TIM_Base_Start_IT(&htim2);
	//status_hal = HAL_TIM_Base_Start_IT(&htim5);

	HAL_Delay(1000);
	//HAL_UART_Receive_DMA(&huart6,(uint8_t*)id,14);
	HAL_Delay(10);
	HAL_UART_Receive_DMA(&huart1, (uint8_t*) &M_buff, 1);	//V5.0.1A
	//HAL_UART_Receive_DMA(&huart1,(uint8_t*)rxmsg,37);
	HAL_Delay(10);
	HAL_UART_Receive_DMA(&huart3, &hmi_buff, 1);
	HAL_Delay(10);
	HAL_UART_Receive_DMA(&huart2, &rxBuffer, 1);
	HAL_Delay(10);
	//HAL_ADC_Start_DMA(&hadc2,adc2_dat,500);
	W25qxx_Init();
	internal_rtc_read = 1;
	Read_Params();

	HAL_Delay(10);
	if (OCPP.magic_value != ocpp_magic_value)	//0XAA80
	{
		Read_Params();
	}
	HAL_Delay(10);
	if (OCPP.magic_value != ocpp_magic_value)
	{
		Read_Params();
	}
	HAL_Delay(10);
	if (OCPP.magic_value != ocpp_magic_value)
	{
		OCPP = default_params;
		//OCPP.Communication_Mode =2;
		OCPP.ether_ip[0] = 172;
		OCPP.ether_ip[1] = 16;
		OCPP.ether_ip[2] = 100;
		OCPP.ether_ip[3] = 1;

		OCPP.magic_value = ocpp_magic_value;
		W25qxx_EraseSector(3840);
		HAL_Delay(10);
		Write_Params();
//	   byte_in=0;
//	   byte_out=0;
//	  SFlash_pointer_write();
	}
	HAL_Delay(10);
	HAL_Delay(10);
	if (OCPP.fw_status == 64)
	{
		OCPP.fw_status = 0;
		Write_Params();
		enQueue(FirmwareStatusNotification);
	}

#if hw == wifi
	GSM.gsm_enable_sts =1;
	GSM.wifi_enable_sts=0;
	GSM.ethernet_enable_sts=0;
	OCPP.Communication_Mode=2;
#else

	if (OCPP.Communication_Mode == 1)
	{
		RELAY_SW_ESPOFF;
		ESPOFF;
		GSM.gsm_enable_sts = 1;
		GSM.wifi_enable_sts = 0;
		GSM.ethernet_enable_sts = 0;

	} else if (OCPP.Communication_Mode == 2)
	{
		RELAY_SW_ESPON;
		ESPON;
		GSMOFF;
		GSM.gsm_enable_sts = 0;
		GSM.wifi_enable_sts = 1;
		GSM.ethernet_enable_sts = 0;
	}
	else if (OCPP.Communication_Mode == 3) //ethernet
	{
		RELAY_SW_ESPON;
		ESPON;
		GSMOFF;
		GSM.gsm_enable_sts = 0;
		GSM.wifi_enable_sts = 0;
		GSM.ethernet_enable_sts = 1;
	}
#endif
	HAL_Delay(10);
	HAL_Delay(1000);
	SFlash_pointer_read();
	HAL_Delay(10);

	if (FlashInfo.StructGuard1 != '$')
	{
		SFlash_pointer_read();
	}
	HAL_Delay(10);
	if (FlashInfo.StructGuard2 != '#')
	{
		SFlash_pointer_read();
	}
	byte_in = FlashInfo.lastPointer;
	HAL_Delay(10);
	SRfid_pointer_read();

	if (rfid_pointer.StructGuard1 != '$')
	{
		SRfid_pointer_read();
	}
	HAL_Delay(10);
	HAL_Delay(10);
	Read_Key_Params();

	if (Ocpp_Setting.magic_value != ocpp_setting_magic_value)	//0XAA99
	{
		Read_Key_Params();
	}

	if (Ocpp_Setting.magic_value != ocpp_setting_magic_value)
	{
		Ocpp_Setting = default_params_ocpp;
		W25qxx_EraseSector(3809);
		HAL_Delay(10);
		Ocpp_Setting.magic_value = ocpp_setting_magic_value;
		Write_Key_Params();
	}

	// Ocpp_Setting.LocalAuthOffln = 1;
	// OCPP.ocpp_status[0] = 0;

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

	charger_status_G1.ocpp_status = Not_Connect;

	charger_status_G1.error = NoError_ChargerPoint;

	charger_status_G1.start = Stoped;

	charger_status_G1.stop = Stoped;

	/////////////////v4.1.4/////////////////////
	HAL_Delay(10);
	HAL_Delay(10);
	Read_CACH_Params();
	HAL_Delay(10);
	HAL_Delay(10);
	if (Cash_Memory.magic_value != 0xAA55)
	{
		memset((unsigned char*) &Cash_Memory.transaction_id[0], 0x00, sizeof(Cash_Memory));
		Cash_Memory.magic_value = 0xAA55;
		Write_CACH_Params();
	}
	/////////////////////////////////////////////
	/////////////////////////////////////////////
//
//		GSMON;
//
//		ESPON;
//		RELAY_SW_ESPON;
//		GSM.gsm_enable_sts =0;
//					GSM.wifi_enable_sts=1;
//					GSM.ethernet_enable_sts=0;
//

	//INTIALLY CONNECT OCPP ON GSM
	//////////////////////////////////////////////////

#if target == actype2
		adc_init=1;
#endif
	//UART_Printf("START_uart\r\n");
	change = 1; //ESP restart when STM starts or Restart
	pwronFlag = 1;

	if (!EMG_SW_READ)		//CHECK IF CONFIG MODE IS ON
	{

		for (int i = 0; i < 2000; i++);	//debounce
		if (!EMG_SW_READ)
		{
			copy_formdata();
			config_mode = 1;	//configuration mode
			RELAY_SW_ESPON;
			ESPON;
			GSMOFF;
			GSM.gsm_enable_sts = 0;
			GSM.wifi_enable_sts = 1;
			GSM.ethernet_enable_sts = 0;
			meter1whclear = 1;
		}
	}

//	HAL_GPIO_WritePin(RELAY_G4_GPIO_Port,RELAY_G4_Pin,GPIO_PIN_RESET); //ON
//	HAL_GPIO_WritePin(RELAY_G3_GPIO_Port,RELAY_G3_Pin,GPIO_PIN_RESET); //ON
//	HAL_GPIO_WritePin(RELAY_G2_GPIO_Port,RELAY_G2_Pin,GPIO_PIN_RESET); //ON
//	HAL_GPIO_WritePin(RELAY_G1_GPIO_Port,RELAY_G1_Pin,GPIO_PIN_RESET); //ON

	/* USER CODE END 2 */

	if (__HAL_RCC_GET_FLAG(RCC_FLAG_LPWRRST))	//v4.x.8
	{
		reset_cause = RESET_CAUSE_LOW_POWER_RESET;
	}
	else if (__HAL_RCC_GET_FLAG(RCC_FLAG_WWDGRST))
	{
		reset_cause = RESET_CAUSE_WINDOW_WATCHDOG_RESET;
	}
	else if (__HAL_RCC_GET_FLAG(RCC_FLAG_IWDGRST))
	{
		reset_cause = RESET_CAUSE_INDEPENDENT_WATCHDOG_RESET;
	}
	else if (__HAL_RCC_GET_FLAG(RCC_FLAG_SFTRST))
	{
		// This reset is induced by calling the ARM CMSIS
		// `NVIC_SystemReset()` function!
		reset_cause = RESET_CAUSE_SOFTWARE_RESET;
	}
	else if (__HAL_RCC_GET_FLAG(RCC_FLAG_PORRST))
	{
		reset_cause = RESET_CAUSE_POWER_ON_POWER_DOWN_RESET;
	}
	else if (__HAL_RCC_GET_FLAG(RCC_FLAG_PINRST))
	{
		reset_cause = RESET_CAUSE_EXTERNAL_RESET_PIN_RESET;
	}
	// Needs to come *after* checking the `RCC_FLAG_PORRST` flag in order to
	// ensure first that the reset cause is NOT a POR/PDR reset. See note
	// below.
	else if (__HAL_RCC_GET_FLAG(RCC_FLAG_BORRST))
	{
		reset_cause = RESET_CAUSE_BROWNOUT_RESET;
	}
	else
	{
		reset_cause = RESET_CAUSE_UNKNOWN;
	}

	__HAL_RCC_CLEAR_RESET_FLAGS();
//	  update_variable =1;
	hmi_resetCause = reset_cause;

	/* Call init function for freertos objects (in freertos.c) */
	MX_FREERTOS_Init();
	osThreadDef(Task1, StartTask1, osPriorityAboveNormal, 0, 256);
	Task1Handle = osThreadCreate(osThread(Task1), NULL);
	/* Start scheduler */
	osKernelStart();

	/* We should never get here as control is--- now taken by the scheduler */
	/* Infinite loop */
	/* USER CODE BEGIN WHILE */
	while (1)
	{
		/* USER CODE END WHILE */

		/* USER CODE BEGIN 3 */
	}
	/* USER CODE END 3 */
}
/**
 * @brief System Clock Configuration
 * @retval None
 */
void SystemClock_Config(void)	//v4.x.8
{
	RCC_OscInitTypeDef RCC_OscInitStruct = {0};
	RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
	RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
	/** Configure the main internal regulator output voltage
	*/
	__HAL_RCC_PWR_CLK_ENABLE();
	__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

	/** Initializes the RCC Oscillators according to the specified parameters
	 * in the RCC_OscInitTypeDef structure.
	 */
	RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_LSE;
	RCC_OscInitStruct.HSEState = RCC_HSE_ON;
	RCC_OscInitStruct.LSEState = RCC_LSE_ON;
	RCC_OscInitStruct.LSIState = RCC_LSI_ON;
	RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
	RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
	RCC_OscInitStruct.PLL.PLLM = 6;
	RCC_OscInitStruct.PLL.PLLN = 96;
	RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
	RCC_OscInitStruct.PLL.PLLQ = 4;
	RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
	if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
	{
		Error_Handler();
	}

	/** Initializes the CPU, AHB and APB buses clocks
	 */
	RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
	RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
	RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
	RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
	RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV4;

	if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3) != HAL_OK)
	{
		Error_Handler();
	}
	PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC;
	PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
	if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
	{
		Error_Handler();
	}
}
/* USER CODE BEGIN 4 */

/**
 * @brief Task function for Task 1.
 *
 * This function is the entry point for Task 1 in the FreeRTOS scheduler.
 * It contains the main loop for the task, where various operations are performed
 * based on the configuration and system state.
 *
 * @param argument: Task input argument (not used in this function).
 */
void StartTask1(void const *argument)
{
	char buff[200];
	///////V4.x.7 changes///////
	char Heartbeat_Interval = 0;		//V4.x.7
	int OCPP_Error_Interval = 0;
	///////////////////////////
	for (;;)
	{
//		char *buff;
//	  	buff = malloc(200 * sizeof(char));

		HAL_IWDG_Refresh(&hiwdg);		//uncomment
		////////////////////////V3.3.1///////////////////
		if (hard_reset == 1)
		{
			if (charger_status_G1.ocpp_status == Not_Connect)
			{
//				HMI_Send(0);
//				HAL_Delay(5000);
				NVIC_SystemReset(); 	//hard reset the system
			}
		}
		//////////////////////////////////////////////////
#if target == actype2
		if(charger_status_G1.charging_status != Unavailable_ChargerPoint)
		{
			AC_TYPE2();
		}
#else
		AC001();
#endif

		if ((ocpp_timer == 1) && (seq == 0))
		{
////////////////////////////////V4.x.7 changes/////////////////////
			if ((!ocpp_boot_status) && (OCPP.ocpp_status[0] == 1))//v4.x.7 change
			{
				if (++OCPP_Error_Interval > 300)
				{
					OCPP_Error_Interval = 0;
					change = 1;
				}
			}
			else
			{
				OCPP_Error_Interval = 0;
			}
			if (WaitForResponse == true)					//v4.x.7 change
			{
				if (++Heartbeat_Interval > (Ocpp_Setting.HeartbeatIntvl * 5))
				{
					Heartbeat_Interval = 0;
					WaitForResponse = false;
					change = 1;
				}
			}
			else
			{
				Heartbeat_Interval = 0;
			}
////////////////////////////////////////////////////

			//if (Ocpp_Setting.AllowOfflineTXUnknownId == 1)		//Add custom API GFD
			if (Ocpp_Setting.GroundFaultDetection == 1)
			{
				if (GFD_READ == 0)
				{
					if (powerfailure_flag == 5)	//v4.x.8
					{
						charger_status_G1.error = NoError; //fault
						powerfailure_flag = 0;
					}
				}
				else
				{
					if (charger_status_G1.voltage == 0)
					{
						//power failure
						charger_status_G1.error = PowerSwitchFailure; //fault
						charger_status_G1.reson = PowerLoss;
						powerfailure_flag = 5;
					}
					else
					{
						charger_status_G1.error = GroundFailure; //fault
					}
				}
			}
			else
			{
				if (charger_status_G1.voltage == 0)
				{
					//power failure
					charger_status_G1.error = PowerSwitchFailure; //fault
					charger_status_G1.reson = PowerLoss;
					powerfailure_flag = 5;
				}
				else
				{
					if (powerfailure_flag == 5)	//v4.x.8
					{
						charger_status_G1.error = NoError; //fault
						powerfailure_flag = 0;
					}
				}
			}
			if (websocket_success == 1)
			{
				if (ocpp_boot_status != Boot_Success)
				{
					ocpp_timer = 0;
					seq = 0;
					// goto ocpp;
				}
				else
				{
					Gun1_ocpp();
					ocpp_timer = 0;
					seq = 0;
				}
			}
			else
			{
				seq = 0;
				ocpp_timer = 0;
				if (Ocpp_Setting.Operative[1] == Available_ChargerPoint)
				{
					if (charger_status_G1.charging_status == SuspendedEVSE_ChargerPoint)
					{
						charger_status_G1.charging_status = Available_ChargerPoint;
					}
				}
#if target == ac001
				if (++charger_status_G1.timer > (Ocpp_Setting.MeterIntvl + 5))
				{
					if (charger_status_G1.power == 0)
					{
						if (charger_status_G1.start == Started)
						{
							charger_status_G1.stop = Try_To_Stop;
							charger_status_G1.reson = EVDisconnected;
							charger_status_G1.charging_status = SuspendedEV_ChargerPoint;
						}
					}
					charger_status_G1.timer = 0;
				}
#endif
			}

#if(multipyfact)
	if(meter1whclear == 0)
	{
		Energy_MeterRead(1);
	}
	else
	{
		Energy_MeterRead(4);
	}
#else
			if (meter1whclear == 0)
			{
				Energy_MeterRead(1);
			}
			else
			{
				Energy_MeterRead(4);
			}
//	Energy_MeterRead(1);
#endif

			OCPP_data();
		}
		if ((Local_List_Update == 1) && (flash_writing == 0))
		{
			Local_List_Update = 0;
			while (LocalListAdding) // == rfid_pointer.Added_rfid)
			{
				strcpy(rfid_data_to_flash.TagId, rfid_data.TagId[LocalListAdding]);
				strcpy(rfid_data_to_flash.expiery_time, rfid_data.expiery_time[LocalListAdding]);
				rfid_data_to_flash.status = rfid_data.status[LocalListAdding];
				Adding_Rfid();
				LocalListAdding--;
			}
			SRfid_pointer_write();
		}
		if (Ocpp_Setting.Operative[1] == Unavailable_ChargerPoint)
		{
			if (charger_status_G1.charging_status == Charging_ChargerPoint)
			{
				if (charger_status_G1.start == Started)
				{
					charger_status_G1.stop = Try_To_Stop;
					charger_status_G1.reson = Other;
					charger_status_G1.charging_status = SuspendedEVSE_ChargerPoint;
				}
			}
		}
		if (WIFI_Setting == 1)
		{
			change = 1;
			WIFI_Setting = 0;
		}
		if (recieve_complete == 1)
		{
			if (hmi_buffer[1] == 0x51)	//TBD
			{

			}
			else if (hmi_buffer[1] == 0x52)
			{
				int i = 0;
				for (i = 0; i < 8; i++)
				{
					/*if(hmi_buffer[i+2] >= 'a' &&  hmi_buffer[i+2] >= 'f')
					 {
					 tagid[i] = hmi_buffer[i+2]-32;
					 }
					 else */
					{
						tagid[i] = hmi_buffer[i + 2];
					}
				}

				tagid[i] = '\0';
#if target == ac001
				if (charger_status_G1.charging_status == Available_ChargerPoint)
				{
					charger_status_G1.start = Authenticate;
				}
#else
			 if(charger_status_G1.charging_status == Preparing_ChargerPoint)
			 {
				 charger_status_G1.start = Authenticate;
			 }
#endif
				else if (charger_status_G1.charging_status == Charging_ChargerPoint)
				{
					charger_status_G1.stop = Authenticate;
				}
				Type2_OCPP_Authorization_Flag = 1;

			}
			memset((unsigned char*) hmi_buffer, 0x00, sizeof(hmi_buffer));
			recieve_complete = 0;
		}
		if (recieve_complete_2 == 1)
		{
			if (inprocess == 0)
			{
				process_ReceiveArray();
			}
			recieve_complete_2 = 0;
		}

		/////////////added by Pooja - 30/06/2025////////////////
		if (Ocpp_Setting.stoptransinternetLoss == 0)
		{
			if (charger_status_G1.On_Going_Tx == Tx_Fail)
			{
				++charger_status_G1.timer;
				if (charger_status_G1.timer >= 1)
				{
					enQueue(G1_discharging_ocpp);
					enQueue(G1_MeterValue_End);
					charger_status_G1.timer = -15;
				}

			}
		}
		/////////////////////////////////////

		else if (req_network_select == 1 || GSMreq_network_select == 1)
		{
			if (Ocpp_Setting.stoptransinternetLoss == 0)
			{
				if (charger_status_G1.On_Going_Tx == Tx_Fail)
				{
					if (charger_status_G1.On_Going_Tx == Tx_Fail)
					{
						charger_status_G1.ocpp_status = StopTransaction_Req;
					}
				}
			}
			else
			{

				if (charger_status_G1.charging_status == Charging_ChargerPoint)
				{
					/////////////////V3.3.1////////////////
					if (charger_status_G1.start == Started)
					{
						charger_status_G1.charging_status = SuspendedEVSE_ChargerPoint;
						charger_status_G1.stop = Try_To_Stop;
					}
				}
				charger_status_G1.ocpp_status = Not_Connect;
			}
			/////
//(ac001smart)

			if (config_mode == 1)
			{
				if (config_mode_start == 1)
				{
					////////////////////////configuration mode start//////////////////////////////////
					int BuffIndex = 0;
					buff[BuffIndex++] = 0x02;	//START BYTE
					buff[BuffIndex++] = 0x70;//FRAME BYTE					//config mode start frame
					buff[BuffIndex++] = 0x00;	//SUB FRAEME BYTE
					buff[BuffIndex++] = 0x00;	//LENGH HIGH
					buff[BuffIndex++] = 0x01;	//LENGTH LOW
					buff[BuffIndex++] = 0x01; //OCPP ENABLE
					buff[BuffIndex++] = 0x03; //END BYTE
					HAL_UART_Transmit(&huart2, (uint8_t*) buff, BuffIndex, 0xffff);
					config_mode_start = 0;
					//////////////////////////////////////////////////////////////////////
				}
				req_network_select = 0;
			}
			else //(ac001smart)
			{
				if (OCPP.Communication_Mode == 2) //wifi)
						{
					if (wifi_connection_varify())
					{
						////////////////////////4G_PARAMETER//////////////////////////////////

						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++] = 0x96; //frame info firmware info //1
						fourGtxBuffer[fourgtxBufferIndex++] = 0x01; //sub frame  //2
						fourGtxBuffer[fourgtxBufferIndex++] = 0x01; //length high //3
						fourGtxBuffer[fourgtxBufferIndex++] = 0x01; //length Low  //4

						sprintf(buff, "%s%c%s%c", OCPP.wifi_ssid, 0x07, OCPP.wifi_password, 0x07);
						memcpy(&fourGtxBuffer[fourgtxBufferIndex], buff, 	strlen(buff)); //6 &7

						fourgtxBufferIndex += strlen(buff);
						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);
						// sprintf(buff,"wifi*%s%c%s%c",OCPP.wifi_ssid,0x07,OCPP.wifi_password,0x07);
						// HAL_UART_Transmit(&huart2, (uint8_t*)buff,strlen(buff),0xffff);

					}
				}
				else if (OCPP.Communication_Mode == 1)
				{
					if (GSMreq_network_select == 1)		 //V4.X.6
					{

						char lclarray[7];
						if (OCPP.ipselection == 0) //V4=1
						{
							lclarray[0] = 'I';
							lclarray[1] = 'P'; //v4
							lclarray[2] = '\0';

						}
						else if (OCPP.ipselection == 1) //V6=1
						{
							lclarray[0] = 'I';
							lclarray[1] = 'P';
							lclarray[2] = 'V';
							lclarray[3] = '6';
							lclarray[4] = '\0';
						}
						else if (OCPP.ipselection == 2) //V4V6=1
						{
							lclarray[0] = 'I';
							lclarray[1] = 'P';
							lclarray[2] = 'V';
							lclarray[3] = '4';
							lclarray[4] = 'V';
							lclarray[5] = '6';
							lclarray[6] = '\0';
						}

						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++] = 0x96; //frame info firmware info //1
						fourGtxBuffer[fourgtxBufferIndex++] = 0x01; //sub frame  //2
						fourGtxBuffer[fourgtxBufferIndex++] = 0x01; //length high //3
						fourGtxBuffer[fourgtxBufferIndex++] = 0x01; //length Low  //4

						sprintf(buff, "%s%c%s%c", OCPP.networkoperator, 0x07, lclarray, 0x07);

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

						fourgtxBufferIndex += strlen(buff);
						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);
						// sprintf(buff,"wifi*%s%c%s%c",OCPP.wifi_ssid,0x07,OCPP.wifi_password,0x07);
						// HAL_UART_Transmit(&huart2, (uint8_t*)buff,strlen(buff),0xffff);
						 GSMreq_network_select = 0;
					}
				}
				else if (OCPP.Communication_Mode == 3) //ethernet
				{
					//if(ether_connection_varify())
					{
						////////////////////////4G_PARAMETER//////////////////////////////////

						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++] = 0x9A; //frame info firmware info //1
						fourGtxBuffer[fourgtxBufferIndex++] = 0x01; //sub frame  //2
						fourGtxBuffer[fourgtxBufferIndex++] = 0x01; //length high //3
						fourGtxBuffer[fourgtxBufferIndex++] = 0x01; //length Low  //4

						//sprintf(buff,"%s%c%s%c",OCPP.wifi_ssid,0x07,OCPP.wifi_password,0x07);
						sprintf(buff, "%d.%d.%d.%d%c%d.%d.%d.%d%c%d.%d.%d.%d%c", OCPP.ether_ip[0], OCPP.ether_ip[1],
						OCPP.ether_ip[2], OCPP.ether_ip[3], 0x07, OCPP.ether_getway[0], OCPP.ether_getway[1],
						OCPP.ether_getway[2], OCPP.ether_getway[3], 0x07, OCPP.ether_subnetmask[0],
						OCPP.ether_subnetmask[1], OCPP.ether_subnetmask[2], OCPP.ether_subnetmask[3], 0x07);
						memcpy(&fourGtxBuffer[fourgtxBufferIndex], buff, strlen(buff)); //6 &7

						fourgtxBufferIndex += strlen(buff);
						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);
						// sprintf(buff,"wifi*%s%c%s%c",OCPP.wifi_ssid,0x07,OCPP.wifi_password,0x07);
						// HAL_UART_Transmit(&huart2, (uint8_t*)buff,strlen(buff),0xffff);
					}
				}
				else
				{
					//return 1;
				}
				req_network_select = 0;
			}
		}// else if(req_network_select==1 || GSMreq_network_select == 1) end here	//(ac001smart)

		else if (wifi_connected == 1)
		{
			////////////////////////4G_PARAMETER//////////////////////////////////

			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++] = 0x91; //frame info firmware info //1
			fourGtxBuffer[fourgtxBufferIndex++] = 0x01; //sub frame  //2
			fourGtxBuffer[fourgtxBufferIndex++] = 0x01; //length high //3
			fourGtxBuffer[fourgtxBufferIndex++] = 0x01; //length Low  //4

			sprintf(buff, "%s%c%s%c%s%c%s%c%s", OCPP.OCPP_servername, seperator, OCPP.OCPP_Port, seperator, OCPP.ocpp_uri, seperator,
					OCPP.OCPP_username, seperator, OCPP.OCPP_Password);
			memcpy(&fourGtxBuffer[fourgtxBufferIndex], buff, strlen_1(buff)); //6 &7

			fourgtxBufferIndex += strlen_1(buff);
			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);
			wifi_connected = 0;
			/////////////////////////////////////////////////////////////
		} else if (req_ocpp_status == 1)
		{
			////////////////////////4G_PARAMETER//////////////////////////////////
			int BuffIndex = 0;
			buff[BuffIndex++] = 0x02;   //START BYTE
			buff[BuffIndex++] = 0x92;   //FRAME BYTE
			buff[BuffIndex++] = 0x00;   //SUB FRAEME BYTE
			buff[BuffIndex++] = 0x00;   //LENGH HIGH
			buff[BuffIndex++] = 0x01;   //LENGTH LOW
			// sprintf(buff,"esp32_restart*");

			if (OCPP.ocpp_status[0] == 1)
			{
				buff[BuffIndex++] = 0x01; //OCPP ENABLE
			}
			else
			{
				buff[BuffIndex++] = 0x02; //OCPP DISABLE
			}
			buff[BuffIndex++] = 0x03; //END BYTE
			HAL_UART_Transmit(&huart2, (uint8_t*) buff, BuffIndex, 0xffff);
			req_ocpp_status = 0;
			//////////////////////////////////////////////////////////////////////
		}

		if (BootNotification_res == 1)
		{
			parse_BootNotification(Array1);

			BootNotification_res = 0;
		}
		if (RemoteStarttx_res == 1)
		{
			parse_remote_start_tx(Array1);
			RemoteStarttx_res = 0;
		}

		if (change == 1)
		{
			websocket_success = 0;
			HMI_websocket_disconnect = 1;
			HMI_wifi_disconnect = 1;
			wifi_status = 0;
			ocpp_boot_status = 0;

			////////////////////////4G_PARAMETER//////////////////////////////////
			int BuffIndex = 0;
			buff[BuffIndex++] = 0x02;
			buff[BuffIndex++] = 0x90;
			buff[BuffIndex++] = 0x00;
			buff[BuffIndex++] = 0x00;
			buff[BuffIndex++] = 0x01;
			buff[BuffIndex++] = 0x01;
			buff[BuffIndex++] = 0x03;
			// sprintf(buff,"esp32_restart*");
			HAL_UART_Transmit_DMA(&huart2, (uint8_t*) buff, BuffIndex);

			change = 0;
			//////////////////////////////////////////////
		}
		//ac001smart
		if (config_TXstruct == 1)
		{
			////////////////////////4G_PARAMETER//////////////////////////////////

			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++] = 0x72; //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], &form_data, sizeof(form_data)); //6 &7

			fourgtxBufferIndex += sizeof(form_data);

			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);
			/////////////////////////////////////////////////////////////

			config_TXstruct = 0;
		}
		if (config_RXstruct == 1)
		{
			OCPP.under_voltage = form_data.under_voltage;
			OCPP.over_voltage = form_data.over_voltage;
			OCPP.over_current = form_data.over_current;
			OCPP.STATE_A_LEVEL = form_data.STATE_A_LEVEL;
			OCPP.STATE_B_LEVEL = form_data.STATE_B_LEVEL;
			OCPP.STATE_C_LEVEL = form_data.STATE_C_LEVEL;
			OCPP.STATE_D_LEVEL = form_data.STATE_D_LEVEL;
			OCPP.auxinput = form_data.auxinput;
//				memcpy(&OCPP.Mob_Num,&form_data.Mob_Num,10);
//				memcpy(&OCPP.vendor_id,&form_data.vendor_id,10);
			memcpy(&OCPP.wifi_ssid, &form_data.wifi_ssid, 15);
			memcpy(&OCPP.wifi_password, &form_data.wifi_password, 15);
			memcpy(&OCPP.serial_no, &form_data.serial_no, 10);
			memcpy(&OCPP.networkoperator, &form_data.networkoperator, 20);
			memcpy(&OCPP.ocpp_uri, &form_data.ocpp_uri, 50);
			memcpy(&OCPP.OCPP_servername, &form_data.OCPP_servername, 30);
			memcpy(&OCPP.OCPP_username, &form_data.OCPP_username, 20);
			memcpy(&OCPP.OCPP_Password, &form_data.OCPP_Password, 20);
			memcpy(&OCPP.OCPP_Port, &form_data.OCPP_Port, 7);
			memcpy(&OCPP.fw_uri, &form_data.fw_uri, 30);
			memcpy(&OCPP.fw_servername, &form_data.fw_servername, 30);
			memcpy(&OCPP.fw_Port, &form_data.fw_Port, 5);

			OCPP.fw_status = (((form_data.fw_status[0] - '0') * 10)
					+ (form_data.fw_status[1] - '0'));

			if (form_data.ocpp_status[0] == '1') // || form_data.ocpp_status[1] == '1' )
			{
				OCPP.ocpp_status[0] = 1;
			}
			else
			{
				OCPP.ocpp_status[0] = 2;
			}

			OCPP.ipselection = (form_data.ipselection[0] - '0');

			ipStringToArray(form_data.ether_ip, global_conversion);
			OCPP.ether_ip[0] = (char) global_conversion[0];
			OCPP.ether_ip[1] = (char) global_conversion[1];
			OCPP.ether_ip[2] = (char) global_conversion[2];
			OCPP.ether_ip[3] = (char) global_conversion[3];

			global_conversion[0] = global_conversion[1] = global_conversion[2] = global_conversion[3] = 0;
			ipStringToArray(form_data.ether_getway, global_conversion);
			OCPP.ether_getway[0] = (char) global_conversion[0];
			OCPP.ether_getway[1] = (char) global_conversion[1];
			OCPP.ether_getway[2] = (char) global_conversion[2];
			OCPP.ether_getway[3] = (char) global_conversion[3];

			global_conversion[0] = global_conversion[1] = global_conversion[2] = global_conversion[3] = 0;
			ipStringToArray(form_data.ether_subnetmask, global_conversion);
			OCPP.ether_subnetmask[0] = (char) global_conversion[0];
			OCPP.ether_subnetmask[1] = (char) global_conversion[1];
			OCPP.ether_subnetmask[2] = (char) global_conversion[2];
			OCPP.ether_subnetmask[3] = (char) global_conversion[3];

			if (form_data.rfid1[0] != '\0')
			{
				rfid_pointer.Added_rfid = 0; //LocalListAdding;
				rfid_pointer.lastPointer = 3816 * 4096;

				strcpy(rfid_data_to_flash.TagId, form_data.rfid1);
				rfid_data_to_flash.status = 1;
				Adding_Rfid();

				strcpy(rfid_data_to_flash.TagId, form_data.rfid2);
				rfid_data_to_flash.status = 1;
				Adding_Rfid();

				strcpy(rfid_data_to_flash.TagId, form_data.rfid3);
				rfid_data_to_flash.status = 1;
				Adding_Rfid();

				SRfid_pointer_write();
			}
			if (((strcmp_1(form_data.ethernet_enable_sts, "wifi")) == 0) || (strcmp_1(form_data.ethernet_enable_sts, "WIFI") == 0))
			{
				GSM.gsm_enable_sts = 0;
				GSM.wifi_enable_sts = 1;
				GSM.ethernet_enable_sts = 0;
				OCPP.Communication_Mode = 2;
				OCPP.ocpp_status[0] = 1;		//OCPP enable
			}
			else if (((strcmp_1(form_data.ethernet_enable_sts, "gsm")) == 0) || (strcmp_1(form_data.ethernet_enable_sts, "GSM") == 0))
			{
				GSM.gsm_enable_sts = 1;
				GSM.wifi_enable_sts = 0;
				GSM.ethernet_enable_sts = 0;
				OCPP.Communication_Mode = 1;
				OCPP.ocpp_status[0] = 1;		//OCPP enable
			}
			else if (((strcmp_1(form_data.ethernet_enable_sts, "eth")) == 0) || (strcmp_1(form_data.ethernet_enable_sts, "ETH") == 0))
			{
				GSM.gsm_enable_sts = 0;
				GSM.wifi_enable_sts = 0;
				GSM.ethernet_enable_sts = 1;
				OCPP.Communication_Mode = 3;
				OCPP.ocpp_status[0] = 1;		//OCPP enable
			}
			else if (((strcmp_1(form_data.ethernet_enable_sts, "none")) == 0) || (strcmp_1(form_data.ethernet_enable_sts, "NONE") == 0))
			{
				GSM.gsm_enable_sts = 0;
				GSM.wifi_enable_sts = 1;
				GSM.ethernet_enable_sts = 0;
				OCPP.Communication_Mode = 2;
				OCPP.ocpp_status[0] = 2;		//OCPP disable
			}
			else
			{
				GSM.gsm_enable_sts = 0;
				GSM.wifi_enable_sts = 1;
				GSM.ethernet_enable_sts = 0;
				OCPP.Communication_Mode = 2;
				OCPP.ocpp_status[0] = 2;		//OCPP disable
			}
			write_para = 1;
			config_RXstruct = 0;
			rfid_sts_update = 1;
			logout = 1;

		} 			//ac001smart

//			 (OCPP.ipselection == 2);

		if (write_para == 1)
		{
			write_para = 0;
			Write_Params();
			HAL_Delay(100);
//				 Read_Params();
//				 HAL_Delay(100);
			if (fw_update == 1 && (OCPP.fw_status == 64))
			{
				hard_reset = 1;
				fw_update = 0;
			}
		}
		if ((erage_chip == 1) && (flash_writing == 0) && (byte_in != 0))
		{
			erage_chip = 0;
			if (chip_erase == 0)
			{
				//W25qxx_EraseChip();
				for (int i = 0; i < 3800; i++)
				{
					W25qxx_EraseSector(i);
					HAL_Delay(1);
					HAL_IWDG_Refresh(&hiwdg); //uncomment
				}
			}
			byte_in = 0;
			byte_out = 0;
			SFlash_pointer_write();
			if (flash_writing == 0)
			{
				Clear_Register = 71;
			}
		}
///////////////////////////////////////////////////////////////////////
		if ((Store_Key_Parameter == 1) && (flash_writing == 0))
		{
			Store_Key_Parameter = 0;
			Write_Key_Params();
		}
		if ((Clear_Register == 24 /* rfid_screen*/) && (flash_writing == 0))
		{
			Clear_Register = 0;
			uint8_t k;
			(rfid_pointer.Added_rfid >= 5) ? (k = 5) : (k = rfid_pointer.Added_rfid);

			for (uint8_t j = 1; j <= k; j++)
			{
				if (read_rfid_last_data(j) == 1)
				{
					strcpy(rfid_data.TagId[j], rfid_data_to_flash.TagId);
					rfid_data.status[j] = rfid_data_to_flash.status;
				}
			}
//			 enQueue_hmi(2402); //RFid
		}

		if (Type2_OCPP_Authorization_Flag)
		{
			Type2_OCPP_Authorization_Flag = 0;

			uint8_t status = 0;

			if ((ocpp_boot_status) && (OCPP.ocpp_status[0] == 1))
			{
				status = 3;
			}
			else if (Ocpp_Setting.LocalAuthOffln == 1)
			{
				if (rfid_pointer.Added_rfid <= 100)
				{
					for (int j = 1; j <= ((rfid_pointer.Added_rfid) + 1); j++)
					{
						if (read_rfid_last_data(j) == 1)
						{
							for (int i = 0; i < 10; i++)
							{
								if ((strcmp_1(tagid, rfid_data_to_flash.TagId)) == 0)
								{
									if (rfid_data_to_flash.status == 1)
									{
										Get_Time();
										status = expiry_calculation( DC001_OCPP_timestamp1, rfid_data_to_flash.expiery_time[i]);
										//status = 1;
									}
									break;
								}
							}
						}
						if (status == 1)
							break;
					}
				}
			}

			if (status == 1)
			{
				rfid_sts_update = 1;
#if target == ac001
				if (charger_status_G1.start == Authenticate)
				{
					strcpy(charger_status_G1.start_tagid, tagid);
					//charger_status_G1.Authentication_done = 1;
//					 correct_rfid = 1;
					charger_status_G1.start = Try_To_Start;
					charger_status_G1.reson = Local;
				}
#else
			  if(charger_status_G1.start == Authenticate)
			 {
				 strcpy(charger_status_G1.start_tagid,tagid);
				 charger_status_G1.reson = Local;
				 //charger_status_G2.start = Try_To_Start;;
				 charger_status_G1.Authentication_done = 1;

			 }
#endif
				else if (charger_status_G1.stop == Authenticate)
				{
					if (strcmp_1(charger_status_G1.start_tagid, tagid) == 0)
					{
						strcpy(charger_status_G1.start_tagid, tagid);
						charger_status_G1.stop = Try_To_Stop;
						charger_status_G1.reson = Local;
//					    correct_rfid = 1;
						charger_status_G1.charging_status = Finishing_ChargerPoint;
					}
					else
					{
						rfid_sts_update = 2;
					}
				}
			}
			else if (status == 3)
			{
				rfid_sts_update = 1;
				//	 #if target == ac001
//			 			  if(charger_status_G1.start == Authenticate)
//			 				 {
//			 					 strcpy(charger_status_G1.start_tagid,tagid);
//			 					 //charger_status_G1.Authentication_done = 1;
//			 //					 correct_rfid = 1;
//			 					charger_status_G1.start = Try_To_Start;
//			 					charger_status_G1.reson = Local;
//			 				 }
//			 #else
				if (charger_status_G1.start == Authenticate)
				{
					strcpy(charger_status_G1.start_tagid, tagid);
					charger_status_G1.reson = Local;
					if (Ocpp_Setting.LocalPreAuth == false)
					{
						charger_status_G1.ocpp_status = Authorise_Req;
					}
//			 				 charger_status_G1.start = Try_To_Start;
					//charger_status_G1.Authentication_done = 1;

				}
//			 #endif
				else if (charger_status_G1.stop == Authenticate)
				{

					if (strcmp_1(charger_status_G1.start_tagid, tagid) == 0)
					{

						charger_status_G1.stop = Try_To_Stop;
						strcpy(charger_status_G1.start_tagid, tagid);
						charger_status_G1.reson = Local;
						//					   correct_rfid = 1;
						charger_status_G1.charging_status =
								Finishing_ChargerPoint;
					}
					else
					{
						rfid_sts_update = 2;
					}
				}
			}
			else
			{
				rfid_sts_update = 2;
				//incorrect_rfid =1;
			}
		}

//
		if ((huart3.gState != HAL_UART_STATE_BUSY_TX))
		{
			send_data_g070();
		}
//	       	  free(buff);
//	       	  buff = NULL;
/////////////////////////////////////////////////////////////////////////
	}
}

/**
 * @brief Handle OCPP operations for Gun 1.
 *
 * This function is responsible for managing OCPP-related operations for Gun 1,
 * such as authorization, starting and stopping transactions, and handling OCPP statuses.
 *
 * @return none.
 * @retval G_charging: Gun 1 is currently charging.
 * @retval G_idle: Gun 1 is idle.
 *
 * @note This function assumes the availability of certain global variables and configurations.
 *       Make sure to set up the required variables and configurations before calling this function.
 */
char Gun1_ocpp(void)
{
	if (charger_status_G1.ocpp_status == Authorise_Req)
	{

		++charger_status_G1.timer;
		if (charger_status_G1.timer > 1)
		{
			enQueue(G1_Authorise_EVSE);
			charger_status_G1.timer = -15;
		}
	}
	else if (charger_status_G1.ocpp_status == StartTransaction_Req)
	{
		//G1 send start transaction
		++charger_status_G1.timer;
		if (charger_status_G1.timer > 0)
		{
			enQueue(G1_StartCharging_EVSE);
			charger_status_G1.timer = -15;
		}
	}
	else if (charger_status_G1.ocpp_status == Current_Demand)
	{
		if (++charger_status_G1.timer == 1)
		{
			enQueue(G1_StatusNotification);
		}
#if defined(ocpp_mod)
	   else if(charger_status_G1.timer == 2)
	   {
		  enQueue(G1_MeterValue_Began);
	   }
#endif
		else if (charger_status_G1.timer > (Ocpp_Setting.MeterIntvl + 5))
		{
#if target == ac001
			if (charger_status_G1.power == 0)
			{
				if (charger_status_G1.start == Started)
				{
					charger_status_G1.stop = Try_To_Stop;
					charger_status_G1.reson = EVDisconnected;
					charger_status_G1.charging_status =
							SuspendedEV_ChargerPoint;
				}
			}
#endif
			enQueue(G1_MeterValue_Periodic);
			charger_status_G1.timer = 5;
		}
	}
	else if (charger_status_G1.ocpp_status == StopTransaction_Req)
	{
		//G1 send stop transaction
		++charger_status_G1.timer;
		if (charger_status_G1.timer >= 1)
		{
			enQueue(G1_StopCharging_EVSE);
#if defined(ocpp_mod)
		  enQueue(G1_MeterValue_End);
#endif
			charger_status_G1.timer = -15;
		}
	}
	else if (charger_status_G1.ocpp_status == StopTransaction_Success)
	{
		//G1 finish send notification
		charger_status_G1.ocpp_status = Not_Connect;
		//charger_status_G1.charging_status = Finishing_ChargerPoint;
		charger_status_G1.On_Going_Tx = Tx_Success;
		enQueue(G1_StatusNotification);
		charger_status_G1.timer = Ocpp_Setting.StatusDuration;
	}
	else if (charger_status_G1.ocpp_status == Not_Connect || charger_status_G1.ocpp_status == Boot_Success)
	{
		++charger_status_G1.timer;
		charger_status_G1.Clock_Align_Timer++;
		if (charger_status_G1.timer > Ocpp_Setting.StatusDuration)
		{
			if (charger_status_G1.charging_status == SuspendedEVSE_ChargerPoint || charger_status_G1.charging_status == Finishing_ChargerPoint
			|| charger_status_G1.charging_status == SuspendedEV_ChargerPoint || charger_status_G1.charging_status == Available_ChargerPoint)
			{
				if (Ocpp_Setting.Operative[1] == Available_ChargerPoint)
				{
					charger_status_G1.charging_status = Available_ChargerPoint;
				}
				else if (Ocpp_Setting.Operative[1] == Unavailable_ChargerPoint)
				{
					charger_status_G1.charging_status = Unavailable_ChargerPoint;
				}
			}
			if (Ocpp_Setting.StatusDuration != 0)		//ocpp_mod
			{
				enQueue(G1_StatusNotification);
			}
			charger_status_G1.timer = 0;
		}
		else if (charger_status_G1.Clock_Align_Timer >= Ocpp_Setting.ClkAlgnIntvl) {
			if (Ocpp_Setting.ClkAlgnIntvl != 0)
			{
				enQueue(G1_MeterValue_ClockAlign);
			}
			charger_status_G1.Clock_Align_Timer = 0;
		}
	}

	if (charger_status_G1.ocpp_status == Authorise_Success)
	{
//		gun_1 =G_charging;

#if target == actype2
		rfid_sts_update = 1;	//send notification
		   charger_status_G1.Authentication_done =1;

#else
//			charger_status_G1.start= Started;
		rfid_sts_update = 1;	//send notification
		charger_status_G1.start = Try_To_Start;
//		HAL_GPIO_WritePin(RELAY_G1_GPIO_Port,RELAY_G1_Pin,GPIO_PIN_RESET); //ON
//		charger_status_G1.charging_status = Charging_ChargerPoint;
//		charger_status_G1.ocpp_status = StartTransaction_Req;
#endif

		charger_status_G1.Retries = 0;
	}
	else if (charger_status_G1.ocpp_status == StartTransaction_Success)
	{
		charger_status_G1.ocpp_status = Current_Demand;
		charger_status_G1.Retries = 0;
		charger_status_G1.On_Going_Tx = Tx_Pending;
	}
	else if ((charger_status_G1.ocpp_status == Authorise_Fail) || (charger_status_G1.ocpp_status == StartTransaction_Fail))
	{

		if (++charger_status_G1.Retries < Ocpp_Setting.FailedAttempt) //V4.
		{
			if (charger_status_G1.ocpp_status == StartTransaction_Fail)
			{
				charger_status_G1.ocpp_status = StartTransaction_Req;
			}
			else if (charger_status_G1.ocpp_status == Authorise_Fail)
			{
				rfid_sts_update = 3;	//send notification
				charger_status_G1.ocpp_status = Authorise_Req;
			}
		}
		else
		{
			charger_status_G1.ocpp_status = Not_Connect;		//ac001smart
			if (charger_status_G1.start == Started)
			{
				charger_status_G1.stop = Stoped;
				charger_status_G1.start = Stoped;
				charger_status_G1.charging_status = Available_ChargerPoint;	//V5.0.0 change
			}
			charger_status_G1.Retries = 0;
		}
	}
}

#if target == ac001
/**
 * @brief Manages the AC001 charging process for multiple guns.
 *
 * It checks the start and stop conditions for each gun, updates charging status,
 * enqueues relevant events, and performs necessary actions based on the OCPP status.
 *
 * @note This function assumes the availability of specific constants, structures,
 *       GPIO pins, and various OCPP settings such as charger_status_G1, G_charging, etc.
 *
 * @note The behavior of this function is tailored for AC001 charging stations.
 *       Different gun numbers (e.g., G1) are managed separately based on conditions.
 *
 * @warning Ensure proper configuration of GPIO pins and OCPP settings for accurate functionality.
 *
 * @param NA
 * @return NA
 */
void AC001(void)
{
	if ((charger_status_G1.start == Try_To_Start) && (charger_status_G1.error == NoError_ChargerPoint))
	{
		charger_status_G1.charging_time = 0;
		charger_status_G1.Bill_Amount = 0;
		Get_Time();

		strcpy(charger_status_G1.start_time, DC001_OCPP_timestamp1);
		if (((charger_status_G1.reson == Remote) || (Ocpp_Setting.LocalPreAuth == true)) || (charger_status_G1.ocpp_status == Authorise_Success))
		{
			charger_status_G1.ocpp_status = StartTransaction_Req;
			charger_status_G1.charging_status = Charging_ChargerPoint;
			HAL_GPIO_WritePin(RELAY_G1_GPIO_Port, RELAY_G1_Pin, GPIO_PIN_RESET); //ON
		}

		else if (Ocpp_Setting.LocalPreAuth == false)
		{
			charger_status_G1.ocpp_status = Authorise_Req;
		}
		charger_status_G1.start_energy = energy;
		charger_status_G1.timer = 0;
		charger_status_G1.start = Started;

		if (OCPP.ocpp_status[0] == 1)
		{

		}
		else if (Ocpp_Setting.LocalAuthOffln == true)
		{
			charger_status_G1.charging_status = Charging_ChargerPoint;
			HAL_GPIO_WritePin(RELAY_G1_GPIO_Port, RELAY_G1_Pin, GPIO_PIN_RESET); //ON
		}
	}

////////////////////////////////////////////////////////////////////////////////////////////
	if ((charger_status_G1.start == Started) && ((charger_status_G1.stop == Error) || (charger_status_G1.stop == Try_To_Stop)))
	{

		Get_Time();
		strcpy(charger_status_G1.stop_time, DC001_OCPP_timestamp1);
		charger_status_G1.timer = 0;
		if ((websocket_success == 0) && (charger_status_G1.On_Going_Tx == Tx_Pending))
		{
			charger_status_G1.On_Going_Tx = Tx_Fail;
			charger_status_G1.charging_status = Available_ChargerPoint; //V4.1.3
		}
		charger_status_G1.ocpp_status = StopTransaction_Req;
		charger_status_G1.stop_energy = energy;

		if (OCPP.ocpp_status[0] == 2)		//DIS
		{
			charger_status_G1.charging_status = Available_ChargerPoint; //V4.1.3
			Billing(1);
//					Clear_Register =19;
		}
		else
		{

			if (Cash_Memory.counter > 9)
			{
				Cash_Memory.counter = 0;
			}

			Cash_Memory.Metervalue[Cash_Memory.counter] = charger_status_G1.stop_energy;
			Cash_Memory.transaction_id[Cash_Memory.counter] = charger_status_G1.transaction_id;
			Cash_Memory.Reson[Cash_Memory.counter] = charger_status_G1.reson;
			strcpy(Cash_Memory.StopTxTime[Cash_Memory.counter], charger_status_G1.stop_time);
			strcpy(Cash_Memory.Tag_Id[Cash_Memory.counter], charger_status_G1.start_tagid);
			Cash_Memory.counter++;
			Write_CACH_Params();
		}

		charger_status_G1.stop = Stoped;
		charger_status_G1.start = Stoped;

		s6_counter1 = 0;
		update_variable = 1;
		//  charger_status_G1.stop = Stoped;
		charger_status_G1.charging_status = Available_ChargerPoint;  //V4.1.3
		HAL_GPIO_WritePin(RELAY_G1_GPIO_Port, RELAY_G1_Pin, GPIO_PIN_SET); //OFF
		HAL_GPIO_WritePin(RELAY_G1_GPIO_Port, RELAY_G1_Pin, GPIO_PIN_SET); //OFF

	}

}
#else
/**
  * @brief Manages the AC_TYPE2 charging process for gun 1.
  *
  * This function handles the AC_TYPE2 charging process for gun 1.
  * It adjusts charging status, updates timers, handles authorizations,
  * and performs necessary actions based on the current state and OCPP status.
  *
  * @note This function assumes the availability of specific constants, structures,
  *       GPIO pins, and various OCPP settings such as charger_status_G1, G_charging, etc.
  *
  * @note The behavior of this function is tailored for AC_TYPE2 charging stations,
  *       focusing on gun 1. Different states (STATE_A, STATE_B, STATE_C, STATE_D) are managed accordingly.
  *
  * @warning Ensure proper configuration of GPIO pins and OCPP settings for accurate functionality.
  */
void AC_TYPE2(void)
{
 if(CURRENT_STATE==STATE_A)
	{
		//stop_pwm();
	 	PWM_stop_flag =1;
		if(charger_status_G1.charging_status == Charging_ChargerPoint)
		{
			charger_status_G1.stop = Try_To_Stop;
			charger_status_G1.charging_status =SuspendedEV_ChargerPoint;
		}
		else if(charger_status_G1.charging_status != Faulted_ChargerPoint)
		{
			if(charger_status_G1.charging_status != Available_ChargerPoint )
			{
//				gun_1 = G_NoError;
				charger_status_G1.timer = Ocpp_Setting.StatusDuration;
				enQueue(G1_StatusNotification);
			}

			//charger_status_G1.ocpp_status = Not_Connect;
			charger_status_G1.charging_status = Available_ChargerPoint;
			charger_status_G1.reson= Other;
			charger_status_G1.stop = Stoped;
			charger_status_G1.start = Stoped;
			charger_status_G1.Authentication_done = 0;
		}
		HAL_GPIO_WritePin(RELAY_G1_GPIO_Port,RELAY_G1_Pin,GPIO_PIN_SET); //ON
		HAL_GPIO_WritePin(RELAY_G1_GPIO_Port,RELAY_G1_Pin,GPIO_PIN_SET); //ON
	}
	else if(CURRENT_STATE==STATE_B)
	{
		if(charger_status_G1.Authentication_done && charger_status_G1.error == NoError_ChargerPoint )
		{
				start_pwm();
//				charger_status_G1.timer = 0;
		}
		else
		{
	//		stop_pwm();
			PWM_stop_flag =1;
			if(charger_status_G1.charging_status == Charging_ChargerPoint)
			{
				if(charger_status_G1.start == Started)
				{
					charger_status_G1.stop = Try_To_Stop;
					charger_status_G1.charging_status = SuspendedEV_ChargerPoint;
					charger_status_G1.timer = Ocpp_Setting.StatusDuration;
					charger_status_G1.reson = EVDisconnected;
					enQueue(G1_StatusNotification);
//					gun_1 = G_Discharging;
				}
			}
			else if(charger_status_G1.charging_status == Available_ChargerPoint)
			{
				charger_status_G1.charging_status = Preparing_ChargerPoint;
				charger_status_G1.reson= Other;
				charger_status_G1.timer = Ocpp_Setting.StatusDuration;
				enQueue(G1_StatusNotification);
//				gun_1 = G_connected;
			}
		}
		HAL_GPIO_WritePin(RELAY_G1_GPIO_Port,RELAY_G1_Pin,GPIO_PIN_SET);
		HAL_GPIO_WritePin(RELAY_G1_GPIO_Port,RELAY_G1_Pin,GPIO_PIN_SET);
	}
	else if((CURRENT_STATE==STATE_C)||(CURRENT_STATE==STATE_D)) // && (Type2_OCPP_Authorization_Flag == 1))
	{

		if(charger_status_G1.Authentication_done)
		{
			charger_status_G1.Authentication_done = 0;
			start_pwm();
			charger_status_G1.start = Try_To_Start;
		}
	}
 ///////////////////////////////////GUN1/////////////////////////////////////////////////
	if((charger_status_G1.start == Try_To_Start) && (charger_status_G1.error == NoError_ChargerPoint))
	{

		charger_status_G1.charging_time = 0;
		charger_status_G1.Bill_Amount =0;
		charger_status_G1.start = Started;
		Get_Time();
		strcpy(charger_status_G1.start_time,DC001_OCPP_timestamp1);


		charger_status_G1.start_energy = energy;
		charger_status_G1.timer = 0;

		if(OCPP.ocpp_status[0] == 1)
		{

		}
		else if(Ocpp_Setting.LocalAuthOffln == true)
		{
//			gun_1 =G_charging;
			charger_status_G1.charging_status =  Charging_ChargerPoint;
			HAL_GPIO_WritePin(RELAY_G1_GPIO_Port,RELAY_G1_Pin,GPIO_PIN_RESET); //ON
			HAL_GPIO_WritePin(RELAY_G1_GPIO_Port,RELAY_G1_Pin,GPIO_PIN_RESET); //ON
			return;
		}

		if((charger_status_G1.reson == Remote) || (Ocpp_Setting.LocalPreAuth == true))
			{
				charger_status_G1.ocpp_status= StartTransaction_Req;
	//			gun_1 =G_charging;
				charger_status_G1.charging_status= Charging_ChargerPoint;

				HAL_GPIO_WritePin(RELAY_G1_GPIO_Port,RELAY_G1_Pin,GPIO_PIN_RESET); //ON
				HAL_GPIO_WritePin(RELAY_G1_GPIO_Port,RELAY_G1_Pin,GPIO_PIN_RESET); //ON
			}
			else if(Ocpp_Setting.LocalPreAuth == false)
			{
	//			charger_status_G1.ocpp_status= Authorise_Req;
				charger_status_G1.charging_status = Charging_ChargerPoint;
				charger_status_G1.ocpp_status = StartTransaction_Req;
				HAL_GPIO_WritePin(RELAY_G1_GPIO_Port,RELAY_G1_Pin,GPIO_PIN_RESET); //ON
			}
	}
 ////////
 ////////////////////////////////////////////////////////////////gun1 ///////////////////////////


	if((charger_status_G1.start == Started )  && ((charger_status_G1.stop == Error) || (charger_status_G1.stop == Try_To_Stop) ))
		  {
		  Get_Time();
		  PWM_stop_flag =1;
		  strcpy(charger_status_G1.stop_time,DC001_OCPP_timestamp1);
		  update_variable = 1;
		  charger_status_G1.timer =0;
		  charger_status_G1.ocpp_status= StopTransaction_Req;
		  s6_counter1 = 0;

		  if((websocket_success == 0) && (charger_status_G1.On_Going_Tx == Tx_Pending))
		  {
			  charger_status_G1.On_Going_Tx = Tx_Fail;
			  charger_status_G1.charging_status =  Available_ChargerPoint;  //V4.1.1
			  Ocpp_Setting.stoptransinternetLoss = 0;		// added by Pooja
		  }
		  charger_status_G1.stop_energy = energy;
		  if(OCPP.ocpp_status[0] == 0 || OCPP.ocpp_status[0] == 2)	//DISABLE
			{
				charger_status_G1.charging_status =  Available_ChargerPoint;  //V4.1.1
				Billing(1);
				Clear_Register =19;
			}
		  else
		  {
//			  Total_time = charger_status_G1.charging_time;   //V4.1.1
//			  Total_cost = charger_status_G1.Bill_Amount;
//			  Total_unit = charger_status_G1.stop_energy - charger_status_G1.start_energy;
//			  Clear_Register =19;
			  if(Cash_Memory.counter > 9)
			  {
				  Cash_Memory.counter = 0;
			  }

			  Cash_Memory.Metervalue[Cash_Memory.counter] = charger_status_G1.stop_energy;
			  Cash_Memory.Reson[Cash_Memory.counter] = charger_status_G1.reson;
			  Cash_Memory.transaction_id[Cash_Memory.counter] = charger_status_G1.transaction_id;
			  strcpy(Cash_Memory.StopTxTime[Cash_Memory.counter],charger_status_G1.stop_time);
			  strcpy(Cash_Memory.Tag_Id[Cash_Memory.counter],charger_status_G1.start_tagid);
			  Cash_Memory.counter++;
			  Write_CACH_Params();
		  }

		  charger_status_G1.start = Stoped;
		  charger_status_G1.stop = Stoped;
//		  gun_1 = G_Discharging;
		  HAL_GPIO_WritePin(RELAY_G1_GPIO_Port,RELAY_G1_Pin,GPIO_PIN_SET); //OFF
		  HAL_GPIO_WritePin(RELAY_G1_GPIO_Port,RELAY_G1_Pin,GPIO_PIN_SET); //OFF
	  }

	  /////////////////////////////////////////////////////////////
}

/**
  * @brief Performs ADC check and updates the charging state based on the ADC value.
  *
  * This function checks the ADC value (cp_val) and updates the charging state
  * (CURRENT_STATE) based on predefined levels for STATE_A, STATE_B, STATE_C, and STATE_D.
  * It counts occurrences of ADC values falling within specified ranges and switches the state accordingly.
  *
  * @note This function relies on the proper initialization of the ADC and specific settings
  *       such as adc_init, OCPP.STATE_A_LEVEL, OCPP.STATE_B_LEVEL, OCPP.STATE_C_LEVEL, OCPP.STATE_D_LEVEL,
  *       Ocpp_Setting.offset, Ocpp_Setting.count, update_CP_Count, pwm_start_stop, and cpchange.
  *
  * @note The counting mechanism helps prevent transient fluctuations in ADC values from affecting state transitions.
  *
  * @note The function also checks if a special update condition (update_CP_Count == 1) is met,
  *       allowing for a one-time state update based on the ADC value.
  *
  * @warning Ensure proper configuration of ADC, OCPP settings, and related parameters for accurate functionality.
  *
  * @param NA
  * @return NA
  */
void adc_check()
{
	// @every 100 ms

	 if(adc_init==0)return;

if(update_CP_Count == 1)
{

	  HAL_ADC_Start_DMA(&hadc1,adc1_dat,1);
     cp_val=adc1_dat[0]; //3081
     hmicp_val=cp_val;

  if((cp_val<=OCPP.STATE_A_LEVEL+Ocpp_Setting.offset)&&(cp_val>=OCPP.STATE_A_LEVEL-Ocpp_Setting.offset))
		{
		  count_D = 0;
		  count_B = 0;
		  count_C = 0;
		  if(++count_A > Ocpp_Setting.count)
		  {
			CURRENT_STATE=STATE_A;
			count_A = 0;
		  }
		}
		else if((cp_val<=OCPP.STATE_B_LEVEL+Ocpp_Setting.offset)&&(cp_val>=OCPP.STATE_B_LEVEL-Ocpp_Setting.offset))
		{
			count_D = 0;
			count_C = 0;
			count_A = 0;
			if(++count_B > Ocpp_Setting.count)
			{
				CURRENT_STATE=STATE_B;
				count_B = 0;
			}
		}
		else if((cp_val<=OCPP.STATE_C_LEVEL+Ocpp_Setting.offset)&&(cp_val>=OCPP.STATE_C_LEVEL-Ocpp_Setting.offset))
		{
			count_D = 0;
			count_B = 0;
			count_A = 0;
			if(++count_C > Ocpp_Setting.count)
			  {
				CURRENT_STATE=STATE_C;
				count_C = 0;
			  }
		}
		else if((cp_val<=OCPP.STATE_D_LEVEL+Ocpp_Setting.offset)&&(cp_val>=OCPP.STATE_D_LEVEL-Ocpp_Setting.offset))
		{
			count_C = 0;
			count_B = 0;
			count_A = 0;
			if(++count_D > Ocpp_Setting.count)
			  {
				CURRENT_STATE=STATE_D;
				count_D = 0;
			  }
		}
		else
		{
			count_D = 0;
			count_C = 0;
			count_B = 0;
			count_A = 0;
		}
  update_CP_Count =0;
}

//V501change
#if cpchange == no
      if(pwm_start_stop ==1)
      {
    	  if((cp_val<=STATE_A_LEVEL_1+100)&&(cp_val>=STATE_A_LEVEL_1-100))
    		{
    		  count_D = 0;
    		  count_B = 0;
    		  count_C = 0;
    		  if(++count_A > 5)
    		  {
    			CURRENT_STATE=STATE_A;
    			count_A = 0;
    		  }
    		}
    		else if((cp_val<=STATE_B_LEVEL_1+100)&&(cp_val>=STATE_B_LEVEL_1-100))
    		{
    			count_D = 0;
    			count_C = 0;
    			count_A = 0;
    			if(++count_B > 5)
    			{
    				CURRENT_STATE=STATE_B;
    				count_B = 0;
    			}
    		}
    		else if((cp_val<=STATE_C_LEVEL_1+100)&&(cp_val>=STATE_C_LEVEL_1-100))
    		{
    			count_D = 0;
    			count_B = 0;
    			count_A = 0;
    			if(++count_C > 5)
    			  {
    				CURRENT_STATE=STATE_C;
    				count_C = 0;
    			  }
    		}
    		else if((cp_val<=STATE_D_LEVEL_1+100)&&(cp_val>=STATE_D_LEVEL_1-100))
    		{
    			count_C = 0;
    			count_B = 0;
    			count_A = 0;
    			if(++count_D > 5)
    			  {
    				CURRENT_STATE=STATE_D;
    				count_D = 0;
    			  }
    		}
      }
      else
      {
    	  if((cp_val<=STATE_A_LEVEL+100)&&(cp_val>=STATE_A_LEVEL-100))
    		{
    		  count_D = 0;
    		  count_B = 0;
    		  count_C = 0;
    		  if(++count_A > 5)
    		  {
    			CURRENT_STATE=STATE_A;
    			count_A = 0;
    		  }
    		}
    		else if((cp_val<=STATE_B_LEVEL+100)&&(cp_val>=STATE_B_LEVEL-100))
    		{
    			count_D = 0;
    			count_C = 0;
    			count_A = 0;
    			if(++count_B > 5)
    			{
    				CURRENT_STATE=STATE_B;
    				count_B = 0;
    			}
    		}
    		else if((cp_val<=STATE_C_LEVEL+100)&&(cp_val>=STATE_C_LEVEL-100))
    		{
    			count_D = 0;
    			count_B = 0;
    			count_A = 0;
    			if(++count_C > 5)
    			  {
    				CURRENT_STATE=STATE_C;
    				count_C = 0;
    			  }
    		}
    		else if((cp_val<=STATE_D_LEVEL+100)&&(cp_val>=STATE_D_LEVEL-100))
    		{
    			count_C = 0;
    			count_B = 0;
    			count_A = 0;
    			if(++count_D > 5)
    			  {
    				CURRENT_STATE=STATE_D;
    				count_D = 0;
    			  }
    		}
      }
#endif
}

#endif

/**
 * @brief Callback function for GPIO external interrupts.
 * @param GPIO_Pin: The pin number that triggered the interrupt.
 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{

}
/**
 * @brief Handles billing information for a charging station.
 *
 * This function processes billing information for a specific charging gun.
 *
 * @param gun The charging gun number (1, 2, 3, etc.).
 */

void Billing(char gun)
{
	char *ptr, *ptr2;
	char save_ok = 0;
	uint32_t last_data_in = 0;
	char failed_attempt = 0;

	ptr = &data_to_flash.start;
	memset(ptr, '\0', sizeof(data_to_flash));

	if (gun == 1)
	{
		if (charger_status_G1.stop == Error)
		{
			strcpy(data_to_flash.ocpp_status, "Fail");
		}
		else
		{
			strcpy(data_to_flash.ocpp_status, "Success");
		}

		charger_status_G1.stop = Stoped;
		//	charger_status_G1.charging_status = SuspendedEV_ChargerPoint;
		data_to_flash.gn_no[0] = '1';
		data_to_flash.gn_no[1] = ' ';
		//snprintf(data_to_flash.gn_no,2,"%u",1);

		if (charger_status_G1.Bill_Amount < 99)
		{
			//snprintf(data_to_flash.Bill_Amount,4,"%u",charger_status_G1.Bill_Amount);
			data_to_flash.Bill_Amount[0] = (uint8_t) ((charger_status_G1.Bill_Amount % 100 / 10) + '0');
			data_to_flash.Bill_Amount[1] = (uint8_t) (charger_status_G1.Bill_Amount % 10 + '0');
			data_to_flash.Bill_Amount[2] = ' ';
			data_to_flash.Bill_Amount[3] = ' ';
		}
		else if (charger_status_G1.Bill_Amount < 999)
		{
			//snprintf(data_to_flash.Bill_Amount,4,"%u",charger_status_G1.Bill_Amount);
			data_to_flash.Bill_Amount[0] = 	(uint8_t) ((charger_status_G1.Bill_Amount % 1000 / 100) + '0');
			data_to_flash.Bill_Amount[1] = (uint8_t) ((charger_status_G1.Bill_Amount % 100 / 10) + '0');
			data_to_flash.Bill_Amount[2] = (charger_status_G1.Bill_Amount % 10 + '0');
			data_to_flash.Bill_Amount[3] = ' ';
		}
		else
		{
			data_to_flash.Bill_Amount[0] = (uint8_t) ((charger_status_G1.Bill_Amount % 10000 / 1000) + '0');
			data_to_flash.Bill_Amount[1] = (uint8_t) ((charger_status_G1.Bill_Amount % 1000 / 100) + '0');
			data_to_flash.Bill_Amount[2] = (uint8_t) ((charger_status_G1.Bill_Amount % 100 / 10) + '0');
			data_to_flash.Bill_Amount[3] = (charger_status_G1.Bill_Amount % 10 + '0');
		}

		//snprintf(data_to_flash.Bill_Amount,4,"%u",charger_status_G1.Bill_Amount);
		strncpy(data_to_flash.start_time, charger_status_G1.start_time, 18);
		strncpy(data_to_flash.stop_time, charger_status_G1.stop_time, 18);
		strncpy(data_to_flash.tagid, charger_status_G1.start_tagid, 12);

		if (charger_status_G1.charging_time < 99)
		{
			//snprintf(data_to_flash.Bill_Amount,4,"%u",charger_status_G1.Bill_Amount);
			data_to_flash.Total_time[0] = (uint8_t) ((charger_status_G1.charging_time % 100 / 10) + '0');
			data_to_flash.Total_time[1] = (uint8_t) (charger_status_G1.charging_time % 10 + '0');
			data_to_flash.Total_time[2] = ' ';
			data_to_flash.Total_time[3] = ' ';
		}
		else if (charger_status_G1.charging_time < 999)
		{
			//snprintf(data_to_flash.Bill_Amount,4,"%u",charger_status_G1.Bill_Amount);
			data_to_flash.Total_time[0] = (uint8_t) ((charger_status_G1.charging_time % 1000 / 100) + '0');
			data_to_flash.Total_time[1] = (uint8_t) ((charger_status_G1.charging_time % 100 / 10) + '0');
			data_to_flash.Total_time[2] = (uint8_t) (charger_status_G1.charging_time % 10 + '0');
			data_to_flash.Total_time[3] = ' ';
		}
		else
		{
			data_to_flash.Total_time[0] = (uint8_t) ((charger_status_G1.charging_time % 10000 / 1000) + '0');
			data_to_flash.Total_time[1] = (uint8_t) ((charger_status_G1.charging_time % 1000 / 100) + '0');
			data_to_flash.Total_time[2] = (uint8_t) ((charger_status_G1.charging_time % 100 / 10) + '0');
			data_to_flash.Total_time[3] = (charger_status_G1.charging_time % 10 + '0');
		}

//		sprintf(data_to_flash.Total_time,"%u",charger_status_G1.charging_time);

	}
	//charger_status.Bill_Amount = (Total_unit*OCPP.energy_charges)/1000;
	//Total_cost = charger_status.Bill_Amount;
	//charger_status.Bill_Amount = charger_status.Bill_Amount + (time_charges *Total_time);

	data_to_flash.start = '$';

	data_to_flash.crc = CRC16(&data_to_flash.start, (sizeof(data_to_flash) - 4));
	data_to_flash.end = '#';

	last_data_in = byte_in;
	ptr = &data_to_flash.start;
	if (sizeof(data_to_flash) % 2)		SFlash_write(ptr, sizeof(data_to_flash) - 1);
	else		SFlash_write(ptr, sizeof(data_to_flash));

	save_ok = 0;
	do
	{
		ptr2 = &data_to_check.start;

		SFlash_read_to_check(ptr2, last_data_in);

		if (data_to_check.crc != CRC16(&data_to_check.start, (sizeof(data_to_check) - 4)))
		{
			last_data_in = byte_in;

			if (sizeof(data_to_flash) % 2)		SFlash_write(ptr, sizeof(data_to_flash) - 1);
			else		SFlash_write(ptr, sizeof(data_to_flash));

			if (++failed_attempt > 3)
			{
				last_data_in = byte_in;
				failed_attempt = 0;
				break;
			}

		}
		else
			save_ok = 1;

	}
	while (save_ok == 0);

	SFlash_pointer_write();

	// free(ptr);
	//   ptr = NULL;

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

/**
 * @brief Adds RFID data to flash memory.
 *
 * This function handles the addition of RFID data to flash memory, including
 * calculating and storing CRC values for data integrity.
 *
 * @param  NA
 * @return NA
 */
void Adding_Rfid(void)
{
	uint8_t failed_attempt, save_ok;
	char *ptr2, *ptr;
	uint32_t last_data_in = 0;
	ptr = &rfid_data_to_flash.start;
	//if(LocalListAdding == rfid_pointer.Added_rfid )
	{
		rfid_data_to_flash.start = '$';

		rfid_data_to_flash.crc = CRC16(&rfid_data_to_flash.start, (sizeof(rfid_data_to_flash) - 4));
		rfid_data_to_flash.end = '#';

		last_data_in = rfid_pointer.lastPointer;

		if (sizeof(rfid_data_to_flash) % 2) 	SFlash_rfid_write(ptr, sizeof(rfid_data_to_flash) - 1);
		else 	SFlash_rfid_write(ptr, sizeof(rfid_data_to_flash));

		save_ok = 0;
		do
		{
			ptr2 = &rfid_data_to_check.start;

			SFlash_read_to_check(ptr2, last_data_in);

			if (rfid_data_to_check.crc != CRC16(&rfid_data_to_check.start, (sizeof(rfid_data_to_check) - 4)))
			{
				rfid_pointer.lastPointer = last_data_in;

				if (sizeof(rfid_data_to_flash) % 2) 	SFlash_rfid_write(ptr, sizeof(rfid_data_to_flash) - 1);
				else	SFlash_rfid_write(ptr, sizeof(rfid_data_to_flash));

				if (++failed_attempt > 3)
				{
					last_data_in = rfid_pointer.lastPointer;
					failed_attempt = 0;
					break;
				}
			} else
			{
				save_ok = 1;
				rfid_pointer.Added_rfid++;
			}

		}
		while (save_ok == 0);
	}

}

/**
 * @brief Calculates RFID expiry.
 *
 * This function calculates RFID expiry based on RTC (Real-Time Clock) and expiry times.
 *
 * @param rtc_time The current RTC time.
 * @param expiery_time The RFID expiry time.
 * @return 1 if RFID is still valid, 0 if expired.
 */
char expiry_calculation(String rtc_time, String expiery_time)
{

	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;
	int total_min_rtc = 0, total_min_exp = 0;
	//found = strtok(rtc,"T");

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

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

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

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

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

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

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

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

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

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

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

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

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

	if (exp_Year > rtc_Year)
	{
		return 1;
	}
	else if (exp_Year == rtc_Year)
	{
		if (exp_Month > rtc_Month)
		{
			return 1;
		}
		else if (exp_Month == rtc_Month)
		{
			if (exp_Day > rtc_Day)
			{
				return 1;
			}
			else if (exp_Day == rtc_Day)
			{
				total_min_exp = exp_Hour * 60;
				total_min_exp += exp_Min;

				total_min_rtc = rtc_Hour * 60;
				total_min_rtc += rtc_Min;

				if (total_min_exp > total_min_rtc)
				{
					return 1;
				}
				/*
				 if(exp_Hour > rtc_Hour )
				 {
				 return 1;
				 }
				 else if(exp_Hour == rtc_Hour)
				 {
				 return 1;
				 }*/
			}
		}
	}
	return 0;
}

/**
 * @brief Calculates billing information for charging points.
 *
 * This function calculates the billing information for each charging point based on
 * charging time, energy consumption, and specified charging criteria.
 *
 * @param NA
 * @return NA
 */
void Billing_calculation(void)
{
	uint32_t Total_cost1 = 0;
	if (++Charging_time > 6)
	{
		if ((charger_status_G1.charging_status == Charging_ChargerPoint))
		{
			update_variable = 1;
		}
		Charging_time = 0;
	}

	if (charger_status_G1.charging_status == Charging_ChargerPoint)
	{
		if (++charger_status_G1.charging_counter >= 6)
		{
			if ((++s6_counter1 % 10) == 0)
			{
				charger_status_G1.charging_time++;

				if (charger_status_G1.charge_by_automatic == 1)
				{

				}
				else if (charger_status_G1.charge_by_time != 0)
				{
					if (charger_status_G1.charging_time >= (charger_status_G1.charge_by_time))
					{
						update_variable = 1;
						charger_status_G1.stop = Try_To_Stop;
						charger_status_G1.charging_status = Finishing_ChargerPoint;
					}
				}
				else if (charger_status_G1.charge_by_energy != 0)
				{
					if ((charger_status_G1.energy) >= charger_status_G1.charge_by_energy * 1000) {
						update_variable = 1;
						charger_status_G1.stop = Try_To_Stop;
						charger_status_G1.charging_status = Finishing_ChargerPoint;
					}
				}
			}
			charger_status_G1.charging_counter = 0;

			Total_cost1 = charger_status_G1.energy * OCPP.energy_charges;
			if (Total_cost1 >= 1000)
			{
				Total_cost1 = Total_cost1 / 1000;
			}
			else
			{
				Total_cost1 = 1;
			}

			Total_cost1 += (s6_counter1 * OCPP.time_charges) / 10;
			charger_status_G1.Bill_Amount = Total_cost1;
			if (charger_status_G1.Bill_Amount > 9999)
			{
				charger_status_G1.Bill_Amount = 9999;
				charger_status_G1.stop = Try_To_Stop;
				charger_status_G1.charging_status = Finishing_ChargerPoint;
			}
		}
	}

}

/**
 * @brief  Sends data over UART for the G070 communication protocol.
 * @note   This function is responsible for transmitting data over UART
 *         according to the G070 communication protocol. It handles different
 *         scenarios such as updating RFID status or sending charger status frames.
 * @retval None
 */
void send_data_g070(void)			//ac001smart
{

	int BuffIndex = 0;

	if (rfid_sts_update != 0 || logout == 1)
	{
		//////////////////////////////////////////////////////////
		G070_TXbuff[BuffIndex++] = 0x5A;			//START BYTE1
		G070_TXbuff[BuffIndex++] = 0xA5;			//START BYTE2
		G070_TXbuff[BuffIndex++] = 0x00;			//data length
		G070_TXbuff[BuffIndex++] = 0X53;			// Frame type
		if (rfid_sts_update == 1)		G070_TXbuff[BuffIndex++] = 0x01;			//data //RFID Ok
		else if (rfid_sts_update == 2)	G070_TXbuff[BuffIndex++] = 0x02;			//data	//RFID not OK
		else if (rfid_sts_update == 3)	G070_TXbuff[BuffIndex++] = 0x03;//data	//RFID Authentication failed
		else if (rfid_sts_update == 4)	G070_TXbuff[BuffIndex++] = 0x01;
		G070_TXbuff[BuffIndex++] = 0x03; //END BYTE

		G070_TXbuff[2] = BuffIndex - 3; //data length
		HAL_UART_Transmit_DMA(&huart3, (uint8_t*) G070_TXbuff, BuffIndex);

		rfid_sts_update = 0;
///////////////////////////////////////////////////////////////
	}
	else if (G070_sts_tx_frame == 1)
	{
		//////////////////////////////////////////////////////////
		G070_TXbuff[BuffIndex++] = 0x5A; //START BYTE1
		G070_TXbuff[BuffIndex++] = 0xA5; //START BYTE2
		G070_TXbuff[BuffIndex++] = 0x00; //data length
		G070_TXbuff[BuffIndex++] = 0X50; // Frame type
		if (config_mode == 1)		G070_TXbuff[BuffIndex++] = 0x06; //data
		else if (charger_status_G1.charging_status == Available_ChargerPoint)	G070_TXbuff[BuffIndex++] = 0x01; //data
		else if (charger_status_G1.charging_status == Preparing_ChargerPoint)	G070_TXbuff[BuffIndex++] = 0x02; //data
		else if (charger_status_G1.charging_status == Charging_ChargerPoint)	G070_TXbuff[BuffIndex++] = 0x03; //data
		else if (charger_status_G1.charging_status == Faulted_ChargerPoint)		G070_TXbuff[BuffIndex++] = 0x04; //data
		else if (charger_status_G1.charging_status == Unavailable_ChargerPoint)	G070_TXbuff[BuffIndex++] = 0x05; //data
		else	G070_TXbuff[BuffIndex++] = 0x06; //data		TBD

		////////////////////////Errors/////////////////////////////////////////////////
		if (config_mode != 1)
		{
			if (charger_status_G1.error == InternalError)
			{
				G070_TXbuff[BuffIndex++] = 0x04; //data
				G070_TXbuff[4] = 0x04; //data
			}
			else if ((charger_status_G1.error == UnderVoltage) || (charger_status_G1.error == OverVoltage)
			|| (charger_status_G1.error == OverCurrentFailure) || (charger_status_G1.error == GroundFailure)
			|| (charger_status_G1.error == PowerSwitchFailure) || (charger_status_G1.error == OtherError))
			{
				G070_TXbuff[BuffIndex++] = 0x03; //data
				G070_TXbuff[4] = 0x04; //data
			}
			else if ((wifi_status == 0) && (OCPP.ocpp_status[0] == 1))
			{
				G070_TXbuff[BuffIndex++] = 0x01; //data
				G070_TXbuff[4] = 0x04; //data
			}

			else if ((!ocpp_boot_status) && (OCPP.ocpp_status[0] == 1))
			{
				G070_TXbuff[BuffIndex++] = 0x02; //data
				G070_TXbuff[4] = 0x04; //data
			}
			else if (charger_status_G1.error == NoError_ChargerPoint)
			{
				G070_TXbuff[BuffIndex++] = 0x00; //data
			}
		}
		else //no error in config mode
		{
			G070_TXbuff[BuffIndex++] = 0x00; //data
		}

		G070_TXbuff[BuffIndex++] = 0x03; //END BYTE

		G070_TXbuff[2] = BuffIndex - 3; //data length
		HAL_UART_Transmit_DMA(&huart3, (uint8_t*) G070_TXbuff, BuffIndex);

		G070_sts_tx_frame = 0;
		///////////////////////////////////////////////////////////////
	}
}

/**
  * @brief  Copies data from OCPP structure to form data structure.
  * @note   This function copies data from the OCPP (Open Charge Point Protocol)
  *         structure to the form data structure. It includes copying various
  *         parameters related to charger status, network configuration, RFID
  *         data, and communication status. The copied data is formatted and
  *         stored in the appropriate fields of the form data structure.
  * @retval None
  */
void copy_formdata(void)
{
	memset((unsigned char*) &form_data.under_voltage, 0x00, sizeof(struct FormData));

	form_data.under_voltage = OCPP.under_voltage;
	form_data.over_voltage = OCPP.over_voltage;
	form_data.over_current = OCPP.over_current;
	form_data.STATE_A_LEVEL = OCPP.STATE_A_LEVEL;
	form_data.STATE_B_LEVEL = OCPP.STATE_B_LEVEL;
	form_data.STATE_C_LEVEL = OCPP.STATE_C_LEVEL;
	form_data.STATE_D_LEVEL = OCPP.STATE_D_LEVEL;
	form_data.auxinput = OCPP.auxinput;
	//				memcpy(&OCPP.Mob_Num,&form_data.Mob_Num,10);
	//				memcpy(&OCPP.vendor_id,&form_data.vendor_id,10);
	memcpy(&form_data.wifi_ssid, &OCPP.wifi_ssid, 15);
	memcpy(&form_data.wifi_password, &OCPP.wifi_password, 15);
	memcpy(&form_data.serial_no, &OCPP.serial_no, 10);	//destinatio //source
	memcpy(&form_data.networkoperator, &OCPP.networkoperator, 20);
	memcpy(&form_data.ocpp_uri, &OCPP.ocpp_uri, 50);
	memcpy(&form_data.OCPP_servername, &OCPP.OCPP_servername, 30);
	memcpy(&form_data.OCPP_username, &OCPP.OCPP_username, 20);
	memcpy(&form_data.OCPP_Password, &OCPP.OCPP_Password, 20);
	memcpy(&form_data.OCPP_Port, &OCPP.OCPP_Port, 7);

	if (OCPP.ocpp_status[0] == 2)
	{
		form_data.ocpp_status[0] = '2';
		form_data.ocpp_status[1] = '\0';
	}
	else
	{
		form_data.ocpp_status[0] = '1';
		form_data.ocpp_status[1] = '\0';
	}

	form_data.fw_status[0] = ((OCPP.fw_status / 10) % 10) + '0';
	form_data.fw_status[1] = ((OCPP.fw_status) % 10) + '0';
	//memcpy(&form_data.fw_status,&OCPP.fw_status,2);
	memcpy(&form_data.fw_uri, &OCPP.fw_uri, 30);
	memcpy(&form_data.fw_servername, &OCPP.fw_servername, 30);
	memcpy(&form_data.fw_Port, &OCPP.fw_Port, 5);

	form_data.ipselection[0] = OCPP.ipselection + '0';
	form_data.ipselection[1] = '\0';

	form_data.ether_ip[0] = ((OCPP.ether_ip[0] / 100) % 10) + '0';
	form_data.ether_ip[1] = ((OCPP.ether_ip[0] / 10) % 10) + '0';
	form_data.ether_ip[2] = ((OCPP.ether_ip[0]) % 10) + '0';
	form_data.ether_ip[3] = '.';
	form_data.ether_ip[4] = ((OCPP.ether_ip[1] / 100) % 10) + '0';
	form_data.ether_ip[5] = ((OCPP.ether_ip[1] / 10) % 10) + '0';
	form_data.ether_ip[6] = ((OCPP.ether_ip[1]) % 10) + '0';
	form_data.ether_ip[7] = '.';
	form_data.ether_ip[8] = ((OCPP.ether_ip[2] / 100) % 10) + '0';
	form_data.ether_ip[9] = ((OCPP.ether_ip[2] / 10) % 10) + '0';
	form_data.ether_ip[10] = ((OCPP.ether_ip[2]) % 10) + '0';
	form_data.ether_ip[11] = '.';
	form_data.ether_ip[12] = ((OCPP.ether_ip[3] / 100) % 10) + '0';
	form_data.ether_ip[13] = ((OCPP.ether_ip[3] / 10) % 10) + '0';
	form_data.ether_ip[14] = ((OCPP.ether_ip[3]) % 10) + '0';
	form_data.ether_ip[15] = '\0';

	form_data.ether_getway[0] = ((OCPP.ether_getway[0] / 100) % 10) + '0';
	form_data.ether_getway[1] = ((OCPP.ether_getway[0] / 10) % 10) + '0';
	form_data.ether_getway[2] = ((OCPP.ether_getway[0]) % 10) + '0';
	form_data.ether_getway[3] = '.';
	form_data.ether_getway[4] = ((OCPP.ether_getway[1] / 100) % 10) + '0';
	form_data.ether_getway[5] = ((OCPP.ether_getway[1] / 10) % 10) + '0';
	form_data.ether_getway[6] = ((OCPP.ether_getway[1]) % 10) + '0';
	form_data.ether_getway[7] = '.';
	form_data.ether_getway[8] = ((OCPP.ether_getway[2] / 100) % 10) + '0';
	form_data.ether_getway[9] = ((OCPP.ether_getway[2] / 10) % 10) + '0';
	form_data.ether_getway[10] = ((OCPP.ether_getway[2]) % 10) + '0';
	form_data.ether_getway[11] = '.';
	form_data.ether_getway[12] = ((OCPP.ether_getway[3] / 100) % 10) + '0';
	form_data.ether_getway[13] = ((OCPP.ether_getway[3] / 10) % 10) + '0';
	form_data.ether_getway[14] = ((OCPP.ether_getway[3]) % 10) + '0';
	form_data.ether_getway[15] = '\0';

	form_data.ether_subnetmask[0] = ((OCPP.ether_subnetmask[0] / 100) % 10) + '0';
	form_data.ether_subnetmask[1] = ((OCPP.ether_subnetmask[0] / 10) % 10) + '0';
	form_data.ether_subnetmask[2] = ((OCPP.ether_subnetmask[0]) % 10) + '0';
	form_data.ether_subnetmask[3] = '.';
	form_data.ether_subnetmask[4] = ((OCPP.ether_subnetmask[1] / 100) % 10) + '0';
	form_data.ether_subnetmask[5] = ((OCPP.ether_subnetmask[1] / 10) % 10) + '0';
	form_data.ether_subnetmask[6] = ((OCPP.ether_subnetmask[1]) % 10) + '0';
	form_data.ether_subnetmask[7] = '.';
	form_data.ether_subnetmask[8] = ((OCPP.ether_subnetmask[2] / 100) % 10) + '0';
	form_data.ether_subnetmask[9] = ((OCPP.ether_subnetmask[2] / 10) % 10) + '0';
	form_data.ether_subnetmask[10] = ((OCPP.ether_subnetmask[2]) % 10) + '0';
	form_data.ether_subnetmask[11] = '.';
	form_data.ether_subnetmask[12] = ((OCPP.ether_subnetmask[3] / 100) % 10) + '0';
	form_data.ether_subnetmask[13] = ((OCPP.ether_subnetmask[3] / 10) % 10) + '0';
	form_data.ether_subnetmask[14] = ((OCPP.ether_subnetmask[3]) % 10) + '0';
	form_data.ether_subnetmask[15] = '\0';

	for (uint8_t j = 1; j <= 3; j++)
	{
		if (read_rfid_last_data(j) == 1)
		{
			strcpy(rfid_data.TagId[j], rfid_data_to_flash.TagId);
		}

	}
	strncpy(form_data.rfid1, rfid_data.TagId[1], 14);
	strncpy(form_data.rfid2, rfid_data.TagId[2], 14);
	strncpy(form_data.rfid3, rfid_data.TagId[3], 14);

	if ((GSM.gsm_enable_sts == 0) && (GSM.wifi_enable_sts == 1) && (GSM.ethernet_enable_sts == 0) && (OCPP.ocpp_status[0] == 1))
	{
		strcpy(form_data.ethernet_enable_sts, "wifi");
	}
	else if ((GSM.gsm_enable_sts == 1) && (GSM.wifi_enable_sts == 0) && (GSM.ethernet_enable_sts == 0) && (OCPP.ocpp_status[0] == 1))
	{
		strcpy(form_data.ethernet_enable_sts, "gsm");
	}
	else if ((GSM.gsm_enable_sts == 0) && (GSM.wifi_enable_sts == 0) && (GSM.ethernet_enable_sts == 1) && (OCPP.ocpp_status[0] == 1))
	{
		strcpy(form_data.ethernet_enable_sts, "eth");
	}
	else if ((GSM.gsm_enable_sts == 0) && (GSM.wifi_enable_sts == 0) && (GSM.ethernet_enable_sts == 0) && (OCPP.ocpp_status[0] == 2))
	{
		strcpy(form_data.ethernet_enable_sts, "none");
	}
	else
	{
		strcpy(form_data.ethernet_enable_sts, "none");
	}

}

/**
 * @brief  Converts an IP address string to an array of integers.
 * @note   This function parses an IP address string, splits it into its
 *         individual parts separated by dots ('.'), and converts each part
 *         into an integer. The resulting integers are stored in the provided
 *         array.
 * @param  ipString: Pointer to the IP address string to be converted.
 * @param  ipArray: Pointer to an integer array to store the converted IP address.
 *                  This array should have at least 4 elements.
 * @retval None
 */
void ipStringToArray(char *ipString, int *ipArray)
{
	// Create a copy of the string since strtok modifies the original string
	char ipCopy[strlen(ipString) + 1];
	strcpy(ipCopy, ipString);

	// Split the IP string using the dot as a delimiter
	char *token = strtok(ipCopy, ".");
	int i = 0;

	// Convert each part to an integer
	while (token != NULL && i < 4)
	{
		ipArray[i++] = atoi(token);
		token = strtok(NULL, ".");
	}
}

/* USER CODE END 4 */

/**
 * @brief  This function is executed in case of error occurrence.
 * @retval None
 */
void Error_Handler(void)
{
	/* USER CODE BEGIN Error_Handler_Debug */
	/* User can add his own implementation to report the HAL error return state */
	__disable_irq();
	while (1)
	{

	}
	/* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
