Asterisk.icl 3.03 KB
Newer Older
1 2 3 4 5 6 7 8
implementation module Incidone.Integration.Asterisk

import iTasks
import Incidone.Configuration
import Incidone.OP.Conversions
import Incidone.OP.SDSs
import Incidone.OP.CommunicationManagementTasks
import Incidone.Util.TaskPatterns
9
import Text, Data.Either
10
import qualified Data.Map as DM
11
import Data.Map.GenJSON
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76

:: AsteriskEvent :== Map String String // Simple key/value mapping

syncAsteriskAMI :: Task ()
syncAsteriskAMI = withShared ([],False,[],False) (\channel -> (sync channel -&&- consume channel) @! ())
where
    sync channel
        =   get asteriskLinkConfig
        >>- \{AsteriskConfig|host,port,username,password} ->
            set ([],False,[authEvent username password],False) channel
        >>| syncNetworkChannel host port "\r\n\r\n" decodeAsteriskEvent encodeAsteriskEvent channel

    consume channel
        =   consumeNetworkStream processEvents channel

    processEvents events
        = allTasks [processEvent m \\ m <- events | isAsteriskEventType ["Dial","Newstate","Hangup"] m] @! ()

    processEvent event
        = case ('DM'.get "Event" event) of
            (Just "Dial") = case 'DM'.get "SubEvent" event of
                (Just "Begin")  = reportPhoneCallBegin CallerIDNum UniqueID @! ()
                (Just "End")    = maybe (return ()) (\id -> reportPhoneCallEnd (Right id)) UniqueID
                _               = return ()
            (Just "Newstate") = case 'DM'.get "ChannelStateDesc" event of
                (Just "Up")     = maybe (return ()) (\id -> reportPhoneCallConnected (Right id)) Uniqueid
                _               = return ()
            _
                = return ()
    where
        CallerIDNum = 'DM'.get "CallerIDNum" event
        UniqueID    = 'DM'.get "UniqueID" event
        Uniqueid    = 'DM'.get "Uniqueid" event

    authEvent username password
        = 'DM'.fromList [("Action","Login"),("Username",username),("Secret",password)]

    originateEvent fromExt toExt context
        = 'DM'.fromList [("Action","Originate"),("Channel","SIP/"+++fromExt),("Exten",toExt),("Priority","1"),("Context",context)]

encodeAsteriskEvent :: AsteriskEvent -> String
encodeAsteriskEvent event = join "\r\n" [k +++ ": " +++ v \\ (k,v) <- 'DM'.toList event] +++ "\r\n\r\n"

decodeAsteriskEvent :: String -> AsteriskEvent
decodeAsteriskEvent enc = foldr addLine 'DM'.newMap (split "\r\n" enc)
where
    addLine line msg = case split ":" line of
        [key,value] = 'DM'.put (trim key) (trim value) msg
        _           = msg

isAsteriskEventType :: [String] AsteriskEvent -> Bool
isAsteriskEventType types msg =  maybe False (\type -> isMember type types) ('DM'.get "Event" msg)

initiateAsteriskChannel :: CommunicationNo -> Task ()
initiateAsteriskChannel communicationNo
    //Set status to pending
    =   upd (\c -> {Communication|c & status = Just Pending}) (sdsFocus communicationNo communicationByNo)
    @!  ()

destroyAsteriskChannel :: CommunicationNo -> Task ()
destroyAsteriskChannel communicationNo
    =   upd (\c -> {Communication|c & status = Nothing}) (sdsFocus communicationNo communicationByNo)
    @!  ()