#include "cJSON.h"
#include "ocpp16.h"
#include "interface.h"
#include "ocpp16_client.h"
#include "ocpp16_encode.h"
#include "ocpp16_decode.h"
#include "ocpp16_configkey.h"
#include "ocpp16_authorization.h"
#include "ocpp16_OfflineChargingRecords.h"
#include "ocpp16_ChargingProfiles.h"
#include "ocpp16_ChargingPrice.h"
#include "secc_port.h"

int ocpp16_CancelReservation_confirm(ocpp_client_t* dev, CancelReservationReq_t* req, CancelReservationConf_t* conf)
{
    ccu_port_t* ccu = (ccu_port_t*)dev->ccu;
    secc_port_t* gunA = (secc_port_t*)ccu->seccA;
    secc_port_t* gunB = (secc_port_t*)ccu->seccB;
    conf->status = CancelReservationStatus_Rejected;
    if (req->reservationId>0)
    {
        if (gunA->GUN_Error == GUN_RESERVED)
        {
            if (gunA->reservationId == req->reservationId)
            {
                secc_set_error(gunA, 0);
                conf->status = CancelReservationStatus_Accepted;
            }
        }
        if (gunB->GUN_Error == GUN_RESERVED)
        {
            if (gunB->reservationId == req->reservationId)
            {
                secc_set_error(gunB, 0);
                conf->status = CancelReservationStatus_Accepted;
            }
        }
    }
    return 0;
}

int ocpp16_ChangeAvailability_confirm(ocpp_client_t* dev, ChangeAvailabilityReq_t* req, ChangeAvailabilityConf_t* conf)
{
    ccu_port_t* ccu = (ccu_port_t*)dev->ccu;
    secc_port_t* gunA = (secc_port_t*)ccu->seccA;
    secc_port_t* gunB = (secc_port_t*)ccu->seccB;
    conf->status = AvailabilityStatus_Rejected;

    if (req->connectorId == 1 || req->connectorId == 0)
    {
        if (req->type == AvailabilityType_Operative){
            gunA->config->GUN_Available = true;
            conf->status = AvailabilityStatus_Accepted;
        }
        if (req->type == AvailabilityType_Inoperative){
            gunA->config->GUN_Available = false;
            conf->status = AvailabilityStatus_Accepted;
        }
    }  
    if (req->connectorId == 2 || req->connectorId == 0)
    {
        if (req->type == AvailabilityType_Operative){
            gunB->config->GUN_Available = true;
            conf->status = AvailabilityStatus_Accepted;
        }
        if (req->type == AvailabilityType_Inoperative){
            gunB->config->GUN_Available = false;
            conf->status = AvailabilityStatus_Accepted;
        }
    }
    return 0;
}

static bool BOOL_fromString(const char* in)
{
    if (strcmp(in, "true")==0) return true;
    if (strcmp(in, "false")==0) return false;
    return false;
}

