123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893 |
- /*====================================================================*
- Copyright (c) 2021 Qualcomm Technologies, Inc.
- All Rights Reserved.
- Confidential and Proprietary - Qualcomm Technologies, Inc.
- *--------------------------------------------------------------------*/
- /*====================================================================*
- *
- * pev1.c - QCA Plug-in Electric Vehicle Emulator;
- *
- * This program, in the current state, is not a finished product;
- * It has been released so that interested parties can begin to
- * see how the SLAC protocol might be implemented;
- *
- * Some key design features are:
- *
- * 1) the use of a channel variable to abstract ISO Layer 2 I/O;
- * the variable is used by functions openchannel, readmessage,
- * sendmessage and closechannel;
- *
- * 2) the use of a message variable to represent an IEEE 802.3
- * Ethernet frame; the variable allows one frame to be used
- * and re-used throughout the program but supports multiple
- * frame buffers if needed;
- *
- * 3) the use of a session variable to support multiple PEV-EVSE
- * interactions without using threads or subrocesses; this has
- * not demonstrated in this version of the program; some more
- * work is needed;
- *
- * 4) the absence of threads or subprocesses so that the program
- * can be ported to hosts without a multi-tasking operating
- * system;
- *
- * 5) lots of debugging messages; these can be suppressed or
- * deleted if not wanted;
- *
- * 6) extened state machine incorporating HAR MME handler;
- *
- *--------------------------------------------------------------------*/
- /*====================================================================*
- * system header files;
- *--------------------------------------------------------------------*/
- #include <unistd.h>
- #include <stdlib.h>
- #include <limits.h>
- #include <string.h>
- #include <errno.h>
- #include <time.h>
- /*====================================================================*
- * custom header files;
- *--------------------------------------------------------------------*/
- #include "../tools/getoptv.h"
- #include "../tools/putoptv.h"
- #include "../tools/memory.h"
- #include "../tools/number.h"
- #include "../tools/types.h"
- #include "../tools/flags.h"
- #include "../tools/files.h"
- #include "../tools/error.h"
- #include "../tools/config.h"
- #include "../ether/channel.h"
- #include "../slac/slac.h"
- #include "../plc/plc.h"
- /*====================================================================*
- * custom source files;
- *--------------------------------------------------------------------*/
- #ifndef MAKEFILE
- #include "../tools/getoptv.c"
- #include "../tools/putoptv.c"
- #include "../tools/version.c"
- #include "../tools/hexdump.c"
- #include "../tools/hexdecode.c"
- #include "../tools/hexencode.c"
- #include "../tools/hexstring.c"
- #include "../tools/decdecode.c"
- #include "../tools/decstring.c"
- #include "../tools/uintspec.c"
- #include "../tools/todigit.c"
- #include "../tools/strfbits.c"
- #include "../tools/config.c"
- #include "../tools/memincr.c"
- #include "../tools/debug.c"
- #include "../tools/error.c"
- #endif
- #ifndef MAKEFILE
- #include "../plc/Devices.c"
- #endif
- #ifndef MAKEFILE
- #include "../mme/EthernetHeader.c"
- #include "../mme/QualcommHeader.c"
- #include "../mme/HomePlugHeader1.c"
- #include "../mme/UnwantedMessage.c"
- #include "../mme/readmessage.c"
- #include "../mme/sendmessage.c"
- #endif
- #ifndef MAKEFILE
- #include "../ether/channel.c"
- #include "../ether/openchannel.c"
- #include "../ether/closechannel.c"
- #include "../ether/sendpacket.c"
- #include "../ether/readpacket.c"
- #endif
- #ifndef MAKEFILE
- #include "../slac/slac_session.c"
- #include "../slac/slac_connect.c"
- #include "../slac/pev_cm_slac_param.c"
- #include "../slac/pev_cm_start_atten_char.c"
- #include "../slac/pev_cm_atten_char.c"
- #include "../slac/pev_cm_mnbc_sound.c"
- #include "../slac/pev_cm_slac_match.c"
- #include "../slac/pev_cm_set_key.c"
- #endif
- /*====================================================================*
- * program constants;
- *--------------------------------------------------------------------*/
- #define PLCDEVICE "PLC"
- #define PROFILE "pev.ini"
- #define SECTION "default"
- #define PEV_STATE_INIT 0
- #define PEV_STATE_RESET 1
- #define PEV_STATE_SLAC_PARAM_EXCHANGE 2
- #define PEV_STATE_SOUNDING 3
- #define PEV_STATE_ATTENUATION_PROFILE 4
- #define PEV_STATE_SLAC_MATCH 5
- #define PEV_STATE_CHARGING 6
- //states 7-31 is reserved for any future slac transactions/MMEs
- #define PEV_STATE_HAR_LOADER 32
- #define PEV_STATE_HAR_FIRMWARE 33
- #define PEV_STATE_HAR_PIB 34
- #define PEV_STATE_HAR_FW_PIB 35
- #define PEV_STATE_HAR_LOADER_SDRAM 36
- #define PEV_STATE_HAR_RESET_FACTORY_DEFAULT 37
- #define PEV_STATE_HAR_BACKGROUND_PIB 38
- #define PEV_STATE_HAR_DEVICE_REBOOTED 39
- #define PEV_STATE_HAR_HIF_READY 40
- #define PEV_STATE_HAR_POWERLINE_READY 41
- #define PEV_STATE_HAR_AVLN_READY_PEER_AVAILABLE 42
- #define PEV_STATE_HAR_LINKLOSS 43
- #define PEV_VID "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" // VehicleIdentifier
- #define PEV_NMK "50E3F4934F855F7040784EA815CE9FA5" // Random NMK
- #define PEV_NID "B0F2E695666B03" // HomePlugAV
- /*====================================================================*
- * program variables;
- *--------------------------------------------------------------------*/
- unsigned prev_session_state = 0;
- unsigned charging_time = SLAC_CHARGETIME;
- unsigned no_of_slac_loop = SLAC_LOOP;
- /*====================================================================*
- *
- * static void configure ();
- *
- * print template PEV-HLE configuration file on stdout so that
- * profile, section and element names match;
- *
- *--------------------------------------------------------------------*/
- static void configure ()
- {
- printf ("# file: %s\n", PROFILE);
- printf ("# ====================================================================\n");
- printf ("# PEV-HLE initialization;\n");
- printf ("# --------------------------------------------------------------------\n");
- printf ("[%s]\n", SECTION);
- printf ("vehicle identifier = %s\n", PEV_VID);
- printf ("network membership key = %s\n", PEV_NMK);
- printf ("network identifier = %s\n", PEV_NID);
- printf ("attenuation threshold = %d\n", SLAC_LIMIT);
- printf ("msound pause = %d\n", SLAC_PAUSE);
- printf ("charge time = %d\n", charging_time);
- printf ("settle time = %d\n", SLAC_SETTLETIME);
- return;
- }
- /*====================================================================*
- *
- * void initialize (struct session * session, char const * profile, char const * section);
- *
- * read PEV-HLE configuration profile; initialize session variable;
- *
- *--------------------------------------------------------------------*/
- static void initialize (struct session * session, char const * profile, char const * section)
- {
- session->next = session->prev = session;
- hexencode (session->PEV_ID, sizeof (session->PEV_ID), configstring (profile, section, "VehicleIdentifier", PEV_VID));
- hexencode (session->NMK, sizeof (session->NMK), configstring (profile, section, "NetworkMembershipKey", PEV_NMK));
- hexencode (session->NID, sizeof (session->NID), configstring (profile, section, "NetworkIdentifier", PEV_NID));
- session->limit = confignumber (profile, section, "AttenuationThreshold", SLAC_LIMIT);
- session->pause = confignumber (profile, section, "MSoundPause", SLAC_PAUSE);
- session->settletime = confignumber (profile, section, "SettleTime", SLAC_SETTLETIME);
- session->chargetime = confignumber (profile, section, "ChargeTime", charging_time);
- session->state = PEV_STATE_INIT;
- memcpy (session->original_nmk, session->NMK, sizeof (session->original_nmk));
- memcpy (session->original_nid, session->NID, sizeof (session->original_nid));
- slac_session (session);
- return;
- }
- /*====================================================================*
- *
- * signed identifier (struct session * session, struct channel * channel);
- *
- * generate the run identifier and store in session variable;
- *
- * copy channel host address to session PEV MAC address; set session
- * PEV identifier to zeros;
- *
- *--------------------------------------------------------------------*/
- static signed identifier (struct session * session, struct channel * channel)
- {
- time_t now;
- time (& now);
- memset (session->RunID, 0, sizeof (session->RunID));
- memcpy (session->RunID, channel->host, ETHER_ADDR_LEN);
- memcpy (session->PEV_MAC, channel->host, sizeof (session->PEV_MAC));
- return (0);
- }
- unsigned int get_session_state(struct plc* plc, unsigned int cur_session_state)
- {
- struct message* message = (struct message*)(plc->message);
- #ifndef __GNUC__
- #pragma pack (push,1)
- #endif
- struct __packed vs_host_action_ind
- {
- struct ethernet_hdr ethernet;
- struct qualcomm_hdr qualcomm;
- uint8_t MACTION;
- uint8_t MAJOR_VERSION;
- uint8_t MINOR_VERSION;
- uint8_t session_id;
- uint16_t outstanding_retries;
- uint16_t retrytimer_in10ms;
- }
- *indicate = (struct vs_host_action_ind*)(message);
- #ifndef __GNUC__
- #pragma pack (pop)
- #endif
- unsigned int state;
- signed action = indicate->MACTION;
- switch (action)
- {
- case 0:
- state = PEV_STATE_HAR_LOADER;
- break;
- case 1:
- state = PEV_STATE_HAR_FIRMWARE;
- break;
- case 2:
- state = PEV_STATE_HAR_PIB;
- break;
- case 3:
- state = PEV_STATE_HAR_FW_PIB;
- break;
- case 4:
- state = PEV_STATE_HAR_LOADER_SDRAM;
- break;
- case 6:
- state = PEV_STATE_HAR_BACKGROUND_PIB;
- break;
- case 7:
- state = PEV_STATE_HAR_DEVICE_REBOOTED;
- break;
- case 8:
- state = PEV_STATE_HAR_HIF_READY;
- break;
- case 9:
- state = PEV_STATE_HAR_POWERLINE_READY;
- break;
- case 10:
- state = PEV_STATE_HAR_AVLN_READY_PEER_AVAILABLE;
- break;
- case 11:
- state = PEV_STATE_HAR_LINKLOSS;
- break;
- default:
- debug(1, 0, "Unhandled HAR message");
- break;
- }
- return state;
- }
- void set_session_state(struct session* session, unsigned int state)
- {
- prev_session_state = session->state;
- session->state = state;
- }
- signed mme_to_pev_state(struct session* session, struct plc* plc, uint16_t MMTYPE)
- {
- switch (MMTYPE)
- {
- case (CM_SLAC_PARAM | MMTYPE_CNF):
- set_session_state(session, PEV_STATE_SLAC_PARAM_EXCHANGE);
- break;
- case (CM_ATTEN_CHAR | MMTYPE_IND):
- set_session_state(session, PEV_STATE_ATTENUATION_PROFILE);
- break;
- case (CM_SLAC_MATCH | MMTYPE_CNF):
- set_session_state(session, PEV_STATE_SLAC_MATCH);
- break;
- case (VS_HOST_ACTION | MMTYPE_IND):
- set_session_state(session, get_session_state(plc, session->state));
- break;
- default:
- return (-1);
- break;
- }
- return 0;
- }
- /*====================================================================*
- *
- * int main (int argc, char * argv[]);
- *
- *
- *--------------------------------------------------------------------*/
- int main (int argc, char const * argv [])
- {
- extern struct channel channel;
- static char const * optv [] =
- {
- "cCdFi:l:n:N:p:P:qr:s:S:t:T:vw:x",
- "",
- "Qualcomm Atheros Plug-in Electric Vehicle Emulator",
- "c\tprint template configuration file on stdout",
- "C\tstop on count mismatch",
- "d\tdisplay debug information",
- "F\tflash non-volatile memory",
- #if defined (WINPCAP) || defined (LIBPCAP)
- "i n\thost interface is (n) [" LITERAL (CHANNEL_ETHNUMBER) "]",
- #else
- "i s\thost interface is (s) [" LITERAL (CHANNEL_ETHDEVICE) "]",
- #endif
- "l n\tloop slac (n) times [" LITERAL(SLAC_LOOP) "]",
- "n f\tuser firmware file is (f)",
- "N f\tfirmware file is (f)",
- "p f\tuser parameter file is (f)",
- "P f\tparameter file is (f)",
- "q\tsuppress normal output",
- "r s\tconfiguration profile is (s) [" LITERAL(PROFILE) "]",
- "s s\tconfiguration section is (s) [" LITERAL(SECTION) "]",
- "S f\tsoftloader file is (f)",
- "t n\tread timeout is (n) milliseconds [" LITERAL (SLAC_TIMEOUT) "]",
- "T n\tcharging time is (n) seconds [" LITERAL(SLAC_CHARGETIME) "]",
- "v\tverbose messages on stdout",
- "x\texit on error",
- (char const *) (0)
- };
- #include "../plc/plc.c"
- struct session session;
- struct message message;
- char const * profile = PROFILE;
- char const * section = SECTION;
- struct homeplug1* homeplug;
- uint16_t MMType;
- char firmware[PLC_VERSION_STRING];
- signed c;
- memset (& session, 0, sizeof (session));
- memset (& message, 0, sizeof (message));
- channel.timeout = SLAC_TIMEOUT;
- if (getenv (PLCDEVICE))
- {
- #if defined (WINPCAP) || defined (LIBPCAP)
- channel.ifindex = atoi (getenv (PLCDEVICE));
- #else
- channel.ifname = strdup (getenv (PLCDEVICE));
- #endif
- }
- optind = 1;
- while (~ (c = getoptv (argc, argv, optv)))
- {
- switch (c)
- {
- case 'c':
- configure ();
- return (0);
- case 'C':
- _setbits (session.flags, SLAC_COMPARE);
- break;
- case 'd':
- _setbits (session.flags, (SLAC_VERBOSE | SLAC_SESSION));
- break;
- case 'F':
- _setbits(plc.flags, PLC_FLASH_DEVICE);
- break;
- case 'i':
- #if defined (WINPCAP) || defined (LIBPCAP)
- channel.ifindex = atoi (optarg);
- #else
- channel.ifname = optarg;
- #endif
- break;
- case 'l':
- no_of_slac_loop = (unsigned)(uintspec(optarg, 0, UINT_MAX));
- break;
- case 'n':
- if (!checkfilename(optarg))
- {
- error(1, EINVAL, "%s", optarg);
- }
- if ((plc.nvm.file = open(plc.nvm.name = optarg, O_BINARY | O_CREAT | O_RDWR | O_TRUNC, FILE_FILEMODE)) == -1)
- {
- error(1, errno, "%s", plc.nvm.name);
- }
- break;
- case 'N':
- if (!checkfilename(optarg))
- {
- error(1, EINVAL, "%s", optarg);
- }
- if ((plc.NVM.file = open(plc.NVM.name = optarg, O_BINARY | O_RDONLY)) == -1)
- {
- error(1, errno, "%s", plc.NVM.name);
- }
- if (panther_nvm_file(&plc.NVM))
- {
- error(1, errno, "Bad panther image file: %s", plc.NVM.name);
- }
- break;
- case 'p':
- if (!checkfilename(optarg))
- {
- error(1, EINVAL, "%s", optarg);
- }
- if ((plc.pib.file = open(plc.pib.name = optarg, O_BINARY | O_CREAT | O_RDWR | O_TRUNC, FILE_FILEMODE)) == -1)
- {
- error(1, errno, "%s", plc.pib.name);
- }
- break;
- case 'P':
- if (!checkfilename(optarg))
- {
- error(1, EINVAL, "%s", optarg);
- }
- if ((plc.PIB.file = open(plc.PIB.name = optarg, O_BINARY | O_RDONLY)) == -1)
- {
- error(1, errno, "%s", plc.PIB.name);
- }
- if (panther_pib_file(&plc.PIB))
- {
- error(1, errno, "Bad panther parameter file: %s", plc.PIB.name);
- }
- break;
- case 'q':
- _clrbits(channel.flags, CHANNEL_SILENCE);
- break;
- case 'r':
- profile = optarg;
- break;
- case 's':
- section = optarg;
- break;
- case 'S':
- if (!checkfilename(optarg))
- {
- error(1, EINVAL, "%s", optarg);
- }
- if ((plc.SFT.file = open(plc.SFT.name = optarg, O_BINARY | O_RDONLY)) == -1)
- {
- error(1, errno, "%s", plc.SFT.name);
- }
- if (panther_nvm_file(&plc.SFT))
- {
- error(1, errno, "Bad panther image file: %s", plc.SFT.name);
- }
- break;
- case 't':
- channel.timeout = (unsigned) (uintspec (optarg, 0, UINT_MAX));
- break;
- case 'T':
- charging_time = (unsigned)(uintspec(optarg, 0, UINT_MAX));
- break;
- case 'v':
- _setbits (channel.flags, CHANNEL_VERBOSE);
- break;
- case 'x':
- session.exit = session.exit? 0: 1;
- break;
- default:
- break;
- }
- }
- argc -= optind;
- argv += optind;
- if (argc)
- {
- debug (1, __func__, ERROR_TOOMANY);
- }
- openchannel (& channel);
- identifier (& session, & channel);
- initialize (& session, profile, section);
- plc.channel = &channel;
- plc.message = &message;
- if (_anyset(session.flags, SLAC_VERBOSE))
- {
- _setbits(plc.flags, PLC_VERBOSE);
- }
- bool wait_in_loop_for_mme = true;
- bool identity_requested = false;
- bool identity_received = false;
- bool evse_slac_matched = false;
- for (unsigned int iteration = 0; iteration < no_of_slac_loop; iteration++)
- {
- printf("iteration = %d\n", iteration);
- if ((session.state == PEV_STATE_INIT) || (session.state == PEV_STATE_HAR_LINKLOSS))
- {
- sleep(session.settletime);
- if (WaitForStart(&plc, firmware, sizeof(firmware)))
- {
- Failure(&plc, PLC_NODETECT);
- exit(1);
- }
- if (strcmp(firmware, "BootLoader"))
- {
- printf("Device not in bootloader mode. ChipID 0x%0x\n", plc.hardwareID);
- //Randomize the NMK
- plc.pushbutton = 2;
- if (PushButton(&plc))
- {
- printf("Failed to randomize\n");
- exit(1);
- }
- else
- {
- memset(firmware, 0, sizeof(firmware));
- if (WaitForStart(&plc, firmware, sizeof(firmware)))
- {
- Failure(&plc, PLC_NODETECT);
- exit(1);
- }
- else
- {
- session.state = PEV_STATE_RESET;
- }
- }
- }
- else {
- if (plc.PIB.file == -1)
- {
- error(1, ECANCELED, "No PIB file specified");
- }
- if (plc.NVM.file == -1)
- {
- error(1, ECANCELED, "No NVM file specified");
- }
- if (plc.SFT.file == -1)
- {
- error(1, ECANCELED, "No Softloader file specified");
- }
- }
- }
- while (true && (session.state != PEV_STATE_HAR_LINKLOSS))
- {
- if (wait_in_loop_for_mme)
- {
- while ((plc.packetsize = readpacket(&channel, &message, sizeof(message))) >= 0)
- {
- homeplug = (struct homeplug1*)(&message);
- MMType = homeplug->homeplug.MMTYPE;
- if (!UnwantedMessage(&message, plc.packetsize, homeplug->homeplug.MMV, MMType))
- {
- if (MMType == (CM_SET_KEY | MMTYPE_CNF))
- {
- if (pev_cm_set_key_cnf(&session, &channel, &message))
- {
- //handle failure of set key gracefully instead of exiting
- debug(1, __func__, "Can't set key");
- }
- if (session.state == PEV_STATE_SLAC_MATCH)
- {
- evse_slac_matched = true;
- }
- }
- else if (MMType == (VS_MODULE_OPERATION | MMTYPE_CNF))
- {
- if (process_get_nid_cnf(&plc, session.original_nid, session.original_nmk))
- {
- debug(1, __func__, "Error in getting NMK & NID");
- }
- identity_received = true;
- if (session.state == PEV_STATE_HAR_POWERLINE_READY)
- {
- break;
- }
- }
- else if (mme_to_pev_state(&session, &plc, MMType) == 0)
- {
- debug(0, __func__, "Received required MME. Break the read loop! MMTYPE %0x", MMType);
- break;
- }
- }
- }
- if (MMType == (VS_HOST_ACTION | MMTYPE_IND))
- {
- //Send HAR response
- vs_host_action_response(&plc);
- }
- }
- else
- {
- wait_in_loop_for_mme = true;
- }
- switch (session.state)
- {
- case PEV_STATE_SLAC_PARAM_EXCHANGE:
- if (pev_cm_slac_param_cnf(&session, &channel, &message))
- {
- debug(1, __func__, "Error in slac parameter exchange confirm");
- }
- //Move to sounding state from here and make wait_in_loop_for_mme false
- prev_session_state = session.state;
- session.state = PEV_STATE_SOUNDING;
- wait_in_loop_for_mme = false;
- break;
- case PEV_STATE_SOUNDING:
- if (pev_cm_start_atten_char(&session, &channel, &message))
- {
- debug(1, __func__, "Error in start attenuation char indication");
- }
- if (pev_cm_mnbc_sound(&session, &channel, &message))
- {
- debug(1, __func__, "Error in sounding");
- }
- break;
- case PEV_STATE_ATTENUATION_PROFILE:
- if (pev_cm_atten_char_process(&session, &channel, &message))
- {
- debug(1, __func__, "Error in decoding attenuation MME");
- }
- if (slac_connect(&session))
- {
- debug(1, __func__, "Calculated attenuation not in range");
- }
- if (pev_cm_slac_match_req(&session, &channel, &message))
- {
- debug(1, __func__, "Error in sending slac match");
- }
- break;
- case PEV_STATE_SLAC_MATCH:
- if (pev_cm_slac_match_cnf(&session, &channel, &message))
- {
- debug(1, __func__, "Error in decoding slac match");
- }
- if (pev_cm_set_key_req(&session, &channel, &message))
- {
- //handle failure of set key gracefully instead of exiting
- debug(1, __func__, "Can't set key in slac match");
- }
- break;
- case PEV_STATE_CHARGING:
- debug(0, __func__, "Charging (%d) ...\n\n", session.counter++);
- sleep(session.chargetime);
- debug(0, __func__, "Disconnecting ...");
- memcpy(session.NMK, session.original_nmk, sizeof(session.NMK));
- memcpy(session.NID, session.original_nid, sizeof(session.NID));
- if (pev_cm_set_key_req(&session, &channel, &message))
- {
- debug(1, __func__, "Can't set key");
- }
- break;
- case PEV_STATE_HAR_LOADER:
- //load FW and PIB
- debug(0, __func__, "HAR event 0x00. Boot device!");
- if (BootDevice2_no_wait(&plc))
- {
- return (-1);
- }
- if (_anyset(plc.flags, PLC_FLASH_DEVICE))
- {
- if (WaitForStart(&plc, firmware, sizeof(firmware)))
- {
- return (-1);
- }
- FlashDevice2_no_wait(&plc, (PLC_COMMIT_FORCE | PLC_COMMIT_NORESET | PLC_COMMIT_FACTPIB));
- }
- break;
- case PEV_STATE_HAR_FIRMWARE:
- //read device FW
- close(plc.NVM.file);
- if (ReadFirmware2(&plc))
- {
- return (-1);
- }
- if ((plc.NVM.file = open(plc.NVM.name = plc.nvm.name, O_BINARY | O_RDONLY)) == -1)
- {
- error(1, errno, "%s", plc.NVM.name);
- }
- break;
- case PEV_STATE_HAR_PIB:
- //read device pib and issue reset
- //pib read not required as of now commented.
- #ifdef READ_PIB
- close(plc.PIB.file);
- if (ReadParameters2(&plc))
- {
- return (-1);
- }
- if ((plc.PIB.file = open(plc.PIB.name = plc.pib.name, O_BINARY | O_RDONLY)) == -1)
- {
- error(1, errno, "%s", plc.PIB.name);
- }
- #endif
- if (ResetDevice(&plc))
- {
- return (-1);
- }
- break;
- case PEV_STATE_HAR_FW_PIB:
- //read device FW and pib and issue reset
- close(plc.PIB.file);
- if (ReadParameters2(&plc))
- {
- return (-1);
- }
- if ((plc.PIB.file = open(plc.PIB.name = plc.pib.name, O_BINARY | O_RDONLY)) == -1)
- {
- error(1, errno, "%s", plc.PIB.name);
- }
- close(plc.NVM.file);
- if (ReadFirmware2(&plc))
- {
- return (-1);
- }
- if ((plc.NVM.file = open(plc.NVM.name = plc.nvm.name, O_BINARY | O_RDONLY)) == -1)
- {
- error(1, errno, "%s", plc.NVM.name);
- }
- if (ResetDevice(&plc))
- {
- return (-1);
- }
- break;
- case PEV_STATE_HAR_LOADER_SDRAM:
- //load MCTL applets
- identity_requested = false;
- identity_received = false;
- evse_slac_matched = false;
- debug(0, __func__, "HAR event 0x04. Init device with MCTL applets!");
- if (InitDevice2(&plc))
- {
- return (-1);
- }
- break;
- case PEV_STATE_HAR_BACKGROUND_PIB:
- debug(0, __func__, "Background pib change occured");
- //MMEs related to SLAC are missing during pib read. so don't do pib read for now. TODO
- #ifdef READ_PIB
- //read device pib
- close(plc.PIB.file);
- if (ReadParameters2(&plc))
- {
- return (-1);
- }
- if ((plc.PIB.file = open(plc.PIB.name = plc.pib.name, O_BINARY | O_RDONLY)) == -1)
- {
- error(1, errno, "%s", plc.PIB.name);
- }
- #endif
- break;
- case PEV_STATE_HAR_DEVICE_REBOOTED:
- debug(0, __func__, "Host has rebooted");
- break;
- case PEV_STATE_HAR_HIF_READY:
- debug(0, __func__, "Device ready for Hif communication");
- //get the original PEV key
- if (get_nid_nmk_req(&plc))
- {
- debug(1, __func__, "Error in getting nid");
- }
- identity_requested = true;
- break;
- case PEV_STATE_HAR_POWERLINE_READY:
- debug(0, __func__, "Device is ready to communicate on powerline but not a member of AVLN yet");
- if ((!identity_requested))
- {
- //get the original PEV key
- if (get_nid_nmk_req(&plc))
- {
- debug(1, __func__, "Error in getting nid");
- }
- identity_requested = true;
- }
- if (identity_received && ((prev_session_state == PEV_STATE_HAR_HIF_READY) || (prev_session_state == PEV_STATE_RESET)))
- {
- memincr(session.RunID, sizeof(session.RunID));
- evse_slac_matched = false;
- if (pev_cm_slac_param_req(&session, &channel, &message))
- {
- debug(1, __func__, "Error in slac parameter exchange");
- }
- }
- break;
- case PEV_STATE_HAR_AVLN_READY_PEER_AVAILABLE:
- debug(0, __func__, "Device is a member of AVLN and there are peers available");
- if (prev_session_state == PEV_STATE_SLAC_MATCH || evse_slac_matched)
- {
- //Move to charging state from here and make wait_in_loop_for_mme false
- debug(0, __func__, "Move to charging state");
- prev_session_state = session.state;
- session.state = PEV_STATE_CHARGING;
- wait_in_loop_for_mme = false;
- }
- break;
- case PEV_STATE_HAR_LINKLOSS:
- debug(0, __func__, "Device has disconnected from AVLN and there are no peers available");
- break;
- default:
- debug(1, __func__, "Illegal state!");
- break;
- }
- }
- }
- closechannel (& channel);
- return (0);
- }
|