Source

ocaml-sip / src / Sip_types.ml

(*********************************************************************************************************************
 * Copyrights (C) 2012 by Pawel Wieczorek <wieczyk at gmail>
 *  http://bitbucket.org/wieczyk/ocaml-sip
 *)

open Batteries
open Sip_utils

(*********************************************************************************************************************
 *)

type sip_request_method
    = REGISTER
    | INVITE
    | CANCEL
    | ACK
    | PRACK
    | BYE
    | OPTIONS
    | SUBSCRIBE
    | NOTIFY
    | PUBLISH
    | INFO
    | REFER
    | MESSAGE
    | UPDATE
    | UnknownRequestMethod of string

let sip_request_method_of_string = function
    | "REGISTER" -> REGISTER
    | "INVITE" -> INVITE
    | "CANCEL" -> CANCEL
    | "ACK" -> ACK
    | "PRACK" -> PRACK
    | "BYE" -> BYE
    | "OPTIONS" -> OPTIONS
    | "SUBSCRIBE" -> SUBSCRIBE
    | "NOTIFY" -> NOTIFY
    | "PUBLISH" -> PUBLISH
    | "INFO" -> INFO
    | "REFER" -> REFER
    | "MESSAGE" -> MESSAGE
    | "UPDATE" -> UPDATE
    | s -> UnknownRequestMethod s

let string_of_sip_request_method = function
    | REGISTER -> "REGISTER"
    | INVITE -> "INVITE"
    | CANCEL -> "CANCEL"
    | ACK -> "ACK"
    | PRACK -> "PRACK"
    | BYE -> "BYE"
    | OPTIONS -> "OPTIONS"
    | SUBSCRIBE -> "SUBSCRIBE"
    | NOTIFY -> "NOTIFY"
    | PUBLISH -> "PUBLISH"
    | INFO -> "INFO"
    | REFER -> "REFER"
    | MESSAGE -> "MESSAGE"
    | UPDATE -> "UPDATE"
    | UnknownRequestMethod s -> s

(*********************************************************************************************************************
 *)

type sip_response_code
    = RESP_100_TRYING
    | RESP_180_RINGING
    | RESP_181_CALL_IS_BEING_FORWARDED
    | RESP_182_QUEUED
    | RESP_183_SESSION_IN_PROGRESS

    | RESP_200_OK
    | RESP_202_ACCEPTED
    | RESP_204_NO_NOTIFICATION

    | RESP_300_MULTIPLE_CHOICES
    | RESP_301_MOVED_PERMANENTLY
    | RESP_302_MOVED_TEMPORILY
    | RESP_305_USE_PROXY
    | RESP_380_ALTERNATIVE_SERVICE

    | RESP_400_BAD_REQUEST
    | RESP_401_UNAUTHORIZED
    | RESP_402_PAYMENT_REQUIRED
    | RESP_403_FORBIDDEN
    | RESP_404_NOT_FOUND
    | RESP_405_METHOD_NOT_ALLOWED

    | RESP_500_SERVER_INTERNAL_ERROR
    | RESP_501_NOT_IMPLEMENTED
    | RESP_502_BAD_GATEWAY
    | RESP_503_SERVICE_UNAVAILABLE

    | RESP_600_BUSY_EVERYWHERE

    | OtherResponse of int

let int_of_response_code = function
    | RESP_100_TRYING -> 100
    | RESP_180_RINGING -> 180
    | RESP_181_CALL_IS_BEING_FORWARDED -> 181
    | RESP_182_QUEUED -> 182
    | RESP_183_SESSION_IN_PROGRESS -> 183

    | RESP_200_OK -> 200
    | RESP_202_ACCEPTED -> 202
    | RESP_204_NO_NOTIFICATION -> 204

    | RESP_300_MULTIPLE_CHOICES -> 300
    | RESP_301_MOVED_PERMANENTLY -> 301
    | RESP_302_MOVED_TEMPORILY -> 302
    | RESP_305_USE_PROXY -> 305
    | RESP_380_ALTERNATIVE_SERVICE -> 380

    | RESP_400_BAD_REQUEST -> 400
    | RESP_401_UNAUTHORIZED -> 401
    | RESP_402_PAYMENT_REQUIRED -> 402
    | RESP_403_FORBIDDEN -> 403
    | RESP_404_NOT_FOUND -> 404
    | RESP_405_METHOD_NOT_ALLOWED -> 405

    | RESP_500_SERVER_INTERNAL_ERROR -> 500
    | RESP_501_NOT_IMPLEMENTED -> 501
    | RESP_502_BAD_GATEWAY -> 502
    | RESP_503_SERVICE_UNAVAILABLE -> 503

    | RESP_600_BUSY_EVERYWHERE -> 600

    | OtherResponse i -> i