int ocpp16_ChangeConfiguration_confirm(ocpp_client_t* dev, ChangeConfigurationReq_t* req, ChangeConfigurationConf_t* conf)
{
    conf->status = ConfigurationStatus_NotSupported;
    //以下被注释的configkey属于只读，不能更改
    if (strcmp(req->key, "AllowOfflineTxForUnknownId") == 0){ ocpp16_configkeys.coreProfile.AllowOfflineTxForUnknownId = BOOL_fromString(req->value); conf->status = ConfigurationStatus_Accepted;}
    if (strcmp(req->key, "AuthorizationCacheEnabled") == 0){ ocpp16_configkeys.coreProfile.AuthorizationCacheEnabled = BOOL_fromString(req->value); conf->status = ConfigurationStatus_Accepted;}
    if (strcmp(req->key, "AuthorizeRemoteTxRequests") == 0){ ocpp16_configkeys.coreProfile.AuthorizeRemoteTxRequests = BOOL_fromString(req->value); conf->status = ConfigurationStatus_Accepted;}
    if (strcmp(req->key, "BlinkRepeat") == 0){ ocpp16_configkeys.coreProfile.BlinkRepeat = atoi(req->value); conf->status = ConfigurationStatus_Accepted;}
    if (strcmp(req->key, "ClockAlignedDataInterval") == 0){ ocpp16_configkeys.coreProfile.ClockAlignedDataInterval = atoi(req->value); conf->status = ConfigurationStatus_Accepted;}
    if (strcmp(req->key, "ConnectionTimeOut") == 0){ ocpp16_configkeys.coreProfile.ConnectionTimeOut = atoi(req->value); conf->status = ConfigurationStatus_Accepted;}
    if (strcmp(req->key, "ConnectorPhaseRotation") == 0){ sprintf(ocpp16_configkeys.coreProfile.ConnectorPhaseRotation, "%s", req->value); conf->status = ConfigurationStatus_Accepted;}
    //if (strcmp(req->key, "ConnectorPhaseRotationMaxLength") == 0){ ocpp16_configkeys.coreProfile.ConnectorPhaseRotationMaxLength = atoi(req->value); conf->status = ConfigurationStatus_Accepted;}
    //if (strcmp(req->key, "GetConfigurationMaxKeys") == 0){ ocpp16_configkeys.coreProfile.GetConfigurationMaxKeys = atoi(req->value); conf->status = ConfigurationStatus_Accepted;}
    if (strcmp(req->key, "HeartbeatInterval") == 0){ ocpp16_configkeys.coreProfile.HeartbeatInterval = atoi(req->value); conf->status = ConfigurationStatus_Accepted;}

    if (strcmp(req->key, "LightIntensity") == 0){ ocpp16_configkeys.coreProfile.LightIntensity = atoi(req->value); conf->status = ConfigurationStatus_Accepted;}
    if (strcmp(req->key, "LocalAuthorizeOffline") == 0){ ocpp16_configkeys.coreProfile.LocalAuthorizeOffline = BOOL_fromString(req->value); conf->status = ConfigurationStatus_Accepted;}
    if (strcmp(req->key, "LocalPreAuthorize") == 0){ ocpp16_configkeys.coreProfile.LocalPreAuthorize = BOOL_fromString(req->value); conf->status = ConfigurationStatus_Accepted;}
    if (strcmp(req->key, "MaxEnergyOnInvalidId") == 0){ ocpp16_configkeys.coreProfile.MaxEnergyOnInvalidId = atoi(req->value); conf->status = ConfigurationStatus_Accepted;}
    if (strcmp(req->key, "MeterValuesAlignedData") == 0){ ocpp16_configkeys.coreProfile.MeterValuesAlignedData = Measurand_fromString(req->value); conf->status = ConfigurationStatus_Accepted;}
    //if (strcmp(req->key, "MeterValuesAlignedDataMaxLength") == 0){ ocpp16_configkeys.coreProfile.MeterValuesAlignedDataMaxLength = atoi(req->value); conf->status = ConfigurationStatus_Accepted;}
    if (strcmp(req->key, "MeterValuesSampledData") == 0){ ocpp16_configkeys.coreProfile.MeterValuesSampledData = Measurand_fromString(req->value); conf->status = ConfigurationStatus_Accepted;}
    //if (strcmp(req->key, "MeterValuesSampledDataMaxLength") == 0){ ocpp16_configkeys.coreProfile.MeterValuesSampledDataMaxLength = atoi(req->value); conf->status = ConfigurationStatus_Accepted;}
    if (strcmp(req->key, "MeterValueSampleInterval") == 0){ ocpp16_configkeys.coreProfile.MeterValueSampleInterval = atoi(req->value); conf->status = ConfigurationStatus_Accepted;}
    if (strcmp(req->key, "MinimumStatusDuration") == 0){ ocpp16_configkeys.coreProfile.MinimumStatusDuration = atoi(req->value); conf->status = ConfigurationStatus_Accepted;}

    //if (strcmp(req->key, "NumberOfConnectors") == 0){ ocpp16_configkeys.coreProfile.NumberOfConnectors = atoi(req->value); conf->status = ConfigurationStatus_Accepted;}
    if (strcmp(req->key, "ResetRetries") == 0){ ocpp16_configkeys.coreProfile.ResetRetries = atoi(req->value); conf->status = ConfigurationStatus_Accepted;}
    if (strcmp(req->key, "StopTransactionOnEVSideDisconnect") == 0){ ocpp16_configkeys.coreProfile.StopTransactionOnEVSideDisconnect = BOOL_fromString(req->value); conf->status = ConfigurationStatus_Accepted;}
    if (strcmp(req->key, "StopTransactionOnInvalidId") == 0){ ocpp16_configkeys.coreProfile.StopTransactionOnInvalidId = BOOL_fromString(req->value); conf->status = ConfigurationStatus_Accepted;}
    if (strcmp(req->key, "StopTxnAlignedData") == 0){ ocpp16_configkeys.coreProfile.StopTxnAlignedData = Measurand_fromString(req->value); conf->status = ConfigurationStatus_Accepted;}
    //if (strcmp(req->key, "StopTxnAlignedDataMaxLength") == 0){ ocpp16_configkeys.coreProfile.StopTxnAlignedDataMaxLength = atoi(req->value); conf->status = ConfigurationStatus_Accepted;}
    if (strcmp(req->key, "StopTxnSampledData") == 0){ ocpp16_configkeys.coreProfile.StopTxnSampledData = Measurand_fromString(req->value); conf->status = ConfigurationStatus_Accepted;}
    //if (strcmp(req->key, "StopTxnSampledDataMaxLength") == 0){ ocpp16_configkeys.coreProfile.StopTxnSampledDataMaxLength = atoi(req->value); conf->status = ConfigurationStatus_Accepted;}
    //if (strcmp(req->key, "SupportedFeatureProfiles") == 0){ sprintf(ocpp16_configkeys.coreProfile.SupportedFeatureProfiles, "%s", req->value); conf->status = ConfigurationStatus_Accepted;}
    //if (strcmp(req->key, "SupportedFeatureProfilesMaxLength") == 0){ ocpp16_configkeys.coreProfile.SupportedFeatureProfilesMaxLength = atoi(req->value); conf->status = ConfigurationStatus_Accepted;}

    if (strcmp(req->key, "TransactionMessageAttempts") == 0){ ocpp16_configkeys.coreProfile.TransactionMessageAttempts = atoi(req->value); conf->status = ConfigurationStatus_Accepted;}
    if (strcmp(req->key, "TransactionMessageRetryInterval") == 0){ ocpp16_configkeys.coreProfile.TransactionMessageRetryInterval = atoi(req->value); conf->status = ConfigurationStatus_Accepted;}
    if (strcmp(req->key, "UnlockConnectorOnEVSideDisconnect") == 0){ ocpp16_configkeys.coreProfile.UnlockConnectorOnEVSideDisconnect = BOOL_fromString(req->value); conf->status = ConfigurationStatus_Accepted;}
    if (strcmp(req->key, "WebSocketPingInterval") == 0){ ocpp16_configkeys.coreProfile.WebSocketPingInterval = atoi(req->value); conf->status = ConfigurationStatus_Accepted;}
    if (strcmp(req->key, "AuthorizationKey") == 0){ sprintf(ocpp16_configkeys.coreProfile.AuthorizationKey, "%s", req->value); conf->status = ConfigurationStatus_Accepted;}
    if (strcmp(req->key, "AuthorizationCacheMaxLength") == 0){ ocpp16_configkeys.coreProfile.AuthorizationCacheMaxLength = atoi(req->value); conf->status = ConfigurationStatus_Accepted;}
    if (strcmp(req->key, "LocalAuthListEnabled") == 0){ ocpp16_configkeys.localAuthListManagemenProfile.LocalAuthListEnabled = BOOL_fromString(req->value); conf->status = ConfigurationStatus_Accepted;}
    //if (strcmp(req->key, "LocalAuthListMaxLength") == 0){ ocpp16_configkeys.localAuthListManagemenProfile.LocalAuthListMaxLength = atoi(req->value); conf->status = ConfigurationStatus_Accepted;}
    //if (strcmp(req->key, "SendLocalListMaxLength") == 0){ ocpp16_configkeys.localAuthListManagemenProfile.SendLocalListMaxLength = atoi(req->value); conf->status = ConfigurationStatus_Accepted;}
    //if (strcmp(req->key, "ReserveConnectorZeroSupported") == 0){ ocpp16_configkeys.reservationProfile.ReserveConnectorZeroSupported = BOOL_fromString(req->value); conf->status = ConfigurationStatus_Accepted;}

    //if (strcmp(req->key, "ChargeProfileMaxStackLevel") == 0){ ocpp16_configkeys.smartChargingProfile.ChargeProfileMaxStackLevel = atoi(req->value); conf->status = ConfigurationStatus_Accepted;}
    //if (strcmp(req->key, "ChargingScheduleAllowedChargingRateUnit") == 0){ ocpp16_configkeys.smartChargingProfile.ChargingScheduleAllowedChargingRateUnit= ChargingScheduleAllowedChargingRateUnit_fromString(req->value); conf->status = ConfigurationStatus_Accepted;}
    //if (strcmp(req->key, "ChargingScheduleMaxPeriods") == 0){ ocpp16_configkeys.smartChargingProfile.ChargingScheduleMaxPeriods = atoi(req->value); conf->status = ConfigurationStatus_Accepted;}
    //if (strcmp(req->key, "ConnectorSwitch3to1PhaseSupported") == 0){ ocpp16_configkeys.smartChargingProfile.ConnectorSwitch3to1PhaseSupported = BOOL_fromString(req->value); conf->status = ConfigurationStatus_Accepted;}
    //if (strcmp(req->key, "MaxChargingProfilesInstalled") == 0){ ocpp16_configkeys.smartChargingProfile.MaxChargingProfilesInstalled = atoi(req->value); conf->status = ConfigurationStatus_Accepted;}

    return 0;
}

int ocpp16_ClearCache_confirm(ocpp_client_t* dev, ClearCacheReq_t* req, ClearCacheConf_t* conf)
{
    conf->status = ClearCacheStatus_Rejected;
    authorizationCache.count = 0;
    conf->status = ClearCacheStatus_Accepted;
    return 0;
}

