make request and response distinguishable
This commit is contained in:
parent
187d164200
commit
e81a4d23e7
|
@ -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,
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue