@@ -112,6 +112,7 @@ module Simplex.Messaging.Agent.Protocol
112112 ServiceScheme ,
113113 FixedLinkData (.. ),
114114 ConnLinkData (.. ),
115+ AUserConnLinkData (.. ),
115116 UserConnLinkData (.. ),
116117 UserContactData (.. ),
117118 UserLinkData (.. ),
@@ -382,6 +383,7 @@ type SndQueueSecured = Bool
382383-- | Parameterized type for SMP agent events
383384data AEvent (e :: AEntity ) where
384385 INV :: AConnectionRequestUri -> Maybe ClientServiceId -> AEvent AEConn
386+ LINK :: AConnShortLink -> AUserConnLinkData -> AEvent AEConn
385387 CONF :: ConfirmationId -> PQSupport -> [SMPServer ] -> ConnInfo -> AEvent AEConn -- ConnInfo is from sender, [SMPServer] will be empty only in v1 handshake
386388 REQ :: InvitationId -> PQSupport -> NonEmpty SMPServer -> ConnInfo -> AEvent AEConn -- ConnInfo is from sender
387389 INFO :: PQSupport -> ConnInfo -> AEvent AEConn
@@ -435,6 +437,7 @@ deriving instance Show AEvtTag
435437
436438data ACommand
437439 = NEW Bool AConnectionMode InitialKeys SubscriptionMode -- response INV
440+ | LSET AUserConnLinkData (Maybe CRClientData ) -- response LINK
438441 | JOIN Bool AConnectionRequestUri PQSupport SubscriptionMode ConnInfo
439442 | LET ConfirmationId ConnInfo -- ConnInfo is from client
440443 | ACK AgentMsgId (Maybe MsgReceiptInfo )
@@ -444,6 +447,7 @@ data ACommand
444447
445448data ACommandTag
446449 = NEW_
450+ | LSET_
447451 | JOIN_
448452 | LET_
449453 | ACK_
@@ -453,6 +457,7 @@ data ACommandTag
453457
454458data AEventTag (e :: AEntity ) where
455459 INV_ :: AEventTag AEConn
460+ LINK_ :: AEventTag AEConn
456461 CONF_ :: AEventTag AEConn
457462 REQ_ :: AEventTag AEConn
458463 INFO_ :: AEventTag AEConn
@@ -499,6 +504,7 @@ deriving instance Show (AEventTag e)
499504aCommandTag :: ACommand -> ACommandTag
500505aCommandTag = \ case
501506 NEW {} -> NEW_
507+ LSET {} -> LSET_
502508 JOIN {} -> JOIN_
503509 LET {} -> LET_
504510 ACK {} -> ACK_
@@ -508,6 +514,7 @@ aCommandTag = \case
508514aEventTag :: AEvent e -> AEventTag e
509515aEventTag = \ case
510516 INV {} -> INV_
517+ LINK {} -> LINK_
511518 CONF {} -> CONF_
512519 REQ {} -> REQ_
513520 INFO {} -> INFO_
@@ -1703,15 +1710,30 @@ data UserContactData = UserContactData
17031710 relays :: [ConnShortLink 'CMContact],
17041711 userData :: UserLinkData
17051712 }
1713+ deriving (Eq , Show )
17061714
17071715newtype UserLinkData = UserLinkData ByteString
1716+ deriving (Eq , Show )
17081717
17091718data AConnLinkData = forall m . ConnectionModeI m => ACLD (SConnectionMode m ) (ConnLinkData m )
17101719
17111720data UserConnLinkData c where
17121721 UserInvLinkData :: UserLinkData -> UserConnLinkData 'CMInvitation
17131722 UserContactLinkData :: UserContactData -> UserConnLinkData 'CMContact
17141723
1724+ deriving instance Eq (UserConnLinkData m )
1725+
1726+ deriving instance Show (UserConnLinkData m )
1727+
1728+ data AUserConnLinkData = forall m . ConnectionModeI m => AUCLD (SConnectionMode m ) (UserConnLinkData m )
1729+
1730+ instance Eq AUserConnLinkData where
1731+ AUCLD m d == AUCLD m' d' = case testEquality m m' of
1732+ Just Refl -> d == d'
1733+ Nothing -> False
1734+
1735+ deriving instance Show AUserConnLinkData
1736+
17151737linkUserData :: ConnLinkData c -> UserLinkData
17161738linkUserData = \ case
17171739 InvitationLinkData _ d -> d
@@ -1738,6 +1760,7 @@ data OwnerAuth = OwnerAuth
17381760 -- Owner validation should detect and reject loops.
17391761 authOwnerSig :: C. Signature 'C.Ed25519
17401762 }
1763+ deriving (Eq , Show )
17411764
17421765instance Encoding OwnerAuth where
17431766 smpEncode OwnerAuth {ownerId, ownerKey, ownerSig, authOwnerId, authOwnerSig} =
@@ -1756,8 +1779,7 @@ instance ConnectionModeI c => Encoding (FixedLinkData c) where
17561779instance ConnectionModeI c => Encoding (ConnLinkData c ) where
17571780 smpEncode = \ case
17581781 InvitationLinkData vr userData -> smpEncode (CMInvitation , vr, userData)
1759- ContactLinkData vr UserContactData {direct, owners, relays, userData} ->
1760- B. concat [smpEncode (CMContact , vr, direct), smpEncodeList owners, smpEncodeList relays, smpEncode userData]
1782+ ContactLinkData vr cd -> smpEncode (CMContact , vr, cd)
17611783 smpP = (\ (ACLD _ d) -> checkConnMode d) <$?> smpP
17621784 {-# INLINE smpP #-}
17631785
@@ -1770,13 +1792,43 @@ instance Encoding AConnLinkData where
17701792 (vr, userData) <- smpP <* A. takeByteString -- ignoring tail for forward compatibility with the future link data encoding
17711793 pure $ ACLD SCMInvitation $ InvitationLinkData vr userData
17721794 CMContact -> do
1773- (vr, direct) <- smpP
1774- owners <- smpListP
1775- relays <- smpListP
1776- userData <- smpP <* A. takeByteString -- ignoring tail for forward compatibility with the future link data encoding
1777- let cd = UserContactData {direct, owners, relays, userData}
1795+ (vr, cd) <- smpP
17781796 pure $ ACLD SCMContact $ ContactLinkData vr cd
17791797
1798+ instance ConnectionModeI c => Encoding (UserConnLinkData c ) where
1799+ smpEncode = \ case
1800+ UserInvLinkData userData -> smpEncode (CMInvitation , userData)
1801+ UserContactLinkData cd -> smpEncode (CMContact , cd)
1802+ smpP = (\ (AUCLD _ d) -> checkConnMode d) <$?> smpP
1803+ {-# INLINE smpP #-}
1804+
1805+ instance Encoding AUserConnLinkData where
1806+ smpEncode (AUCLD _ d) = smpEncode d
1807+ {-# INLINE smpEncode #-}
1808+ smpP =
1809+ smpP >>= \ case
1810+ CMInvitation -> do
1811+ userData <- smpP <* A. takeByteString -- ignoring tail for forward compatibility with the future link data encoding
1812+ pure $ AUCLD SCMInvitation $ UserInvLinkData userData
1813+ CMContact ->
1814+ AUCLD SCMContact . UserContactLinkData <$> smpP
1815+
1816+ instance StrEncoding AUserConnLinkData where
1817+ strEncode = smpEncode
1818+ {-# INLINE strEncode #-}
1819+ strP = smpP
1820+ {-# INLINE strP #-}
1821+
1822+ instance Encoding UserContactData where
1823+ smpEncode UserContactData {direct, owners, relays, userData} =
1824+ B. concat [smpEncode direct, smpEncodeList owners, smpEncodeList relays, smpEncode userData]
1825+ smpP = do
1826+ direct <- smpP
1827+ owners <- smpListP
1828+ relays <- smpListP
1829+ userData <- smpP <* A. takeByteString -- ignoring tail for forward compatibility with the future link data encoding
1830+ pure UserContactData {direct, owners, relays, userData}
1831+
17801832instance Encoding UserLinkData where
17811833 smpEncode (UserLinkData s) = if B. length s <= 254 then smpEncode s else smpEncode ('\ 255 ', Large s)
17821834 {-# INLINE smpEncode #-}
@@ -1976,6 +2028,7 @@ instance StrEncoding ACommandTag where
19762028 strP =
19772029 A. takeTill (== ' ' ) >>= \ case
19782030 " NEW" -> pure NEW_
2031+ " LSET" -> pure LSET_
19792032 " JOIN" -> pure JOIN_
19802033 " LET" -> pure LET_
19812034 " ACK" -> pure ACK_
@@ -1984,6 +2037,7 @@ instance StrEncoding ACommandTag where
19842037 _ -> fail " bad ACommandTag"
19852038 strEncode = \ case
19862039 NEW_ -> " NEW"
2040+ LSET_ -> " LSET"
19872041 JOIN_ -> " JOIN"
19882042 LET_ -> " LET"
19892043 ACK_ -> " ACK"
@@ -1995,6 +2049,7 @@ commandP binaryP =
19952049 strP
19962050 >>= \ case
19972051 NEW_ -> s (NEW <$> strP_ <*> strP_ <*> pqIKP <*> (strP <|> pure SMP. SMSubscribe ))
2052+ LSET_ -> s (LSET <$> strP <*> optional (A. space *> strP))
19982053 JOIN_ -> s (JOIN <$> strP_ <*> strP_ <*> pqSupP <*> (strP_ <|> pure SMP. SMSubscribe ) <*> binaryP)
19992054 LET_ -> s (LET <$> A. takeTill (== ' ' ) <* A. space <*> binaryP)
20002055 ACK_ -> s (ACK <$> A. decimal <*> optional (A. space *> binaryP))
@@ -2012,6 +2067,7 @@ commandP binaryP =
20122067serializeCommand :: ACommand -> ByteString
20132068serializeCommand = \ case
20142069 NEW ntfs cMode pqIK subMode -> s (NEW_ , ntfs, cMode, pqIK, subMode)
2070+ LSET uld cd_ -> s (LSET_ , uld) <> maybe " " (B. cons ' ' . s) cd_
20152071 JOIN ntfs cReq pqSup subMode cInfo -> s (JOIN_ , ntfs, cReq, pqSup, subMode, Str $ serializeBinary cInfo)
20162072 LET confId cInfo -> B. unwords [s LET_ , confId, serializeBinary cInfo]
20172073 ACK mId rcptInfo_ -> s (ACK_ , mId) <> maybe " " (B. cons ' ' . serializeBinary) rcptInfo_
0 commit comments