int ocpp16_ClearChargingProfile_confirm(ocpp_client_t* dev, ClearChargingProfileReq_t* req, ClearChargingProfileConf_t* conf)
{
    int i, j;
    int matched = 0;
    conf->status = ClearChargingProfileStatus_Unknown;
    if (req->id != -1)
    {
        for (i=0; i<chargingProfiles.count; i++)
        {
            if (chargingProfiles.items[i].chargingProfileId == req->id)
            {
                conf->status = ClearChargingProfileStatus_Accepted;
                for (j=i; j<chargingProfiles.count; j++)
                {
                    if (j == chargingProfiles.count-1)
                    {
                        memset(&chargingProfiles.items[chargingProfiles.count-1], 0, sizeof(ChargingProfile_t));
                    }else{
                        memcpy(&chargingProfiles.items[j], &chargingProfiles.items[j+1], sizeof(ChargingProfile_t));
                    }
                }
                chargingProfiles.count -= 1;
                break;
            }
        }
    }

    for (i=0; i<chargingProfiles.count; i++)
    {
        matched = 0;
        if (req->connectorId == -1)
        {
            if (req->chargingProfilePurpose == 0)
            {
                if (req->stackLevel != -1 && chargingProfiles.items[i].stackLevel == req->stackLevel)
                {
                    matched = 1;
                }
            }else{
                if (chargingProfiles.items[i].chargingProfilePurpose == req->chargingProfilePurpose)
                {
                    if (req->stackLevel == -1 || chargingProfiles.items[i].stackLevel == req->stackLevel)
                    {
                        matched = 1;
                    }
                }
            }
        }else{
            if (chargingProfiles.items[i].transactionId == req->connectorId)
            {
                if (req->chargingProfilePurpose == 0)
                {
                    matched = 1;
                }else{
                    if (req->stackLevel == -1 || chargingProfiles.items[i].stackLevel == req->stackLevel)
                    {
                        matched = 1;
                    }
                }
            }
        }

        if (matched == 1)
        {
            conf->status = ClearChargingProfileStatus_Accepted;
            for (j=i; j<chargingProfiles.count; j++)
            {
                if (j == chargingProfiles.count-1)
                {
                    memset(&chargingProfiles.items[chargingProfiles.count-1], 0, sizeof(ChargingProfile_t));
                }else{
                    memcpy(&chargingProfiles.items[j], &chargingProfiles.items[j+1], sizeof(ChargingProfile_t));
                }
            }
            chargingProfiles.count -= 1;
            break;
        }
    }

}

int ocpp16_DataTransfer_confirm(ocpp_client_t* dev, DataTransferReq_t* req, DataTransferConf_t* conf)
{
    conf->status = DataTransferStatus_UnknownVendorId;
    if (strcmp(req->vendorId, "TCharge")==0)
    {
        conf->status = DataTransferStatus_UnknownMessageId;
        if (strcmp(req->messageId,"SetPrice")==0)
        {
            ocpp16_ChargingPrice_save("/home/root/app_run/etc/ocpp16_ChargingPrice.json", &req->data);
            conf->status = DataTransferStatus_Accepted;
        }
        if (strcmp(req->messageId,"GetPrice")==0)
        {
            ocpp16_ChargingPrice_load("/home/root/app_run/etc/ocpp16_ChargingPrice.json", &conf->data);
            conf->status = DataTransferStatus_Accepted;
        }
    }
}

int ocpp16_GetCompositeSchedule_confirm(ocpp_client_t* dev, GetCompositeScheduleReq_t* req, GetCompositeScheduleConf_t* conf)
{
    conf->status = GetCompositeScheduleStatus_Rejected;
}

static char* BOOL_toString(bool in)
{
    if(in == true) return "true";
    else return "false";
}

