module Network.ADB.Server (
Session,
withServerSession,
withAccept,
module Network.ADB.Transport
) where
import Control.Applicative
import Control.Concurrent
import Control.Monad.Error
import Data.ByteString.Char8 (ByteString)
import qualified Data.ByteString.Char8 as C
import Data.Monoid
import Network.ADB.Common
import Network.ADB.Transport
withServerSession :: Transport (ErrorT TransportError IO)
-> ByteString
-> (Session (ErrorT TransportError IO) -> ErrorT TransportError IO a)
-> ErrorT TransportError IO a
withServerSession tra descriptor code = do
negotiate descriptor tra
withSession tra code
negotiate :: (MonadError TransportError m, Applicative m, MonadIO m) =>
ByteString
-> Transport m -> m ()
negotiate descriptor tra = do
pkt <- readPacket tra
case pkt of
Packet CNXN _ _ _ -> write tra $ formatPacket $ Packet CNXN a_VERSION mAX_PAYLOAD (descriptor <> "\0")
_ -> negotiate descriptor tra
withAccept :: Session (ErrorT TransportError IO)
-> (C.ByteString -> Maybe (Transport (ErrorT TransportError IO) -> ErrorT TransportError IO ()))
-> ErrorT TransportError IO ()
withAccept session@(Session allocLocalID writePkt readPkt) qCode = forever $ do
pkt <- readPkt
case pkt of
Packet OPEN remoteID 0 uri ->
if "\0" `C.isSuffixOf` uri
then case qCode (C.take (C.length uri 1) uri) of
Just code -> do
_ <- liftIO $ forkIO $ do
localID <- allocLocalID
_ <- runErrorT $ do
writePkt $ Packet OKAY localID remoteID C.empty
withConversation session localID remoteID code
return ()
return ()
Nothing -> writePkt $ Packet CLSE 0 remoteID C.empty
else writePkt $ Packet CLSE 0 remoteID C.empty
_ -> return ()