module Network.PeyoTLS.Codec.Alert (Alert(..), AlertLevel(..), AlertDesc(..)) where
import Control.Applicative
import "monads-tf" Control.Monad.Error.Class (Error(..))
import Data.Word (Word8)
import qualified Data.ByteString as BS
import qualified Codec.Bytable.BigEndian as B
modNm :: String
modNm = "Network.PeyoTLS.Codec.Alert"
data Alert
= Alert AlertLevel AlertDesc String
| ExternalAlert String
| NotDetected String deriving Show
instance B.Bytable Alert where
encode (Alert al ad _) = B.encode al `BS.append` B.encode ad
encode _ = error "Alert.encode"
decode alad = let (al, ad) = BS.splitAt 1 alad in
Alert <$> B.decode al <*> B.decode ad <*> return ""
data AlertLevel = ALWarning | ALFtl | ALRaw Word8 deriving Show
instance B.Bytable AlertLevel where
encode ALWarning = "\x01"
encode ALFtl = "\x02"
encode (ALRaw w) = BS.pack [w]
decode bs = case BS.unpack bs of
[al] -> Right $ case al of
1 -> ALWarning; 2 -> ALFtl; _ -> ALRaw al
_ -> Left $ modNm ++ ": AlertLevel.decode"
data AlertDesc
= ADCloseNotify | ADUnexMsg | ADBadRecMac | ADRecOverflow | ADDecFail
| ADHsFailure | ADUnsCert | ADCertEx | ADCertUnk | ADIllParam
| ADUnkCa | ADDecodeErr | ADDecryptErr | ADProtoVer | ADInsSec
| ADInternalErr | ADUnk | ADRaw Word8
deriving Show
instance B.Bytable AlertDesc where
encode ADCloseNotify = "\0"
encode ADUnexMsg = "\10"
encode ADBadRecMac = "\20"
encode ADRecOverflow = "\22"
encode ADDecFail = "\30"
encode ADHsFailure = "\40"
encode ADUnsCert = "\43"
encode ADCertEx = "\45"
encode ADCertUnk = "\46"
encode ADIllParam = "\47"
encode ADUnkCa = "\48"
encode ADDecodeErr = "\50"
encode ADDecryptErr = "\51"
encode ADProtoVer = "\70"
encode ADInsSec = "\71"
encode ADInternalErr = "\80"
encode ADUnk = error $ modNm ++ ": AlertDesc,encode"
encode (ADRaw w) = BS.pack [w]
decode bs = case BS.unpack bs of
[ad] -> Right $ case ad of
0 -> ADCloseNotify
10 -> ADUnexMsg
20 -> ADBadRecMac
22 -> ADRecOverflow
30 -> ADDecFail
40 -> ADHsFailure
43 -> ADUnsCert
45 -> ADCertEx
46 -> ADCertUnk
47 -> ADIllParam
48 -> ADUnkCa
50 -> ADDecodeErr
51 -> ADDecryptErr
70 -> ADProtoVer
71 -> ADInsSec
80 -> ADInternalErr
w -> ADRaw w
_ -> Left $ modNm ++ ": AlertDesc.decode"
instance Error Alert where strMsg = NotDetected