int ocpp16_GetConfiguration_confirm(ocpp_client_t* dev, GetConfigurationReq_t* req, GetConfigurationConf_t* conf)
{
    int i;
    char buff[512];
    printv("step\n");
    memset(conf, 0, sizeof(GetConfigurationConf_t));
    conf->configurationKey.count=0;
    conf->unknownKey.count = 0;
    if (req->key.count==0)
    {
        sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "AllowOfflineTxForUnknownId");
        sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%s", BOOL_toString(ocpp16_configkeys.coreProfile.AllowOfflineTxForUnknownId));
        conf->configurationKey.items[conf->configurationKey.count].readonly = false;
        conf->configurationKey.count++;

        sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "AuthorizationCacheEnabled");
        sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%s", BOOL_toString(ocpp16_configkeys.coreProfile.AuthorizationCacheEnabled));
        conf->configurationKey.items[conf->configurationKey.count].readonly = false;
        conf->configurationKey.count++;

        sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "AuthorizeRemoteTxRequests");
        sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%s", BOOL_toString(ocpp16_configkeys.coreProfile.AuthorizeRemoteTxRequests));
        conf->configurationKey.items[conf->configurationKey.count].readonly = true;
        conf->configurationKey.count++;

        sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "BlinkRepeat");
        sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%d", ocpp16_configkeys.coreProfile.BlinkRepeat);
        conf->configurationKey.items[conf->configurationKey.count].readonly = false;
        conf->configurationKey.count++;

        sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "ClockAlignedDataInterval");
        sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%d", ocpp16_configkeys.coreProfile.ClockAlignedDataInterval);
        conf->configurationKey.items[conf->configurationKey.count].readonly = false;
        conf->configurationKey.count++;

        sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "ConnectionTimeOut");
        sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%d", ocpp16_configkeys.coreProfile.ConnectionTimeOut);
        conf->configurationKey.items[conf->configurationKey.count].readonly = false;
        conf->configurationKey.count++;

        sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "ConnectorPhaseRotation");
        sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%s", ocpp16_configkeys.coreProfile.ConnectorPhaseRotation);
        conf->configurationKey.items[conf->configurationKey.count].readonly = false;
        conf->configurationKey.count++;

        sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "ConnectorPhaseRotationMaxLength");
        sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%d", ocpp16_configkeys.coreProfile.ConnectorPhaseRotationMaxLength);
        conf->configurationKey.items[conf->configurationKey.count].readonly = true;
        conf->configurationKey.count++;

        sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "GetConfigurationMaxKeys");
        sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%d", ocpp16_configkeys.coreProfile.GetConfigurationMaxKeys);
        conf->configurationKey.items[conf->configurationKey.count].readonly = true;
        conf->configurationKey.count++;

        sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "HeartbeatInterval");
        sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%d", ocpp16_configkeys.coreProfile.HeartbeatInterval);
        conf->configurationKey.items[conf->configurationKey.count].readonly = false;
        conf->configurationKey.count++;

        sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "LightIntensity");
        sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%d", ocpp16_configkeys.coreProfile.LightIntensity);
        conf->configurationKey.items[conf->configurationKey.count].readonly = false;
        conf->configurationKey.count++;

        sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "LocalAuthorizeOffline");
        sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%s", BOOL_toString(ocpp16_configkeys.coreProfile.LocalAuthorizeOffline));
        conf->configurationKey.items[conf->configurationKey.count].readonly = false;
        conf->configurationKey.count++;

        sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "LocalPreAuthorize");
        sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%s", BOOL_toString(ocpp16_configkeys.coreProfile.LocalPreAuthorize));
        conf->configurationKey.items[conf->configurationKey.count].readonly = false;
        conf->configurationKey.count++;

        sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "MaxEnergyOnInvalidId");
        sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%d", ocpp16_configkeys.coreProfile.MaxEnergyOnInvalidId);
        conf->configurationKey.items[conf->configurationKey.count].readonly = false;
        conf->configurationKey.count++;

        sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "MeterValuesAlignedData");
        sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%s", Measurand_toString(buff, ocpp16_configkeys.coreProfile.MeterValuesAlignedData));
        conf->configurationKey.items[conf->configurationKey.count].readonly = false;
        conf->configurationKey.count++;

        sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "MeterValuesAlignedDataMaxLength");
        sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%d", ocpp16_configkeys.coreProfile.MeterValuesAlignedDataMaxLength);
        conf->configurationKey.items[conf->configurationKey.count].readonly = true;
        conf->configurationKey.count++;

        sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "MeterValuesSampledData");
        sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%s", Measurand_toString(buff, ocpp16_configkeys.coreProfile.MeterValuesSampledData));
        conf->configurationKey.items[conf->configurationKey.count].readonly = false;
        conf->configurationKey.count++;

        sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "MeterValuesSampledDataMaxLength");
        sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%d", ocpp16_configkeys.coreProfile.MeterValuesSampledDataMaxLength);
        conf->configurationKey.items[conf->configurationKey.count].readonly = true;
        conf->configurationKey.count++;

        sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "MeterValueSampleInterval");
        sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%d", ocpp16_configkeys.coreProfile.MeterValueSampleInterval);
        conf->configurationKey.items[conf->configurationKey.count].readonly = false;
        conf->configurationKey.count++;

        sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "MinimumStatusDuration");
        sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%d", ocpp16_configkeys.coreProfile.MinimumStatusDuration);
        conf->configurationKey.items[conf->configurationKey.count].readonly = false;
        conf->configurationKey.count++;

        sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "NumberOfConnectors");
        sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%d", ocpp16_configkeys.coreProfile.NumberOfConnectors);
        conf->configurationKey.items[conf->configurationKey.count].readonly = true;
        conf->configurationKey.count++;

        sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "ResetRetries");
        sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%d", ocpp16_configkeys.coreProfile.ResetRetries);
        conf->configurationKey.items[conf->configurationKey.count].readonly = false;
        conf->configurationKey.count++;

        sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "StopTransactionOnEVSideDisconnect");
        sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%s", BOOL_toString(ocpp16_configkeys.coreProfile.StopTransactionOnEVSideDisconnect));
        conf->configurationKey.items[conf->configurationKey.count].readonly = false;
        conf->configurationKey.count++;

        sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "StopTransactionOnInvalidId");
        sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%s", BOOL_toString(ocpp16_configkeys.coreProfile.StopTransactionOnInvalidId));
        conf->configurationKey.items[conf->configurationKey.count].readonly = false;
        conf->configurationKey.count++;

        sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "StopTxnAlignedData");
        sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%s", Measurand_toString(buff, ocpp16_configkeys.coreProfile.StopTxnAlignedData));
        conf->configurationKey.items[conf->configurationKey.count].readonly = false;
        conf->configurationKey.count++;

        sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "StopTxnAlignedDataMaxLength");
        sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%d", ocpp16_configkeys.coreProfile.StopTxnAlignedDataMaxLength);
        conf->configurationKey.items[conf->configurationKey.count].readonly = true;
        conf->configurationKey.count++;

        sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "StopTxnSampledData");
        sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%s", Measurand_toString(buff, ocpp16_configkeys.coreProfile.StopTxnSampledData));
        conf->configurationKey.items[conf->configurationKey.count].readonly = false;
        conf->configurationKey.count++;

        sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "StopTxnSampledDataMaxLength");
        sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%d", ocpp16_configkeys.coreProfile.StopTxnSampledDataMaxLength);
        conf->configurationKey.items[conf->configurationKey.count].readonly = true;
        conf->configurationKey.count++;

        sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "SupportedFeatureProfiles");
        sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%s", ocpp16_configkeys.coreProfile.SupportedFeatureProfiles);
        conf->configurationKey.items[conf->configurationKey.count].readonly = true;
        conf->configurationKey.count++;

        sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "SupportedFeatureProfilesMaxLength");
        sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%d", ocpp16_configkeys.coreProfile.SupportedFeatureProfilesMaxLength);
        conf->configurationKey.items[conf->configurationKey.count].readonly = true;
        conf->configurationKey.count++;

        sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "TransactionMessageAttempts");
        sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%d", ocpp16_configkeys.coreProfile.TransactionMessageAttempts);
        conf->configurationKey.items[conf->configurationKey.count].readonly = false;
        conf->configurationKey.count++;

        sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "TransactionMessageRetryInterval");
        sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%d", ocpp16_configkeys.coreProfile.TransactionMessageRetryInterval);
        conf->configurationKey.items[conf->configurationKey.count].readonly = false;
        conf->configurationKey.count++;

        sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "UnlockConnectorOnEVSideDisconnect");
        sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%s", BOOL_toString(ocpp16_configkeys.coreProfile.UnlockConnectorOnEVSideDisconnect));
        conf->configurationKey.items[conf->configurationKey.count].readonly = false;
        conf->configurationKey.count++;

        sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "WebSocketPingInterval");
        sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%d", ocpp16_configkeys.coreProfile.WebSocketPingInterval);
        conf->configurationKey.items[conf->configurationKey.count].readonly = false;
        conf->configurationKey.count++;

        sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "AuthorizationKey");
        sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%s", ocpp16_configkeys.coreProfile.AuthorizationKey);
        conf->configurationKey.items[conf->configurationKey.count].readonly = false;
        conf->configurationKey.count++;

        sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "AuthorizationCacheMaxLength");
        sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%d", ocpp16_configkeys.coreProfile.AuthorizationCacheMaxLength);
        conf->configurationKey.items[conf->configurationKey.count].readonly = false;
        conf->configurationKey.count++;

        sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "LocalAuthListEnabled");
        sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%s", BOOL_toString(ocpp16_configkeys.localAuthListManagemenProfile.LocalAuthListEnabled));
        conf->configurationKey.items[conf->configurationKey.count].readonly = false;
        conf->configurationKey.count++;

        sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "LocalAuthListMaxLength");
        sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%d", ocpp16_configkeys.localAuthListManagemenProfile.LocalAuthListMaxLength);
        conf->configurationKey.items[conf->configurationKey.count].readonly = true;
        conf->configurationKey.count++;

        sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "SendLocalListMaxLength");
        sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%d", ocpp16_configkeys.localAuthListManagemenProfile.SendLocalListMaxLength);
        conf->configurationKey.items[conf->configurationKey.count].readonly = true;
        conf->configurationKey.count++;

        sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "ReserveConnectorZeroSupported");
        sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%s", BOOL_toString(ocpp16_configkeys.reservationProfile.ReserveConnectorZeroSupported));
        conf->configurationKey.items[conf->configurationKey.count].readonly = true;
        conf->configurationKey.count++;

        sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "ChargeProfileMaxStackLevel");
        sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%d", ocpp16_configkeys.smartChargingProfile.ChargeProfileMaxStackLevel);
        conf->configurationKey.items[conf->configurationKey.count].readonly = true;
        conf->configurationKey.count++;

        sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "ChargingScheduleAllowedChargingRateUnit");
        sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%s", ChargingScheduleAllowedChargingRateUnit_toString(buff, ocpp16_configkeys.smartChargingProfile.ChargingScheduleAllowedChargingRateUnit));
        conf->configurationKey.items[conf->configurationKey.count].readonly = true;
        conf->configurationKey.count++;

        sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "ChargingScheduleMaxPeriods");
        sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%d", ocpp16_configkeys.smartChargingProfile.ChargingScheduleMaxPeriods);
        conf->configurationKey.items[conf->configurationKey.count].readonly = true;
        conf->configurationKey.count++;

        sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "ConnectorSwitch3to1PhaseSupported");
        sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%s", BOOL_toString(ocpp16_configkeys.smartChargingProfile.ConnectorSwitch3to1PhaseSupported));
        conf->configurationKey.items[conf->configurationKey.count].readonly = true;
        conf->configurationKey.count++;

        sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "MaxChargingProfilesInstalled");
        sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%d", ocpp16_configkeys.smartChargingProfile.MaxChargingProfilesInstalled);
        conf->configurationKey.items[conf->configurationKey.count].readonly = true;
        conf->configurationKey.count++;   
        return 0;
    }
    printv("step\n");
    for (i=0; i<req->key.count; i++)
    {
        int findkey = conf->configurationKey.count;
        if (strcmp(req->key.items[i], "AllowOfflineTxForUnknownId")==0) 
        {
            sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "AllowOfflineTxForUnknownId");
            sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%s", BOOL_toString(ocpp16_configkeys.coreProfile.AllowOfflineTxForUnknownId));
            conf->configurationKey.items[conf->configurationKey.count].readonly = false;
            conf->configurationKey.count++;
        }
        if (strcmp(req->key.items[i], "AuthorizationCacheEnabled")==0) 
        {
            sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "AuthorizationCacheEnabled");
            sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%s", BOOL_toString(ocpp16_configkeys.coreProfile.AuthorizationCacheEnabled));
            conf->configurationKey.items[conf->configurationKey.count].readonly = false;
            conf->configurationKey.count++;
        }
        if (strcmp(req->key.items[i], "AuthorizeRemoteTxRequests")==0) 
        {
            sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "AuthorizeRemoteTxRequests");
            sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%s", BOOL_toString(ocpp16_configkeys.coreProfile.AuthorizeRemoteTxRequests));
            conf->configurationKey.items[conf->configurationKey.count].readonly = true;
            conf->configurationKey.count++;
        }
        if (strcmp(req->key.items[i], "BlinkRepeat")==0) 
        {
            sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "BlinkRepeat");
            sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%d", ocpp16_configkeys.coreProfile.BlinkRepeat);
            conf->configurationKey.items[conf->configurationKey.count].readonly = false;
            conf->configurationKey.count++;
        }
        if (strcmp(req->key.items[i], "ClockAlignedDataInterval")==0) 
        {
            sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "ClockAlignedDataInterval");
            sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%d", ocpp16_configkeys.coreProfile.ClockAlignedDataInterval);
            conf->configurationKey.items[conf->configurationKey.count].readonly = false;
            conf->configurationKey.count++;
        }
        if (strcmp(req->key.items[i], "ConnectionTimeOut")==0) 
        {
            sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "ConnectionTimeOut");
            sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%d", ocpp16_configkeys.coreProfile.ConnectionTimeOut);
            conf->configurationKey.items[conf->configurationKey.count].readonly = false;
            conf->configurationKey.count++;
        }
        if (strcmp(req->key.items[i], "ConnectorPhaseRotation")==0) 
        {
            sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "ConnectorPhaseRotation");
            sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%s", ocpp16_configkeys.coreProfile.ConnectorPhaseRotation);
            conf->configurationKey.items[conf->configurationKey.count].readonly = false;
            conf->configurationKey.count++;
        }
        if (strcmp(req->key.items[i], "ConnectorPhaseRotationMaxLength")==0) 
        {
            sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "ConnectorPhaseRotationMaxLength");
            sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%d", ocpp16_configkeys.coreProfile.ConnectorPhaseRotationMaxLength);
            conf->configurationKey.items[conf->configurationKey.count].readonly = true;
            conf->configurationKey.count++;
        }
        if (strcmp(req->key.items[i], "GetConfigurationMaxKeys")==0) 
        {
            sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "GetConfigurationMaxKeys");
            sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%d", ocpp16_configkeys.coreProfile.GetConfigurationMaxKeys);
            conf->configurationKey.items[conf->configurationKey.count].readonly = true;
            conf->configurationKey.count++;
        }
        if (strcmp(req->key.items[i], "HeartbeatInterval")==0) 
        {
            sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "HeartbeatInterval");
            sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%d", ocpp16_configkeys.coreProfile.HeartbeatInterval);
            conf->configurationKey.items[conf->configurationKey.count].readonly = false;
            conf->configurationKey.count++;
        }
        if (strcmp(req->key.items[i], "LightIntensity")==0) 
        {
            sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "LightIntensity");
            sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%d", ocpp16_configkeys.coreProfile.LightIntensity);
            conf->configurationKey.items[conf->configurationKey.count].readonly = false;
            conf->configurationKey.count++;
        }
        if (strcmp(req->key.items[i], "LocalAuthorizeOffline")==0) 
        {
            sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "LocalAuthorizeOffline");
            sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%s", BOOL_toString(ocpp16_configkeys.coreProfile.LocalAuthorizeOffline));
            conf->configurationKey.items[conf->configurationKey.count].readonly = false;
            conf->configurationKey.count++;
        }
        if (strcmp(req->key.items[i], "LocalPreAuthorize")==0) 
        {
            sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "LocalPreAuthorize");
            sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%s", BOOL_toString(ocpp16_configkeys.coreProfile.LocalPreAuthorize));
            conf->configurationKey.items[conf->configurationKey.count].readonly = false;
            conf->configurationKey.count++;
        }
        if (strcmp(req->key.items[i], "MaxEnergyOnInvalidId")==0) 
        {
            sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "MaxEnergyOnInvalidId");
            sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%d", ocpp16_configkeys.coreProfile.MaxEnergyOnInvalidId);
            conf->configurationKey.items[conf->configurationKey.count].readonly = false;
            conf->configurationKey.count++;
        }
        if (strcmp(req->key.items[i], "MeterValuesAlignedData")==0) 
        {
            sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "MeterValuesAlignedData");
            sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%s", Measurand_toString(buff, ocpp16_configkeys.coreProfile.MeterValuesAlignedData));
            conf->configurationKey.items[conf->configurationKey.count].readonly = false;
            conf->configurationKey.count++;
        }
        if (strcmp(req->key.items[i], "MeterValuesAlignedDataMaxLength")==0) 
        {
            sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "MeterValuesAlignedDataMaxLength");
            sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%d", ocpp16_configkeys.coreProfile.MeterValuesAlignedDataMaxLength);
            conf->configurationKey.items[conf->configurationKey.count].readonly = true;
            conf->configurationKey.count++;
        }
        if (strcmp(req->key.items[i], "MeterValuesSampledData")==0) 
        {
            sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "MeterValuesSampledData");
            sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%s", Measurand_toString(buff, ocpp16_configkeys.coreProfile.MeterValuesSampledData));
            conf->configurationKey.items[conf->configurationKey.count].readonly = false;
            conf->configurationKey.count++;
        }
        if (strcmp(req->key.items[i], "MeterValuesSampledDataMaxLength")==0) 
        {
            sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "MeterValuesSampledDataMaxLength");
            sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%d", ocpp16_configkeys.coreProfile.MeterValuesSampledDataMaxLength);
            conf->configurationKey.items[conf->configurationKey.count].readonly = true;
            conf->configurationKey.count++;
        }
        if (strcmp(req->key.items[i], "MeterValueSampleInterval")==0) 
        {
            sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "MeterValueSampleInterval");
            sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%d", ocpp16_configkeys.coreProfile.MeterValueSampleInterval);
            conf->configurationKey.items[conf->configurationKey.count].readonly = false;
            conf->configurationKey.count++;
        }
        if (strcmp(req->key.items[i], "MinimumStatusDuration")==0) 
        {
            sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "MinimumStatusDuration");
            sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%d", ocpp16_configkeys.coreProfile.MinimumStatusDuration);
            conf->configurationKey.items[conf->configurationKey.count].readonly = false;
            conf->configurationKey.count++;
        }
        if (strcmp(req->key.items[i], "NumberOfConnectors")==0) 
        {
            sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "NumberOfConnectors");
            sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%d", ocpp16_configkeys.coreProfile.NumberOfConnectors);
            conf->configurationKey.items[conf->configurationKey.count].readonly = true;
            conf->configurationKey.count++;
        }
        if (strcmp(req->key.items[i], "ResetRetries")==0) 
        {
            sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "ResetRetries");
            sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%d", ocpp16_configkeys.coreProfile.ResetRetries);
            conf->configurationKey.items[conf->configurationKey.count].readonly = false;
            conf->configurationKey.count++;
        }
        if (strcmp(req->key.items[i], "StopTransactionOnEVSideDisconnect")==0) 
        {
            sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "StopTransactionOnEVSideDisconnect");
            sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%s", BOOL_toString(ocpp16_configkeys.coreProfile.StopTransactionOnEVSideDisconnect));
            conf->configurationKey.items[conf->configurationKey.count].readonly = false;
            conf->configurationKey.count++;
        }
        if (strcmp(req->key.items[i], "StopTransactionOnInvalidId")==0) 
        {
            sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "StopTransactionOnInvalidId");
            sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%s", BOOL_toString(ocpp16_configkeys.coreProfile.StopTransactionOnInvalidId));
            conf->configurationKey.items[conf->configurationKey.count].readonly = false;
            conf->configurationKey.count++;
        }
        if (strcmp(req->key.items[i], "StopTxnAlignedData")==0) 
        {
            sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "StopTxnAlignedData");
            sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%s", Measurand_toString(buff, ocpp16_configkeys.coreProfile.StopTxnAlignedData));
            conf->configurationKey.items[conf->configurationKey.count].readonly = false;
            conf->configurationKey.count++;
        }
        if (strcmp(req->key.items[i], "StopTxnAlignedDataMaxLength")==0) 
        {
            sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "StopTxnAlignedDataMaxLength");
            sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%d", ocpp16_configkeys.coreProfile.StopTxnAlignedDataMaxLength);
            conf->configurationKey.items[conf->configurationKey.count].readonly = true;
            conf->configurationKey.count++;
        }
        if (strcmp(req->key.items[i], "StopTxnSampledData")==0) 
        {
            sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "StopTxnSampledData");
            sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%s", Measurand_toString(buff, ocpp16_configkeys.coreProfile.StopTxnSampledData));
            conf->configurationKey.items[conf->configurationKey.count].readonly = false;
            conf->configurationKey.count++;
        }
        if (strcmp(req->key.items[i], "StopTxnSampledDataMaxLength")==0) 
        {
            sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "StopTxnSampledDataMaxLength");
            sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%d", ocpp16_configkeys.coreProfile.StopTxnSampledDataMaxLength);
            conf->configurationKey.items[conf->configurationKey.count].readonly = true;
            conf->configurationKey.count++;
        }
        if (strcmp(req->key.items[i], "SupportedFeatureProfiles")==0) 
        {
            sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "SupportedFeatureProfiles");
            sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%s", ocpp16_configkeys.coreProfile.SupportedFeatureProfiles);
            conf->configurationKey.items[conf->configurationKey.count].readonly = true;
            conf->configurationKey.count++;
        }
        if (strcmp(req->key.items[i], "SupportedFeatureProfilesMaxLength")==0) 
        {
            sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "SupportedFeatureProfilesMaxLength");
            sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%d", ocpp16_configkeys.coreProfile.SupportedFeatureProfilesMaxLength);
            conf->configurationKey.items[conf->configurationKey.count].readonly = true;
            conf->configurationKey.count++;
        }
        if (strcmp(req->key.items[i], "TransactionMessageAttempts")==0) 
        {
            sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "TransactionMessageAttempts");
            sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%d", ocpp16_configkeys.coreProfile.TransactionMessageAttempts);
            conf->configurationKey.items[conf->configurationKey.count].readonly = false;
            conf->configurationKey.count++;
        }
        if (strcmp(req->key.items[i], "TransactionMessageRetryInterval")==0) 
        {
            sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "TransactionMessageRetryInterval");
            sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%d", ocpp16_configkeys.coreProfile.TransactionMessageRetryInterval);
            conf->configurationKey.items[conf->configurationKey.count].readonly = false;
            conf->configurationKey.count++;
        }
        if (strcmp(req->key.items[i], "UnlockConnectorOnEVSideDisconnect")==0) 
        {
            sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "UnlockConnectorOnEVSideDisconnect");
            sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%s", BOOL_toString(ocpp16_configkeys.coreProfile.UnlockConnectorOnEVSideDisconnect));
            conf->configurationKey.items[conf->configurationKey.count].readonly = false;
            conf->configurationKey.count++;
        }
        if (strcmp(req->key.items[i], "WebSocketPingInterval")==0) 
        {
            sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "WebSocketPingInterval");
            sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%d", ocpp16_configkeys.coreProfile.WebSocketPingInterval);
            conf->configurationKey.items[conf->configurationKey.count].readonly = false;
            conf->configurationKey.count++;
        }
        if (strcmp(req->key.items[i], "AuthorizationKey")==0) 
        {
            sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "AuthorizationKey");
            sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%s", ocpp16_configkeys.coreProfile.AuthorizationKey);
            conf->configurationKey.items[conf->configurationKey.count].readonly = false;
            conf->configurationKey.count++;
        }
        if (strcmp(req->key.items[i], "AuthorizationCacheMaxLength")==0) 
        {
            sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "AuthorizationCacheMaxLength");
            sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%d", ocpp16_configkeys.coreProfile.AuthorizationCacheMaxLength);
            conf->configurationKey.items[conf->configurationKey.count].readonly = false;
            conf->configurationKey.count++;
        }
        if (strcmp(req->key.items[i], "LocalAuthListEnabled")==0) 
        {
            sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "LocalAuthListEnabled");
            sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%s", BOOL_toString(ocpp16_configkeys.localAuthListManagemenProfile.LocalAuthListEnabled));
            conf->configurationKey.items[conf->configurationKey.count].readonly = false;
            conf->configurationKey.count++;
        }
        if (strcmp(req->key.items[i], "LocalAuthListMaxLength")==0) 
        {
            sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "LocalAuthListMaxLength");
            sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%d", ocpp16_configkeys.localAuthListManagemenProfile.LocalAuthListMaxLength);
            conf->configurationKey.items[conf->configurationKey.count].readonly = true;
            conf->configurationKey.count++;
        }
        if (strcmp(req->key.items[i], "SendLocalListMaxLength")==0) 
        {
            sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "SendLocalListMaxLength");
            sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%d", ocpp16_configkeys.localAuthListManagemenProfile.SendLocalListMaxLength);
            conf->configurationKey.items[conf->configurationKey.count].readonly = true;
            conf->configurationKey.count++;
        }
        if (strcmp(req->key.items[i], "ReserveConnectorZeroSupported")==0) 
        {
            sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "ReserveConnectorZeroSupported");
            sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%s", BOOL_toString(ocpp16_configkeys.reservationProfile.ReserveConnectorZeroSupported));
            conf->configurationKey.items[conf->configurationKey.count].readonly = true;
            conf->configurationKey.count++;
        }
        if (strcmp(req->key.items[i], "ChargeProfileMaxStackLevel")==0) 
        {
            sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "ChargeProfileMaxStackLevel");
            sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%d", ocpp16_configkeys.smartChargingProfile.ChargeProfileMaxStackLevel);
            conf->configurationKey.items[conf->configurationKey.count].readonly = true;
            conf->configurationKey.count++;
        }
        if (strcmp(req->key.items[i], "ChargingScheduleAllowedChargingRateUnit")==0) 
        {
            sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "ChargingScheduleAllowedChargingRateUnit");
            sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%d", ChargingScheduleAllowedChargingRateUnit_toString(buff, ocpp16_configkeys.smartChargingProfile.ChargingScheduleAllowedChargingRateUnit));
            conf->configurationKey.items[conf->configurationKey.count].readonly = true;
            conf->configurationKey.count++;
        }
        if (strcmp(req->key.items[i], "ChargingScheduleMaxPeriods")==0) 
        {
            sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "ChargingScheduleMaxPeriods");
            sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%d", ocpp16_configkeys.smartChargingProfile.ChargingScheduleMaxPeriods);
            conf->configurationKey.items[conf->configurationKey.count].readonly = true;
            conf->configurationKey.count++;
        }
        if (strcmp(req->key.items[i], "ConnectorSwitch3to1PhaseSupported")==0) 
        {
            sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "ConnectorSwitch3to1PhaseSupported");
            sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%s", BOOL_toString(ocpp16_configkeys.smartChargingProfile.ConnectorSwitch3to1PhaseSupported));
            conf->configurationKey.items[conf->configurationKey.count].readonly = true;
            conf->configurationKey.count++;
        }
        if (strcmp(req->key.items[i], "MaxChargingProfilesInstalled")==0) 
        {
            sprintf(conf->configurationKey.items[conf->configurationKey.count].key, "MaxChargingProfilesInstalled");
            sprintf(conf->configurationKey.items[conf->configurationKey.count].value, "%d", ocpp16_configkeys.smartChargingProfile.MaxChargingProfilesInstalled);
            conf->configurationKey.items[conf->configurationKey.count].readonly = true;
            conf->configurationKey.count++;
        }
        if (conf->configurationKey.count <= findkey)
        {
            sprintf(conf->unknownKey.items[conf->unknownKey.count++], "%s", req->key.items[i]);
        }
    }
    printv("conf->configurationKey.count:%d, conf->unknownKey.count:%d\n", conf->configurationKey.count, conf->unknownKey.count);
    return 0;
}

