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}
Request ::= SEQUENCE {
action Action,
requestID INTEGER,
senderID NodeID,
parts INTEGER, -- number of message parts
part INTEGER, -- part number of this message
action Action,
actionPayload CHOICE {
queryIDSendPayload QueryIDSendPayload,
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 {
responseTo INTEGER,
senderID NodeID,

View file

@ -114,14 +114,23 @@ encodeJoinReceivePayload succ' pred' ncache =
encodeJoinSendPayload :: NodeState -> [ASN1]
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 requestID senderID parts part action payload = [
Start Sequence
, Enumerated . fromIntegral . fromEnum $ action
, IntVal requestID
, IntVal . getNodeID $ senderID
, IntVal parts
, IntVal part
, Enumerated . fromIntegral . fromEnum $ action]
, IntVal part ]
++ payload
encodeResponse :: Integer -> NodeID -> Integer -> Integer -> Action -> [ASN1] -> [ASN1]
@ -134,11 +143,55 @@ encodeResponse responseTo senderID parts part action payload = [
, Enumerated . fromIntegral . fromEnum $ action]
++ payload
encodePingSendPayload :: [ASN1]
encodePingSendPayload = Null
-- ===== parser combinators =====
encodePingReceivePayload :: [NodeState] -> [ASN1]
encodePingReceivePayload nss =
Start Sequence
: concatMap encodeNodeState nss
++ [End Sequence]
parseMessage :: ParseASN1 () -- todo: change type
parseMessage = do
-- request and response messages are distiguishable by their structure,
-- see ASN.1 schema
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