evse_cm_set_key.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. /*====================================================================*
  2. *
  3. * Copyright (c) 2013 Qualcomm Atheros, Inc.
  4. *
  5. * All rights reserved.
  6. *
  7. *====================================================================*/
  8. /*====================================================================*
  9. *
  10. * signed evse_cm_set_key (struct session * session, struct channel * channel, struct message * message);
  11. *
  12. * slac.h
  13. *
  14. * PEV-HLE sets the NMK and NID on PEV-PLC using CM_SET_KEY.REQ;
  15. * the NMK and NID must match those provided by EVSE-HLE using
  16. * CM_SLAC_MATCH.CNF;
  17. *
  18. * Contributor(s):
  19. * Charles Maier <cmaier@qca.qualcomm.com>
  20. *
  21. *--------------------------------------------------------------------*/
  22. #ifndef EVSE_CM_SET_KEY_SOURCE
  23. #define EVSE_CM_SET_KEY_SOURCE
  24. #include <string.h>
  25. #include "../ether/channel.h"
  26. #include "../tools/memory.h"
  27. #include "../tools/error.h"
  28. #include "../tools/flags.h"
  29. #include "../mme/qualcomm.h"
  30. #include "../mme/homeplug.h"
  31. #include "../slac/slac.h"
  32. signed evse_cm_set_key (struct session * session, struct channel * channel, struct message * message)
  33. {
  34. #ifndef __GNUC__
  35. #pragma pack(push,1)
  36. #endif
  37. struct __packed cm_set_key_request
  38. {
  39. struct ethernet_hdr ethernet;
  40. struct homeplug_fmi homeplug;
  41. uint8_t KEYTYPE;
  42. uint32_t MYNOUNCE;
  43. uint32_t YOURNOUNCE;
  44. uint8_t PID;
  45. uint16_t PRN;
  46. uint8_t PMN;
  47. uint8_t CCOCAP;
  48. uint8_t NID [SLAC_NID_LEN];
  49. uint8_t NEWEKS;
  50. uint8_t NEWKEY [SLAC_NMK_LEN];
  51. uint8_t RSVD [3];
  52. }
  53. * request = (struct cm_set_key_request *) (message);
  54. struct __packed cm_set_key_confirm
  55. {
  56. struct ethernet_hdr ethernet;
  57. struct homeplug_fmi homeplug;
  58. uint8_t RESULT;
  59. uint32_t MYNOUNCE;
  60. uint32_t YOURNOUNCE;
  61. uint8_t PID;
  62. uint16_t PRN;
  63. uint8_t PMN;
  64. uint8_t CCOCAP;
  65. uint8_t RSVD [27];
  66. }
  67. * confirm = (struct cm_set_key_confirm *) (message);
  68. #ifndef __GNUC__
  69. #pragma pack (pop)
  70. #endif
  71. memset (message, 0, sizeof (* message));
  72. debug (0, __func__, "--> CM_SET_KEY.REQ");
  73. EthernetHeader (& request->ethernet, channel->peer, channel->host, channel->type);
  74. HomePlugHeader1 (& request->homeplug, HOMEPLUG_MMV, (CM_SET_KEY | MMTYPE_REQ));
  75. request->KEYTYPE = SLAC_CM_SETKEY_KEYTYPE;
  76. memset (& request->MYNOUNCE, 0xAA, sizeof (request->MYNOUNCE));
  77. memset (& request->YOURNOUNCE, 0x00, sizeof (request->YOURNOUNCE));
  78. request->PID = SLAC_CM_SETKEY_PID;
  79. request->PRN = HTOLE16 (SLAC_CM_SETKEY_PRN);
  80. request->PMN = SLAC_CM_SETKEY_PMN;
  81. request->CCOCAP = SLAC_CM_SETKEY_CCO;
  82. memcpy (request->NID, session->NID, sizeof (request->NID));
  83. request->NEWEKS = SLAC_CM_SETKEY_EKS;
  84. memcpy (request->NEWKEY, session->NMK, sizeof (request->NEWKEY));
  85. #if SLAC_DEBUG
  86. if (_anyset (session->flags, SLAC_VERBOSE))
  87. {
  88. char string [1024];
  89. debug (0, __func__, "CM_SET_KEY.KEYTYPE %d", request->KEYTYPE);
  90. debug (0, __func__, "CM_SET_KEY.MYNOUNCE %s", hexstring (string, sizeof (string), & request->MYNOUNCE, sizeof (request->MYNOUNCE)));
  91. debug (0, __func__, "CM_SET_KEY.YOURNOUNCE %s", hexstring (string, sizeof (string), & request->YOURNOUNCE, sizeof (request->MYNOUNCE)));
  92. debug (0, __func__, "CM_SET_KEY.PID %d", request->PID);
  93. debug (0, __func__, "CM_SET_KEY.PRN %d", LE32TOH (request->PRN));
  94. debug (0, __func__, "CM_SET_KEY.PMN %d", request->PMN);
  95. debug (0, __func__, "CM_SET_KEY.CCoCAP %d", request->CCOCAP);
  96. debug (0, __func__, "CM_SET_KEY.NID %s", HEXSTRING (string, request->NID));
  97. debug (0, __func__, "CM_SET_KEY.NEWEKS %d", request->NEWEKS);
  98. debug (0, __func__, "CM_SET_KEY.NEWKEY %s", HEXSTRING (string, request->NEWKEY));
  99. }
  100. #endif
  101. if (sendpacket (channel, request, sizeof (* request)) <= 0)
  102. {
  103. return (debug (1, __func__, CHANNEL_CANTSEND));
  104. }
  105. while (readpacket (channel, confirm, sizeof (* confirm)) > 0)
  106. {
  107. if (ntohs (confirm->ethernet.MTYPE) != ETH_P_HPAV)
  108. {
  109. debug (session->exit, __func__, "Ignore MTYPE 0x%04X", htons (confirm->ethernet.MTYPE));
  110. continue;
  111. }
  112. if (confirm->homeplug.MMV != HOMEPLUG_MMV)
  113. {
  114. debug (session->exit, __func__, "Ignore MMV 0x%02X", confirm->homeplug.MMV);
  115. continue;
  116. }
  117. if (LE32TOH (confirm->homeplug.MMTYPE) != (CM_SET_KEY | MMTYPE_CNF))
  118. {
  119. debug (session->exit, __func__, "Ignore MMTYPE 0x%04X", LE32TOH (confirm->homeplug.MMTYPE));
  120. continue;
  121. }
  122. debug (0, __func__, "<-- CM_SET_KEY.CNF");
  123. if (! confirm->RESULT)
  124. {
  125. return (debug (session->exit, __func__, "Device refused request"));
  126. }
  127. #if SLAC_DEBUG
  128. if (_anyset (session->flags, SLAC_VERBOSE))
  129. {
  130. char string [1024];
  131. debug (0, __func__, "CM_SET_KEY.RESULT %d", confirm->RESULT);
  132. debug (0, __func__, "CM_SET_KEY.MYNOUNCE %s", hexstring (string, sizeof (string), & confirm->MYNOUNCE, sizeof (confirm->MYNOUNCE)));
  133. debug (0, __func__, "CM_SET_KEY.YOURNOUNCE %s", hexstring (string, sizeof (string), & confirm->YOURNOUNCE, sizeof (confirm->MYNOUNCE)));
  134. debug (0, __func__, "CM_SET_KEY.PID %d", confirm->PID);
  135. debug (0, __func__, "CM_SET_KEY.PRN %d", LE32TOH (confirm->PRN));
  136. debug (0, __func__, "CM_SET_KEY.PMN %d", confirm->PMN);
  137. debug (0, __func__, "CM_SET_KEY.CCoCAP %d", confirm->CCOCAP);
  138. }
  139. #endif
  140. return (0);
  141. }
  142. return (debug (session->exit, __func__, "<-- CM_SET_KEY.REQ ?"));
  143. }
  144. #endif