int ocpp16_GetDiagnostics_confirm(ocpp_client_t* dev, GetDiagnosticsReq_t* req, GetDiagnosticsConf_t* conf)
{
    memset(conf, 0, sizeof(GetDiagnosticsConf_t));
    if (req->startTime<=0){
        dev->diagnosticsReq.startTime = time(NULL);
    }else{
        dev->diagnosticsReq.startTime = req->startTime;
    }
    if (req->stopTime<=0){
        dev->diagnosticsReq.stopTime = time(NULL);
    }else{
        dev->diagnosticsReq.stopTime = req->stopTime;
    }
    if (dev->diagnosticsReq.startTime>=0 && dev->diagnosticsReq.stopTime>=0 && dev->diagnosticsReq.startTime <= dev->diagnosticsReq.stopTime)
    {
        sprintf(dev->diagnosticsReq.location, "%s", req->location);
        if (dev->diagnosticsReq.retries < 1) dev->diagnosticsReq.retries = 1;
        if (dev->diagnosticsReq.retryInterval < 1) dev->diagnosticsReq.retryInterval = 1;
        sprintf(conf->fileName, "/home/root/app_run/log/*.log");
        dev->need_diagnostics = 1;
    }
    return 0;
}

int ocpp16_GetLocalListVersion_confirm(ocpp_client_t* dev, GetLocalListVersionReq_t* req, GetLocalListVersionConf_t* conf)
{
    memset(conf, 0, sizeof(GetLocalListVersionConf_t));
    conf->listVersion = 1;
    return 0;
}