let sip_response_code_of_string = function
    | i -> OtherResponse i

(*********************************************************************************************************************
 * TODO: Maybe Should I use some external library for parsing URI? Eh... crazy text format ;]
 *)

type sip_uri_scheme
    = URI_SCHEME_SIP
    | URI_SCHEME_SIPS
    | URI_SCHEME_TEL
    | UnknownUriScheme of string

let string_of_sip_uri_scheme = function
    | URI_SCHEME_SIP -> "sip"
    | URI_SCHEME_SIPS -> "sips"
    | URI_SCHEME_TEL -> "tel"
    | UnknownUriScheme s -> s

let sip_uri_scheme_of_string = function
    | "sip"  -> URI_SCHEME_SIP
    | "sips" -> URI_SCHEME_SIPS
    | scheme -> UnknownUriScheme scheme

(*********************************************************************************************************************
 *)

type sip_uri =
    SipUri of string

let string_of_sip_uri = function
    | SipUri s -> s

let sip_uri_of_string = function
    | s -> SipUri s

(*********************************************************************************************************************
 *)
type sip_address =
    SipAddress of string

let sip_address_of_string = function
    | s -> SipAddress s

let string_of_sip_address = function
    | SipAddress s -> s

(*********************************************************************************************************************
 *)

type sip_call_id =
    SipCallId of string

let sip_call_id_of_string = function
    | s -> SipCallId s

let string_of_sip_call_id = function
    | SipCallId s -> s

(*********************************************************************************************************************
 *)

type sip_cseq =
    SipCseq of int32 * sip_request_method

let string_of_sip_cseq = function
    | SipCseq (seq, reqmethod) -> Int32.to_string seq ^ " " ^ string_of_sip_request_method reqmethod

let sip_cseq_of_string s = 
    try
        let (word, index) = Sip_utils.find_word 0 s in
        let rest          = String.slice ~first:(succ index) s in
        SipCseq (Int32.of_string word, sip_request_method_of_string rest)
    with _ ->
        failwith "sip_cseq_of_string"

(*********************************************************************************************************************
 *)

type sip_version =
    | SIP_1_0
    | SIP_2_0
    | UnknownSipVersion of string

let sip_version_of_string = function
    | "SIP/1.0" ->
        SIP_1_0

    | "SIP/2.0" ->
        SIP_2_0

    | sipver when String.starts_with sipver "SIP/" ->
        UnknownSipVersion (String.slice ~first:4 sipver)

    | _ -> raise (Failure "sip_version_of_string")

let string_of_sip_version = function
    | SIP_1_0 -> "SIP/1.0"
    | SIP_2_0 -> "SIP/2.0"
    | UnknownSipVersion s -> "SIP/"^ s

(*********************************************************************************************************************
 *)

type sip_via =
    | SipVia of string

let sip_via_of_string = function
    | s -> SipVia s

let string_of_sip_via = function
    | SipVia s -> s

(*********************************************************************************************************************
 *)

class type sip_message =
    object

        method sip_version      : sip_version

        method content_length   : int

        method addr_to          : sip_address

        method addr_from        : sip_address

        method vias             : sip_via list

        method call_id          : sip_call_id

        method cseq             : sip_cseq

        method contact          : sip_address option

        method header           : string -> string

        method header_option    : string -> string option

        method header_all       : string -> string list

    end

class type sip_request =
    object

        method sip_method       : sip_request_method

        method uri              : sip_uri

        method max_forwards     : int

        inherit sip_message

    end

class type sip_response =
    object

        method sip_response_code    : sip_response_code

        method sip_response_message : string

        inherit sip_message

    end
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.