added retry of SDP

This commit is contained in:
uhi22 2022-11-17 13:08:36 +01:00
parent 8f5d90bcd2
commit 3e0878986c
4 changed files with 39 additions and 16 deletions

View file

@ -131,14 +131,14 @@ class addressManager():
# "fe80::4c46:fea5:b6c9:25a9"
ba = bytearray(16)
s = self.localIpv6Address
print("[addressManager] converting self.localIpv6Address into bytearray")
# print("[addressManager] converting self.localIpv6Address into bytearray")
# Step1: remove the % and all behind:
x = s.find("%")
#print("percent found at " + str(x))
#print(s)
if (x>0):
s=s[0:x]
print(s)
#print(s)
# Step 2: expand the ommited zeros
x = s.find("::")
#print(":: found at " + str(x))
@ -146,10 +146,10 @@ class addressManager():
# a :: means four bytes which are 0x00 each.
# Todo: but we need two bytes more?!?
s = s.replace("::", ":0000:0000:0000:")
print(s)
#print(s)
# Step 3: Remove all ":"
s = s.replace(":", "")
print(s)
#print(s)
if (len(s)!=32):
print("[addressManager] ERROR: invalid length of IPv6 string. Expected be 16 bytes, means 32 hex characters. Found " + str(len(s)))
else:

View file

@ -764,20 +764,38 @@ class pyPlcHomeplug():
print("[PEVSLAC] Number of modems in the AVLN: " + str(self.numberOfSoftwareVersionResponses))
if ((self.numberOfSoftwareVersionResponses<2) and (self.isSimulationMode==0)):
print("[PEVSLAC] ERROR: There should be at least two modems, one from car and one from charger.")
self.callbackAvlnEstablished(0) # report that we lost the connection
self.callbackReadyForTcp(0) # report that we lost the connection
self.addressManager.setSeccIp("") # forget the IPv6 of the charger
self.enterState(0)
else:
# inform the higher-level state machine, that now it can start the SDP / IPv6 communication
self.ipv6.initiateSdpRequest()
self.enterState(13) # Final state is reached
# The AVLN is established, we have two modems in the network.
# Next step is to discover the chargers communication controller (SECC) using discovery protocol (SDP).
self.pevSequenceDelayCycles=0
self.SdpRepetitionCounter = 5 # prepare the number of retries for the SDP
self.enterState(13)
return
if (self.pevSequenceState==13): # AVLN is established. SDP request was sent. Waiting for SDP response.
if (self.pevSequenceState==13): # SDP request transmission and waiting for SDP response.
if (len(self.addressManager.getSeccIp())>0):
# we received an SDP response, and can start the high-level communication
print("[PEVSLAC] Now we know the chargers IP.")
self.callbackAvlnEstablished(1)
self.callbackReadyForTcp(1)
self.enterState(14)
return
if (self.pevSequenceDelayCycles>0):
# just waiting until next action
self.pevSequenceDelayCycles-=1
return
if (self.SdpRepetitionCounter>0):
# Reference: The Ioniq waits 4.1s from the slac_match.cnf to the SDP request.
# Here we send the SdpRequest. Maybe too early, but we will retry if there is no response.
self.ipv6.initiateSdpRequest()
self.SdpRepetitionCounter-=1
self.pevSequenceDelayCycles = 30 # e.g. one second delay until re-try of the SDP
self.enterState(13) # stick in the same state
return
if (self.isTooLong()):
print("[PEVSLAC] ERROR: Did not receive SDP response. Starting from the beginning.")
self.enterState(0)
return
if (self.pevSequenceState==14): # AVLN is established. SDP finished. Nothing more to do, just wait until unplugging.
@ -816,12 +834,12 @@ class pyPlcHomeplug():
self.ipv6.enterListenMode()
self.showStatus("LISTEN mode", "mode")
def __init__(self, callbackAddToTrace=None, callbackShowStatus=None, mode=C_LISTEN_MODE, addrMan=None, callbackAvlnEstablished=None, isSimulationMode=0):
def __init__(self, callbackAddToTrace=None, callbackShowStatus=None, mode=C_LISTEN_MODE, addrMan=None, callbackReadyForTcp=None, isSimulationMode=0):
self.mytransmitbuffer = bytearray("Hallo das ist ein Test", 'UTF-8')
self.nPacketsReceived = 0
self.callbackAddToTrace = callbackAddToTrace
self.callbackShowStatus = callbackShowStatus
self.callbackAvlnEstablished = callbackAvlnEstablished
self.callbackReadyForTcp = callbackReadyForTcp
self.addressManager = addrMan
self.pevSequenceState = 0
self.pevSequenceCyclesInState = 0

View file

@ -102,6 +102,10 @@ class ipv6handler():
def sendSdpResponse(self):
# SECC Discovery Response.
# The response from the charger to the EV, which transfers the IPv6 address of the charger to the car.
if (self.faultInjectionSuppressSdpResponse>0):
print("Fault injection: SDP response suppressed")
self.faultInjectionSuppressSdpResponse-=1
return
self.SdpPayload = bytearray(20) # SDP response has 20 bytes
for i in range(0, 16):
self.SdpPayload[i] = self.SeccIp[i] # 16 bytes IP address of the charger
@ -350,6 +354,7 @@ class ipv6handler():
self.EvccIp = [ 0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0x06, 0x65, 0x65, 0xff, 0xfe, 0, 0x64, 0xC3 ]
#self.ownMac = [ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 ] # 6 bytes own MAC default. Should be overwritten before use.
self.ownMac = self.addressManager.getLocalMacAddress()
self.faultInjectionSuppressSdpResponse = 0 # can be set to >0 for fault injection. Number of "lost" SDP responses.
print("pyPlcIpv6 started with ownMac " + prettyMac(self.ownMac))
if (self.iAmEvse):
# If we are an charger, we need to support the SDP, which requires to know our IPv6 adrress.

View file

@ -23,7 +23,7 @@ class pyPlcWorker():
self.callbackShowStatus = callbackShowStatus
self.oldAvlnStatus = 0
self.isSimulationMode = isSimulationMode
self.hp = pyPlcHomeplug.pyPlcHomeplug(self.callbackAddToTrace, self.callbackShowStatus, self.mode, self.addressManager, self.callbackAvlnEstablished, self.isSimulationMode)
self.hp = pyPlcHomeplug.pyPlcHomeplug(self.callbackAddToTrace, self.callbackShowStatus, self.mode, self.addressManager, self.callbackReadyForTcp, self.isSimulationMode)
if (self.mode == C_EVSE_MODE):
self.evse = fsmEvse.fsmEvse()
if (self.mode == C_PEV_MODE):
@ -35,16 +35,16 @@ class pyPlcWorker():
def showStatus(self, s, selection = ""):
self.callbackShowStatus(s, selection)
def callbackAvlnEstablished(self, status):
def callbackReadyForTcp(self, status):
if (status==1):
print("[PLCWORKER] AVLN is formed")
print("[PLCWORKER] Network is established, ready for TCP.")
if (self.oldAvlnStatus==0):
self.oldAvlnStatus = 1
if (self.mode == C_PEV_MODE):
self.pev.reInit()
else:
print("[PLCWORKER] no AVLN")
print("[PLCWORKER] no network")
self.oldAvlnStatus = 0
def mainfunction(self):