int ocpp16_RemoteStartTransaction_confirm(ocpp_client_t* dev, RemoteStartTransactionReq_t* req, RemoteStartTransactionConf_t* conf)
{
    ccu_port_t *ccu = (ccu_port_t*)dev->ccu;
    secc_port_t *seccA = (secc_port_t*)ccu->seccA;
    secc_port_t *seccB = (secc_port_t*)ccu->seccB;
    int ret = 0;
    uint32_t request_KWh = ocpp16_configkeys.coreProfile.MaxEnergyOnInvalidId;
    if (req->connectorId == 0){
        if (seccA->GUN_Error == GUN_RESERVED)
        {
            if (strcmp(seccA->reserve_emaid, req->idTag) == 0)
            {
                ret = secc_eim_startup(seccA, req->idTag, request_KWh, 0, 0);
            }
        }
        if (seccB->GUN_Error == GUN_RESERVED)
        {
            if (strcmp(seccB->reserve_emaid, req->idTag) == 0)
            {
                ret = secc_eim_startup(seccB, req->idTag, request_KWh, 0, 0);
            }
        }
    }
    if (req->connectorId == 1){ 
        if (seccA->GUN_Error == GUN_RESERVED)
        {
            if (strcmp(seccA->reserve_emaid, req->idTag) == 0)
            {
                ret = secc_eim_startup(seccA, req->idTag, request_KWh, 0, 0);
            }
        }else{
            ret = secc_eim_startup(seccA, req->idTag, request_KWh, 0, 0); 
        }
        if (req->chargingProfile_used && req->chargingProfile.chargingProfilePurpose == ChargingProfilePurposeType_TxProfile)
        {
            ocpp16_set_ChargingProfiles(&req->chargingProfile, 1);
        }
    }
    if (req->connectorId == 2){ 
        if (seccB->GUN_Error == GUN_RESERVED)
        {
            if (strcmp(seccB->reserve_emaid, req->idTag) == 0)
            {
                ret = secc_eim_startup(seccB, req->idTag, request_KWh, 0, 0);
            }
        }else{
            ret = secc_eim_startup(seccB, req->idTag, request_KWh, 0, 0); 
        }
        if (req->chargingProfile_used && req->chargingProfile.chargingProfilePurpose == ChargingProfilePurposeType_TxProfile)
        {
            ocpp16_set_ChargingProfiles(&req->chargingProfile, 2);
        }
    }
    printd("ret = %d\n", ret);
    if (ret==0)
    {
        conf->status = RemoteStartStopStatus_Accepted;
    }else{
        conf->status = RemoteStartStopStatus_Rejected;
    }
    return 0;
}

