make request and response distinguishable

This commit is contained in:
Trolli Schmittlauch 2020-04-30 23:32:16 +02:00
parent 187d164200
commit e81a4d23e7
2 changed files with 66 additions and 10 deletions

View file

@ -7,11 +7,11 @@ Domain ::= VisibleString
Action ::= ENUMERATED {queryID, join, leave, stabilise, ping} Action ::= ENUMERATED {queryID, join, leave, stabilise, ping}
Request ::= SEQUENCE { Request ::= SEQUENCE {
action Action,
requestID INTEGER, requestID INTEGER,
senderID NodeID, senderID NodeID,
parts INTEGER, -- number of message parts parts INTEGER, -- number of message parts
part INTEGER, -- part number of this message part INTEGER, -- part number of this message
action Action,
actionPayload CHOICE { actionPayload CHOICE {
queryIDSendPayload QueryIDSendPayload, queryIDSendPayload QueryIDSendPayload,
joinSendPayload JoinSendPayload, joinSendPayload JoinSendPayload,
@ -21,6 +21,9 @@ Request ::= SEQUENCE {
} }
} }
-- idea: different message layouts as a way of distinguishing between
-- request and response instead of explicit flag
Response ::= SEQUENCE { Response ::= SEQUENCE {
responseTo INTEGER, responseTo INTEGER,
senderID NodeID, senderID NodeID,

View file

@ -114,14 +114,23 @@ encodeJoinReceivePayload succ' pred' ncache =
encodeJoinSendPayload :: NodeState -> [ASN1] encodeJoinSendPayload :: NodeState -> [ASN1]
encodeJoinSendPayload = encodeNodeState encodeJoinSendPayload = encodeNodeState
encodePingSendPayload :: [ASN1]
encodePingSendPayload = Null
encodePingReceivePayload :: [NodeState] -> [ASN1]
encodePingReceivePayload nss =
Start Sequence
: concatMap encodeNodeState nss
++ [End Sequence]
encodeRequest :: Integer -> NodeID -> Integer -> Integer -> Action -> [ASN1] -> [ASN1] encodeRequest :: Integer -> NodeID -> Integer -> Integer -> Action -> [ASN1] -> [ASN1]
encodeRequest requestID senderID parts part action payload = [ encodeRequest requestID senderID parts part action payload = [
Start Sequence Start Sequence
, Enumerated . fromIntegral . fromEnum $ action
, IntVal requestID , IntVal requestID
, IntVal . getNodeID $ senderID , IntVal . getNodeID $ senderID
, IntVal parts , IntVal parts
, IntVal part , IntVal part ]
, Enumerated . fromIntegral . fromEnum $ action]
++ payload ++ payload
encodeResponse :: Integer -> NodeID -> Integer -> Integer -> Action -> [ASN1] -> [ASN1] encodeResponse :: Integer -> NodeID -> Integer -> Integer -> Action -> [ASN1] -> [ASN1]
@ -134,11 +143,55 @@ encodeResponse responseTo senderID parts part action payload = [
, Enumerated . fromIntegral . fromEnum $ action] , Enumerated . fromIntegral . fromEnum $ action]
++ payload ++ payload
encodePingSendPayload :: [ASN1] -- ===== parser combinators =====
encodePingSendPayload = Null
encodePingReceivePayload :: [NodeState] -> [ASN1] parseMessage :: ParseASN1 () -- todo: change type
encodePingReceivePayload nss = parseMessage = do
Start Sequence -- request and response messages are distiguishable by their structure,
: concatMap encodeNodeState nss -- see ASN.1 schema
++ [End Sequence] first <- getNext
case first of
Enumerated a -> parseRequest . toEnum $ a
IntVal i -> parseResponse i
parseRequest :: Action -> ParseASN1 () -- todo: change type
parseRequest action = do
requestID <- parseInteger
senderID <- (fromInteger <$> parseInteger :: ParseASN1 NodeID)
parts <- parseInteger
part <- parseInteger
payload <- onNextContainer Sequence $
case action of
QueryID -> parseQueryIDRequest
Join -> parseJoinRequest
Leave -> parseLeaveRequest
Stabilise -> parseStabiliseRequest
Ping -> parsePingRequest
return ()
parseResponse :: Integer -> ParseASN1 () -- todo: change type
parseResponse responseTo = do
senderID <- (fromInteger <$> parseInteger :: ParseASN1 NodeID)
parts <- parseInteger
part <- parseInteger
action <- (parseEnum :: ParseASN1 Action)
payload <- onNextContainer Sequence $
case action of
QueryID -> parseQueryIDResponse
Join -> parseJoinResponse
Leave -> parseLeaveResponse
Stabilise -> parseStabiliseResponse
Ping -> parsePingResponse
return ()
parseInteger :: ParseASN1 Integer
parseInteger = do
IntVal parsed <- getNext
return parsed
parseEnum :: Enum a => ParseASN1 a
parseEnum = do
Enumerated en <- getNext
return $ toEnum . fromIntegral $ en