int ocpp16_RemoteStopTransaction_confirm(ocpp_client_t* dev, RemoteStopTransactionReq_t* req, RemoteStopTransactionConf_t* conf)
{
    ccu_port_t *ccu = (ccu_port_t*)dev->ccu;
    secc_port_t *seccA = (secc_port_t*)ccu->seccA;
    secc_port_t *seccB = (secc_port_t*)ccu->seccB;
    int ret = 0;
    if (req->transactionId == seccA->transactionId && req->transactionId!=0){ ret = secc_eim_shutdown(seccA); }
    if (req->transactionId == seccB->transactionId && req->transactionId!=0){ ret = secc_eim_shutdown(seccB); }
    printd("ret = %d\n", ret);
    if (ret==0)
    {
        conf->status = RemoteStartStopStatus_Accepted;
    }else{
        conf->status = RemoteStartStopStatus_Rejected;
    }
    return 0;
}

int ocpp16_ReserveNow_confirm(ocpp_client_t* dev, ReserveNowReq_t* req, ReserveNowConf_t* conf)
{
    ccu_port_t *ccu = (ccu_port_t*)dev->ccu;
    secc_port_t *seccA = (secc_port_t*)ccu->seccA;
    secc_port_t *seccB = (secc_port_t*)ccu->seccB;
    secc_port_t *secc = NULL;
    conf->status = ReservationStatus_Rejected;
    if (req->connectorId == 1){ secc = (secc_port_t*)ccu->seccA; }
    if (req->connectorId == 2){ secc = (secc_port_t*)ccu->seccB; }

    if (secc && req->expiryDate > (time(NULL)+5*60))
    {
        if (ccu->config->CCU_Available != 1 || secc->config->GUN_Available != 1)
        {
            conf->status = ReservationStatus_Unavailable;
            return 0;
        }
        if (secc->GUN_Error == GUN_RESERVED)
        {
            conf->status = ReservationStatus_Occupied;
            return 0;
        }
        if (secc->GUN_Error != 0)
        {
            conf->status = ReservationStatus_Faulted;
            return 0;
        }
        if (secc->GUN_State != GUN_NORMAL)
        {
            conf->status = ReservationStatus_Occupied;
            return 0;
        }
        if (secc_reserveNow(secc, req->idTag, req->expiryDate, req->reservationId) == 0)
        {
            conf->status = ReservationStatus_Accepted;
        }
    }
    return 0;
}

int ocpp16_Reset_confirm(ocpp_client_t* dev, ResetReq_t* req, ResetConf_t* conf)
{
    dev->need_reset = req->type;
    return 0;
}

int ocpp16_SendLocalList_confirm(ocpp_client_t* dev, SendLocalListReq_t* req, SendLocalListConf_t* conf)
{
    int i;
    ccu_port_t *ccu = (ccu_port_t*)dev->ccu;
    if (req->updateType == UpdateType_Full)
    {
        localAuthorizationList.count = 0;
        for (i=0; i<req->localAuthorizationList.count; i++)
        {
            ocpp16_LocalAuthorizationList_append(req->localAuthorizationList.items[i].idTag, req->localAuthorizationList.items[i].idTagInfo.parentIdTag, req->localAuthorizationList.items[i].idTagInfo.expiryDate, req->localAuthorizationList.items[i].idTagInfo.status);
        }
    }
    if (req->updateType == UpdateType_Differential)
    {
        for (i=0; i<req->localAuthorizationList.count; i++)
        {
            ocpp16_LocalAuthorizationList_append(req->localAuthorizationList.items[i].idTag, req->localAuthorizationList.items[i].idTagInfo.parentIdTag, req->localAuthorizationList.items[i].idTagInfo.expiryDate, req->localAuthorizationList.items[i].idTagInfo.status);
        }
    }
    return 0;
}

int ocpp16_SetChargingProfile_confirm(ocpp_client_t* dev, SetChargingProfileReq_t* req, SetChargingProfileConf_t* conf)
{
    conf->status =  ChargingProfileStatus_NotSupported;
    if (ocpp16_set_ChargingProfiles(&req->csChargingProfiles, req->connectorId)==0)
    {
        conf->status =  ChargingProfileStatus_Accepted;
    }else{
        conf->status =  ChargingProfileStatus_Rejected;
    }
    return 0;
}

int ocpp16_TriggerMessage_confirm(ocpp_client_t* dev, TriggerMessageReq_t* req, TriggerMessageConf_t* conf)
{
    conf->status = TriggerMessageStatus_Rejected;
    if (req->connectorId){}
    switch(req->requestedMessage)
    {
        case MessageTrigger_BootNotification:
        case MessageTrigger_DiagnosticsStatusNotification:
        case MessageTrigger_FirmwareStatusNotification:
        case MessageTrigger_Heartbeat: {
            dev->trigger_flag = 1<<req->requestedMessage;
            conf->status = TriggerMessageStatus_Accepted;
        }break;
        case MessageTrigger_MeterValues:{
            if (req->connectorId == 0 || req->connectorId == 1)
            {
                dev->trigger_flag = 1<<MessageTrigger_MeterValues;
                conf->status = TriggerMessageStatus_Accepted;
            }
            if (req->connectorId == 0 || req->connectorId == 2)
            {
                dev->trigger_flag = 1<<MessageTrigger_MeterValues7;
                conf->status = TriggerMessageStatus_Accepted;
            }
        }break;
        case MessageTrigger_StatusNotification:{
            if (req->connectorId == 0 || req->connectorId == 1)
            {
                dev->trigger_flag = 1<<MessageTrigger_StatusNotification;
                conf->status = TriggerMessageStatus_Accepted;
            }
            if (req->connectorId == 0 || req->connectorId == 2)
            {
                dev->trigger_flag = 1<<MessageTrigger_StatusNotification8;
                conf->status = TriggerMessageStatus_Accepted;
            }
            conf->status = TriggerMessageStatus_Accepted;
        }break;
    }
    return 0;
}

int ocpp16_UnlockConnector_confirm(ocpp_client_t* dev, UnlockConnectorReq_t* req, UnlockConnectorConf_t* conf)
{
    ccu_port_t *ccu = (ccu_port_t*)dev->ccu;
    secc_port_t *seccA = (secc_port_t*)ccu->seccA;
    secc_port_t *seccB = (secc_port_t*)ccu->seccB;
    conf->status = UnlockStatus_NotSupported;
    if (req->connectorId == 1)
    {
        if (seccA->GUN_Error != 0 && seccA->GUN_State == GUN_PLUGIN)
        {
            seccA->set_PWM_ratio(seccA, 100);
            seccA->set_Aux12V_state(seccA, 0);
            if (seccA->set_K1K2_state(seccA, 0, 1000) == 1)
                conf->status = UnlockStatus_Unlocked;
            else
                conf->status = UnlockStatus_UnlockFailed;
        }
    }
    if (req->connectorId == 2) 
    {
        if (seccB->GUN_Error != 0 && seccB->GUN_State == GUN_PLUGIN)
        {
            seccB->set_PWM_ratio(seccB, 100);
            seccB->set_Aux12V_state(seccB, 0);
            if (seccB->set_K1K2_state(seccB, 0, 1000) == 1)
                conf->status = UnlockStatus_Unlocked;
            else
                conf->status = UnlockStatus_UnlockFailed;
        }
    }
    return 0;
}

int ocpp16_UpdateFirmware_confirm(ocpp_client_t* dev, UpdateFirmwareReq_t* req, UpdateFirmwareConf_t* conf)
{
    if (strstr(req->location, "app_")!=NULL)
    {
        sprintf(dev->updateFirmware.location, "%s", req->location);
        dev->updateFirmware.retries = req->retries;
        dev->updateFirmware.retryInterval = req->retryInterval;
        if (dev->updateFirmware.retries < 1) dev->updateFirmware.retries = 1;
        if (dev->updateFirmware.retryInterval < 1) dev->updateFirmware.retryInterval = 1;
        dev->need_updatefirmware = 1;
        return 0;
    }else{
        return -1;
    }
}
