From 631fffee8a28b1bec5ed1f1d26a20e0135967f99 Mon Sep 17 00:00:00 2001 From: Mamadou DIOP Date: Mon, 17 Aug 2015 01:56:35 +0200 Subject: - --- tinySIP/ragel/tsip_machine_header.rl | 133 ++++ tinySIP/ragel/tsip_machine_message.rl | 57 ++ tinySIP/ragel/tsip_machine_utils.rl | 197 +++++ tinySIP/ragel/tsip_parser_header.rl | 863 +++++++++++++++++++++ tinySIP/ragel/tsip_parser_header_Accept_Contact.rl | 1 + .../ragel/tsip_parser_header_Accept_Encoding.rl | 1 + .../ragel/tsip_parser_header_Accept_Language.rl | 1 + .../tsip_parser_header_Accept_Resource_Priority.rl | 1 + tinySIP/ragel/tsip_parser_header_Alert_Info.rl | 1 + tinySIP/ragel/tsip_parser_header_Allow.rl | 190 +++++ tinySIP/ragel/tsip_parser_header_Allow_Events.rl | 170 ++++ .../tsip_parser_header_Authentication_Info.rl | 1 + tinySIP/ragel/tsip_parser_header_Authorization.rl | 285 +++++++ tinySIP/ragel/tsip_parser_header_CSeq.rl | 168 ++++ tinySIP/ragel/tsip_parser_header_Call_ID.rl | 163 ++++ tinySIP/ragel/tsip_parser_header_Call_Info.rl | 1 + tinySIP/ragel/tsip_parser_header_Contact.rl | 256 ++++++ .../tsip_parser_header_Content_Disposition.rl | 1 + .../ragel/tsip_parser_header_Content_Encoding.rl | 1 + .../ragel/tsip_parser_header_Content_Language.rl | 1 + tinySIP/ragel/tsip_parser_header_Content_Length.rl | 157 ++++ tinySIP/ragel/tsip_parser_header_Content_Type.rl | 181 +++++ tinySIP/ragel/tsip_parser_header_Date.rl | 221 ++++++ tinySIP/ragel/tsip_parser_header_Dummy.rl | 170 ++++ tinySIP/ragel/tsip_parser_header_Error_Info.rl | 1 + tinySIP/ragel/tsip_parser_header_Event.rl | 168 ++++ tinySIP/ragel/tsip_parser_header_Expires.rl | 155 ++++ tinySIP/ragel/tsip_parser_header_From.rl | 196 +++++ tinySIP/ragel/tsip_parser_header_History_Info.rl | 1 + tinySIP/ragel/tsip_parser_header_Identity.rl | 1 + tinySIP/ragel/tsip_parser_header_Identity_Info.rl | 1 + tinySIP/ragel/tsip_parser_header_In_Reply_To.rl | 1 + tinySIP/ragel/tsip_parser_header_Join.rl | 1 + tinySIP/ragel/tsip_parser_header_MIME_Version.rl | 1 + tinySIP/ragel/tsip_parser_header_Max_Forwards.rl | 155 ++++ tinySIP/ragel/tsip_parser_header_Min_Expires.rl | 160 ++++ tinySIP/ragel/tsip_parser_header_Min_SE.rl | 160 ++++ tinySIP/ragel/tsip_parser_header_Organization.rl | 1 + .../tsip_parser_header_P_Access_Network_Info.rl | 170 ++++ tinySIP/ragel/tsip_parser_header_P_Answer_State.rl | 1 + .../tsip_parser_header_P_Asserted_Identity.rl | 200 +++++ .../ragel/tsip_parser_header_P_Associated_URI.rl | 212 +++++ .../ragel/tsip_parser_header_P_Called_Party_ID.rl | 1 + ..._parser_header_P_Charging_Function_Addresses.rl | 195 +++++ .../ragel/tsip_parser_header_P_Charging_Vector.rl | 1 + .../ragel/tsip_parser_header_P_DCS_Billing_Info.rl | 1 + tinySIP/ragel/tsip_parser_header_P_DCS_LAES.rl | 1 + tinySIP/ragel/tsip_parser_header_P_DCS_OSPS.rl | 1 + tinySIP/ragel/tsip_parser_header_P_DCS_Redirect.rl | 1 + .../tsip_parser_header_P_DCS_Trace_Party_ID.rl | 1 + tinySIP/ragel/tsip_parser_header_P_Early_Media.rl | 1 + .../tsip_parser_header_P_Media_Authorization.rl | 1 + .../tsip_parser_header_P_Preferred_Identity.rl | 198 +++++ tinySIP/ragel/tsip_parser_header_P_Profile_Key.rl | 1 + .../ragel/tsip_parser_header_P_User_Database.rl | 1 + .../tsip_parser_header_P_Visited_Network_ID.rl | 1 + tinySIP/ragel/tsip_parser_header_Path.rl | 214 +++++ tinySIP/ragel/tsip_parser_header_Priority.rl | 1 + tinySIP/ragel/tsip_parser_header_Privacy.rl | 176 +++++ .../ragel/tsip_parser_header_Proxy_Authenticate.rl | 245 ++++++ .../tsip_parser_header_Proxy_Authorization.rl | 286 +++++++ tinySIP/ragel/tsip_parser_header_Proxy_Require.rl | 181 +++++ tinySIP/ragel/tsip_parser_header_RAck.rl | 170 ++++ tinySIP/ragel/tsip_parser_header_RSeq.rl | 158 ++++ tinySIP/ragel/tsip_parser_header_Reason.rl | 1 + tinySIP/ragel/tsip_parser_header_Record_Route.rl | 211 +++++ tinySIP/ragel/tsip_parser_header_Refer_Sub.rl | 165 ++++ tinySIP/ragel/tsip_parser_header_Refer_To.rl | 195 +++++ tinySIP/ragel/tsip_parser_header_Referred_By.rl | 207 +++++ tinySIP/ragel/tsip_parser_header_Reject_Contact.rl | 1 + tinySIP/ragel/tsip_parser_header_Replaces.rl | 1 + tinySIP/ragel/tsip_parser_header_Reply_To.rl | 1 + .../tsip_parser_header_Request_Disposition.rl | 1 + tinySIP/ragel/tsip_parser_header_Require.rl | 180 +++++ .../ragel/tsip_parser_header_Resource_Priority.rl | 1 + tinySIP/ragel/tsip_parser_header_Retry_After.rl | 1 + tinySIP/ragel/tsip_parser_header_Route.rl | 218 ++++++ tinySIP/ragel/tsip_parser_header_SIP_ETag.rl | 163 ++++ tinySIP/ragel/tsip_parser_header_SIP_If_Match.rl | 165 ++++ .../ragel/tsip_parser_header_Security_Client.rl | 297 +++++++ .../ragel/tsip_parser_header_Security_Server.rl | 280 +++++++ .../ragel/tsip_parser_header_Security_Verify.rl | 279 +++++++ tinySIP/ragel/tsip_parser_header_Server.rl | 167 ++++ tinySIP/ragel/tsip_parser_header_Service_Route.rl | 213 +++++ .../ragel/tsip_parser_header_Session_Expires.rl | 172 ++++ tinySIP/ragel/tsip_parser_header_Subject.rl | 1 + .../ragel/tsip_parser_header_Subscription_State.rl | 189 +++++ tinySIP/ragel/tsip_parser_header_Supported.rl | 180 +++++ tinySIP/ragel/tsip_parser_header_Target_Dialog.rl | 1 + tinySIP/ragel/tsip_parser_header_Timestamp.rl | 1 + tinySIP/ragel/tsip_parser_header_To.rl | 200 +++++ tinySIP/ragel/tsip_parser_header_Unsupported.rl | 1 + tinySIP/ragel/tsip_parser_header_User_Agent.rl | 160 ++++ tinySIP/ragel/tsip_parser_header_Via.rl | 345 ++++++++ .../ragel/tsip_parser_header_WWW_Authenticate.rl | 244 ++++++ tinySIP/ragel/tsip_parser_header_Warning.rl | 190 +++++ tinySIP/ragel/tsip_parser_message.rl | 275 +++++++ tinySIP/ragel/tsip_parser_uri.rl | 180 +++++ 98 files changed, 11528 insertions(+) create mode 100644 tinySIP/ragel/tsip_machine_header.rl create mode 100644 tinySIP/ragel/tsip_machine_message.rl create mode 100644 tinySIP/ragel/tsip_machine_utils.rl create mode 100644 tinySIP/ragel/tsip_parser_header.rl create mode 100644 tinySIP/ragel/tsip_parser_header_Accept_Contact.rl create mode 100644 tinySIP/ragel/tsip_parser_header_Accept_Encoding.rl create mode 100644 tinySIP/ragel/tsip_parser_header_Accept_Language.rl create mode 100644 tinySIP/ragel/tsip_parser_header_Accept_Resource_Priority.rl create mode 100644 tinySIP/ragel/tsip_parser_header_Alert_Info.rl create mode 100644 tinySIP/ragel/tsip_parser_header_Allow.rl create mode 100644 tinySIP/ragel/tsip_parser_header_Allow_Events.rl create mode 100644 tinySIP/ragel/tsip_parser_header_Authentication_Info.rl create mode 100644 tinySIP/ragel/tsip_parser_header_Authorization.rl create mode 100644 tinySIP/ragel/tsip_parser_header_CSeq.rl create mode 100644 tinySIP/ragel/tsip_parser_header_Call_ID.rl create mode 100644 tinySIP/ragel/tsip_parser_header_Call_Info.rl create mode 100644 tinySIP/ragel/tsip_parser_header_Contact.rl create mode 100644 tinySIP/ragel/tsip_parser_header_Content_Disposition.rl create mode 100644 tinySIP/ragel/tsip_parser_header_Content_Encoding.rl create mode 100644 tinySIP/ragel/tsip_parser_header_Content_Language.rl create mode 100644 tinySIP/ragel/tsip_parser_header_Content_Length.rl create mode 100644 tinySIP/ragel/tsip_parser_header_Content_Type.rl create mode 100644 tinySIP/ragel/tsip_parser_header_Date.rl create mode 100644 tinySIP/ragel/tsip_parser_header_Dummy.rl create mode 100644 tinySIP/ragel/tsip_parser_header_Error_Info.rl create mode 100644 tinySIP/ragel/tsip_parser_header_Event.rl create mode 100644 tinySIP/ragel/tsip_parser_header_Expires.rl create mode 100644 tinySIP/ragel/tsip_parser_header_From.rl create mode 100644 tinySIP/ragel/tsip_parser_header_History_Info.rl create mode 100644 tinySIP/ragel/tsip_parser_header_Identity.rl create mode 100644 tinySIP/ragel/tsip_parser_header_Identity_Info.rl create mode 100644 tinySIP/ragel/tsip_parser_header_In_Reply_To.rl create mode 100644 tinySIP/ragel/tsip_parser_header_Join.rl create mode 100644 tinySIP/ragel/tsip_parser_header_MIME_Version.rl create mode 100644 tinySIP/ragel/tsip_parser_header_Max_Forwards.rl create mode 100644 tinySIP/ragel/tsip_parser_header_Min_Expires.rl create mode 100644 tinySIP/ragel/tsip_parser_header_Min_SE.rl create mode 100644 tinySIP/ragel/tsip_parser_header_Organization.rl create mode 100644 tinySIP/ragel/tsip_parser_header_P_Access_Network_Info.rl create mode 100644 tinySIP/ragel/tsip_parser_header_P_Answer_State.rl create mode 100644 tinySIP/ragel/tsip_parser_header_P_Asserted_Identity.rl create mode 100644 tinySIP/ragel/tsip_parser_header_P_Associated_URI.rl create mode 100644 tinySIP/ragel/tsip_parser_header_P_Called_Party_ID.rl create mode 100644 tinySIP/ragel/tsip_parser_header_P_Charging_Function_Addresses.rl create mode 100644 tinySIP/ragel/tsip_parser_header_P_Charging_Vector.rl create mode 100644 tinySIP/ragel/tsip_parser_header_P_DCS_Billing_Info.rl create mode 100644 tinySIP/ragel/tsip_parser_header_P_DCS_LAES.rl create mode 100644 tinySIP/ragel/tsip_parser_header_P_DCS_OSPS.rl create mode 100644 tinySIP/ragel/tsip_parser_header_P_DCS_Redirect.rl create mode 100644 tinySIP/ragel/tsip_parser_header_P_DCS_Trace_Party_ID.rl create mode 100644 tinySIP/ragel/tsip_parser_header_P_Early_Media.rl create mode 100644 tinySIP/ragel/tsip_parser_header_P_Media_Authorization.rl create mode 100644 tinySIP/ragel/tsip_parser_header_P_Preferred_Identity.rl create mode 100644 tinySIP/ragel/tsip_parser_header_P_Profile_Key.rl create mode 100644 tinySIP/ragel/tsip_parser_header_P_User_Database.rl create mode 100644 tinySIP/ragel/tsip_parser_header_P_Visited_Network_ID.rl create mode 100644 tinySIP/ragel/tsip_parser_header_Path.rl create mode 100644 tinySIP/ragel/tsip_parser_header_Priority.rl create mode 100644 tinySIP/ragel/tsip_parser_header_Privacy.rl create mode 100644 tinySIP/ragel/tsip_parser_header_Proxy_Authenticate.rl create mode 100644 tinySIP/ragel/tsip_parser_header_Proxy_Authorization.rl create mode 100644 tinySIP/ragel/tsip_parser_header_Proxy_Require.rl create mode 100644 tinySIP/ragel/tsip_parser_header_RAck.rl create mode 100644 tinySIP/ragel/tsip_parser_header_RSeq.rl create mode 100644 tinySIP/ragel/tsip_parser_header_Reason.rl create mode 100644 tinySIP/ragel/tsip_parser_header_Record_Route.rl create mode 100644 tinySIP/ragel/tsip_parser_header_Refer_Sub.rl create mode 100644 tinySIP/ragel/tsip_parser_header_Refer_To.rl create mode 100644 tinySIP/ragel/tsip_parser_header_Referred_By.rl create mode 100644 tinySIP/ragel/tsip_parser_header_Reject_Contact.rl create mode 100644 tinySIP/ragel/tsip_parser_header_Replaces.rl create mode 100644 tinySIP/ragel/tsip_parser_header_Reply_To.rl create mode 100644 tinySIP/ragel/tsip_parser_header_Request_Disposition.rl create mode 100644 tinySIP/ragel/tsip_parser_header_Require.rl create mode 100644 tinySIP/ragel/tsip_parser_header_Resource_Priority.rl create mode 100644 tinySIP/ragel/tsip_parser_header_Retry_After.rl create mode 100644 tinySIP/ragel/tsip_parser_header_Route.rl create mode 100644 tinySIP/ragel/tsip_parser_header_SIP_ETag.rl create mode 100644 tinySIP/ragel/tsip_parser_header_SIP_If_Match.rl create mode 100644 tinySIP/ragel/tsip_parser_header_Security_Client.rl create mode 100644 tinySIP/ragel/tsip_parser_header_Security_Server.rl create mode 100644 tinySIP/ragel/tsip_parser_header_Security_Verify.rl create mode 100644 tinySIP/ragel/tsip_parser_header_Server.rl create mode 100644 tinySIP/ragel/tsip_parser_header_Service_Route.rl create mode 100644 tinySIP/ragel/tsip_parser_header_Session_Expires.rl create mode 100644 tinySIP/ragel/tsip_parser_header_Subject.rl create mode 100644 tinySIP/ragel/tsip_parser_header_Subscription_State.rl create mode 100644 tinySIP/ragel/tsip_parser_header_Supported.rl create mode 100644 tinySIP/ragel/tsip_parser_header_Target_Dialog.rl create mode 100644 tinySIP/ragel/tsip_parser_header_Timestamp.rl create mode 100644 tinySIP/ragel/tsip_parser_header_To.rl create mode 100644 tinySIP/ragel/tsip_parser_header_Unsupported.rl create mode 100644 tinySIP/ragel/tsip_parser_header_User_Agent.rl create mode 100644 tinySIP/ragel/tsip_parser_header_Via.rl create mode 100644 tinySIP/ragel/tsip_parser_header_WWW_Authenticate.rl create mode 100644 tinySIP/ragel/tsip_parser_header_Warning.rl create mode 100644 tinySIP/ragel/tsip_parser_message.rl create mode 100644 tinySIP/ragel/tsip_parser_uri.rl (limited to 'tinySIP/ragel') diff --git a/tinySIP/ragel/tsip_machine_header.rl b/tinySIP/ragel/tsip_machine_header.rl new file mode 100644 index 0000000..84ff59c --- /dev/null +++ b/tinySIP/ragel/tsip_machine_header.rl @@ -0,0 +1,133 @@ +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* DOUBANGO is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with DOUBANGO. +* +*/ +/**@file tsip_machine_headers.rl. + * @brief Ragel file. + * + * @author Mamadou Diop + * + + */ + +/*== Header pasrsing machine. Supports both full-length and compact mode. */ +%%{ + machine tsip_machine_header; + + Accept = "Accept"i SP* HCOLON SP*<: any* :>CRLF @parse_header_Accept; + Accept_Contact = ("Accept-Contact"i | "a") SP* HCOLON SP*<: any* :>CRLF @parse_header_Accept_Contact; + Accept_Encoding = "Accept-Encoding"i SP* HCOLON SP*<: any* :>CRLF @parse_header_Accept_Encoding; + Accept_Language = "Accept-Language"i SP* HCOLON SP*<: any* :>CRLF @parse_header_Accept_Language; + Accept_Resource_Priority = "Accept-Resource-Priority"i SP* HCOLON SP*<: any* :>CRLF @parse_header_Accept_Resource_Priority; + Alert_Info = "Alert-Info"i SP* HCOLON SP*<: any* :>CRLF @parse_header_Alert_Info; + Allow = "Allow"i SP* HCOLON SP*<: any* :>CRLF @parse_header_Allow; + Allow_Events = ("Allow-Events"i | "u") SP* HCOLON SP*<: any* :>CRLF @parse_header_Allow_Events; + Authentication_Info = "Authentication-Info"i SP* HCOLON SP*<: any* :>CRLF @parse_header_Authentication_Info; + Authorization = "Authorization"i SP* HCOLON SP*<: any* :>CRLF @parse_header_Authorization; + Call_ID = ("Call-ID"i | "i") SP* HCOLON SP*<: any* :>CRLF @parse_header_Call_ID; + Call_Info = "Call-Info"i SP* HCOLON SP*<: any* :>CRLF @parse_header_Call_Info; + Contact = ("Contact"i | "m") SP* HCOLON SP*<: any* :>CRLF @parse_header_Contact; + Content_Disposition = "Content-Disposition"i SP* HCOLON SP*<: any* :>CRLF @parse_header_Content_Disposition; + Content_Encoding = ("Content-Encoding"i | "e") SP* HCOLON SP*<: any* :>CRLF @parse_header_Content_Encoding; + Content_Language = "Content-Language"i SP* HCOLON SP*<: any* :>CRLF @parse_header_Content_Language; + Content_Length = ("Content-Length"i | "l") SP* HCOLON SP*<: any* :>CRLF @parse_header_Content_Length; + Content_Type = ("Content-Type"i | "c") SP* HCOLON SP*<: any* :>CRLF @parse_header_Content_Type; + CSeq = "CSeq"i SP* HCOLON SP*<: any* :>CRLF @parse_header_CSeq; + Date = "Date"i SP* HCOLON SP*<: any* :>CRLF @parse_header_Date; + Error_Info = "Error-Info"i SP* HCOLON SP*<: any* :>CRLF @parse_header_Error_Info; + Event = ("Event"i | "o"i) SP* HCOLON SP*<: any* :>CRLF @parse_header_Event; + Expires = "Expires"i SP* HCOLON SP*<: any* :>CRLF @parse_header_Expires; + From = ("From"i | "f") SP* HCOLON SP*<: any* :>CRLF @parse_header_From; + History_Info = "History-Info"i SP* HCOLON SP*<: any* :>CRLF @parse_header_History_Info; + Identity = ("Identity"i | "y") SP* HCOLON SP*<: any* :>CRLF @parse_header_Identity; + Identity_Info = ("Identity-Info"i | "n") SP* HCOLON SP*<: any* :>CRLF @parse_header_Identity_Info; + In_Reply_To = "In_Reply-To"i SP* HCOLON SP*<: any* :>CRLF @parse_header_In_Reply_To; + Join = "Join"i SP* HCOLON SP*<: any* :>CRLF @parse_header_Join; + Max_Forwards = "Max-Forwards"i SP* HCOLON SP*<: any* :>CRLF @parse_header_Max_Forwards; + MIME_Version = "MIME-Version"i SP* HCOLON SP*<: any* :>CRLF @parse_header_MIME_Version; + Min_Expires = "Min-Expires"i SP* HCOLON SP*<: any* :>CRLF @parse_header_Min_Expires; + Min_SE = "Min-SE"i SP* HCOLON SP*<: any* :>CRLF @parse_header_Min_SE; + Organization = "Organization"i SP* HCOLON SP*<: any* :>CRLF @parse_header_Organization; + Path = "Path"i SP* HCOLON SP*<: any* :>CRLF @parse_header_Path; + Priority = "Priority"i SP* HCOLON SP*<: any* :>CRLF @parse_header_Priority; + Privacy = "Privacy"i SP* HCOLON SP*<: any* :>CRLF @parse_header_Privacy; + Proxy_Authenticate = "Proxy-Authenticate"i SP* HCOLON SP*<: any* :>CRLF @parse_header_Proxy_Authenticate; + Proxy_Authorization = "Proxy-Authorization"i SP* HCOLON SP*<: any* :>CRLF @parse_header_Proxy_Authorization; + Proxy_Require = "Proxy-Require"i SP* HCOLON SP*<: any* :>CRLF @parse_header_Proxy_Require; + RAck = "RAck"i SP* HCOLON SP*<: any* :>CRLF @parse_header_RAck; + Reason = "Reason"i SP* HCOLON SP*<: any* :>CRLF @parse_header_Reason; + Record_Route = "Record-Route"i SP* HCOLON SP*<: any* :>CRLF @parse_header_Record_Route; + Refer_Sub = "Refer-Sub"i SP* HCOLON SP*<: any* :>CRLF @parse_header_Refer_Sub; + Refer_To = ("Refer-To"i | "r") SP* HCOLON SP*<: any* :>CRLF @parse_header_Refer_To; + Referred_By = ("Referred-By"i | "b") SP* HCOLON SP*<: any* :>CRLF @parse_header_Referred_By; + Reject_Contact = ("Reject-Contact"i | "j") SP* HCOLON SP*<: any* :>CRLF @parse_header_Reject_Contact; + Replaces = "Replaces"i SP* HCOLON SP*<: any* :>CRLF @parse_header_Replaces; + Reply_To = "Reply-To"i SP* HCOLON SP*<: any* :>CRLF @parse_header_Reply_To; + Request_Disposition = ("Request-Disposition"i | "d") SP* HCOLON SP*<: any* :>CRLF @parse_header_Request_Disposition; + Require = "Require"i SP* HCOLON SP*<: any* :>CRLF @parse_header_Require; + Resource_Priority = "Resource-Priority"i SP* HCOLON SP*<: any* :>CRLF @parse_header_Resource_Priority; + Retry_After = "Retry-After"i SP* HCOLON SP*<: any* :>CRLF @parse_header_Retry_After; + Route = "Route"i SP* HCOLON SP*<: any* :>CRLF @parse_header_Route; + RSeq = "RSeq"i SP* HCOLON SP*<: any* :>CRLF @parse_header_RSeq; + Security_Client = "Security-Client"i SP* HCOLON SP*<: any* :>CRLF @parse_header_Security_Client; + Security_Server = "Security-Server"i SP* HCOLON SP*<: any* :>CRLF @parse_header_Security_Server; + Security_Verify = "Security-Verify"i SP* HCOLON SP*<: any* :>CRLF @parse_header_Security_Verify; + Server = "Server"i SP* HCOLON SP*<: any* :>CRLF @parse_header_Server; + Service_Route = "Service-Route"i SP* HCOLON SP*<: any* :>CRLF @parse_header_Service_Route; + Session_Expires = ("Session-Expires"i | "x") SP* HCOLON SP*<: any* :>CRLF @parse_header_Session_Expires; + SIP_ETag = "SIP-ETag"i SP* HCOLON SP*<: any* :>CRLF @parse_header_SIP_ETag; + SIP_If_Match = "SIP-If-Match"i SP* HCOLON SP*<: any* :>CRLF @parse_header_SIP_If_Match; + Subject = ("Subject"i | "s"i) SP* HCOLON SP*<: any* :>CRLF @parse_header_Subject; + Subscription_State = ("Subscription-State"i) SP* HCOLON SP*<: any* :>CRLF @parse_header_Subscription_State; + Supported = ("Supported"i | "k") SP* HCOLON SP*<: any* :>CRLF @parse_header_Supported; + Target_Dialog = "Target-Dialog"i SP* HCOLON SP*<: any* :>CRLF @parse_header_Target_Dialog; + Timestamp = "Timestamp"i SP* HCOLON SP*<: any* :>CRLF @parse_header_Timestamp; + To = ("To"i | "t") SP* HCOLON SP*<: any* :>CRLF @parse_header_To; + Unsupported = "Unsupported"i SP* HCOLON SP*<: any* :>CRLF @parse_header_Unsupported; + User_Agent = "User-Agent"i SP* HCOLON SP*<: any* :>CRLF @parse_header_User_Agent; + Via = ("Via"i | "v") SP* HCOLON SP*<: any* :>CRLF @parse_header_Via; + Warning = "Warning"i SP* HCOLON SP*<: any* :>CRLF @parse_header_Warning; + WWW_Authenticate = "WWW-Authenticate"i SP* HCOLON SP*<: any* :>(CRLF when prev_not_comma) @parse_header_WWW_Authenticate; + P_Access_Network_Info = "P-Access-Network-Info"i SP* HCOLON SP*<: any* :>CRLF @parse_header_P_Access_Network_Info; + P_Answer_State = "P-Answer-State"i SP* HCOLON SP*<: any* :>CRLF @parse_header_P_Answer_State; + P_Asserted_Identity = "P-Asserted-Identity"i SP* HCOLON SP*<: any* :>CRLF @parse_header_P_Asserted_Identity; + P_Associated_URI = "P-Associated-URI"i SP* HCOLON SP*<: any* :>CRLF @parse_header_P_Associated_URI; + P_Called_Party_ID = "P-Called-Party-ID"i SP* HCOLON SP*<: any* :>CRLF @parse_header_P_Called_Party_ID; + P_Charging_Function_Addresses = "P-Charging-Function-Addresses"i SP* HCOLON SP*<: any* :>CRLF @parse_header_P_Charging_Function_Addresses; + P_Charging_Vector = "P-Charging-Vector"i SP* HCOLON SP*<: any* :>CRLF @parse_header_P_Charging_Vector; + P_DCS_Billing_Info = "P-DCS-Billing-Info"i SP* HCOLON SP*<: any* :>CRLF @parse_header_P_DCS_Billing_Info; + P_DCS_LAES = "P-DCS-LAES"i SP* HCOLON SP*<: any* :>CRLF @parse_header_P_DCS_LAES; + P_DCS_OSPS = "P-DCS-OSPS"i SP* HCOLON SP*<: any* :>CRLF @parse_header_P_DCS_OSPS; + P_DCS_Redirect = "P-DCS-Redirect"i SP* HCOLON SP*<: any* :>CRLF @parse_header_P_DCS_Redirect; + P_DCS_Trace_Party_ID = "P-DCS-Trace-Party-ID"i SP* HCOLON SP*<: any* :>CRLF @parse_header_P_DCS_Trace_Party_ID; + P_Early_Media = "P-Early-Media"i SP* HCOLON SP*<: any* :>CRLF @parse_header_P_Early_Media; + P_Media_Authorization = "P-Media-Authorization"i SP* HCOLON SP*<: any* :>CRLF @parse_header_P_Media_Authorization; + P_Preferred_Identity = "P-Preferred-Identity"i SP* HCOLON SP*<: any* :>CRLF @parse_header_P_Preferred_Identity; + P_Profile_Key = "P-Profile-Key"i SP* HCOLON SP*<: any* :>CRLF @parse_header_P_Profile_Key; + P_User_Database = "P-User-Database"i SP* HCOLON SP*<: any* :>CRLF @parse_header_P_User_Database; + P_Visited_Network_ID = "P-Visited-Network-ID"i SP* HCOLON SP*<: any* :>CRLF @parse_header_P_Visited_Network_ID; + + ###### + extension_header = (token) SP* HCOLON SP*<: any* :>CRLF @parse_header_extension_header; + + HEADER = ( Accept | Accept_Contact | Accept_Encoding | Accept_Language | Accept_Resource_Priority | Alert_Info | Allow | Allow_Events | Authentication_Info | Authorization | Call_ID | Call_Info | Contact | Content_Disposition | Content_Encoding | Content_Language | Content_Length | Content_Type | CSeq | Date | Error_Info | Event | Expires | From | History_Info | Identity | Identity_Info | In_Reply_To | Join | Max_Forwards | MIME_Version | Min_Expires | Min_SE | Organization | Path | Priority | Privacy | Proxy_Authenticate | Proxy_Authorization | Proxy_Require | RAck | Reason | Record_Route | Refer_Sub | Refer_To | Referred_By | Reject_Contact | Replaces | Reply_To | Request_Disposition | Require | Resource_Priority | Retry_After | Route | RSeq | Security_Client | Security_Server | Security_Verify | Server | Service_Route | Session_Expires | SIP_ETag | SIP_If_Match | Subject | Subscription_State | Supported | Target_Dialog | Timestamp | To | Unsupported | User_Agent | Via | Warning | WWW_Authenticate | P_Access_Network_Info | P_Answer_State | P_Asserted_Identity | P_Associated_URI | P_Called_Party_ID | P_Charging_Function_Addresses | P_Charging_Vector | P_DCS_Billing_Info | P_DCS_LAES | P_DCS_OSPS | P_DCS_Redirect | P_DCS_Trace_Party_ID | P_Early_Media | P_Media_Authorization | P_Preferred_Identity | P_Profile_Key | P_User_Database | P_Visited_Network_ID)@1 | (extension_header)@0; + + +}%% diff --git a/tinySIP/ragel/tsip_machine_message.rl b/tinySIP/ragel/tsip_machine_message.rl new file mode 100644 index 0000000..42ffbb0 --- /dev/null +++ b/tinySIP/ragel/tsip_machine_message.rl @@ -0,0 +1,57 @@ +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* DOUBANGO is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with DOUBANGO. +* +*/ +/**@file tsip_machine_message.rl + * @brief Ragel file. + * + * @author Mamadou Diop + * + + */ +%%{ + machine tsip_machine_message; + + #message_body = OCTET*; + message_body = any*; + SIP_Version = ("SIP"i "/" DIGIT+ "." DIGIT+) >tag %parse_sipversion; + + action prev_not_comma{ + prev_not_comma(p) + } + + message_header = any+>tag :>(CRLF when prev_not_comma) %parse_header; + + # SIP RESPONSE + Reason_Phrase = (( reserved | unreserved | escaped | UTF8_NONASCII | UTF8_CONT | SP | HTAB )*)>tag %parse_reason_phrase; + Status_Line = SIP_Version :>SP Status_Code>tag %parse_status_code :>SP Reason_Phrase :>CRLF; + Response = Status_Line (message_header* :>CRLF); + + + # SIP REQUEST + URI = (scheme HCOLON any+)>tag %parse_requesturi; + Request_URI = URI; + Request_Line = Method>tag %parse_method :>SP Request_URI :>SP SIP_Version :>CRLF; + Request = Request_Line (message_header* :>CRLF); + + # SIP MESSAGE + SIP_message = (Response | Request)>1 @eoh message_body?>0; + +}%% diff --git a/tinySIP/ragel/tsip_machine_utils.rl b/tinySIP/ragel/tsip_machine_utils.rl new file mode 100644 index 0000000..678545b --- /dev/null +++ b/tinySIP/ragel/tsip_machine_utils.rl @@ -0,0 +1,197 @@ +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* DOUBANGO is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with DOUBANGO. +* +*/ +/**@file tsip_machine_utils.rl + * @brief Ragel file. + * + * @author Mamadou Diop + * + + */ +%%{ + + machine tsip_machine_utils; + + #OCTET = 0x00..0xff; + OCTET = "0x"[0-9A-Fa-f]+; + CHAR = 0x01..0x7f; + VCHAR = 0x21..0x7e; + ALPHA = 0x41..0x5a | 0x61..0x7a; + DIGIT = 0x30..0x39; + CTL = 0x00..0x1f | 0x7f; + HTAB = "\t"; + LF = "\n"; + CR = "\r"; + SP = " "; + DQUOTE = "\""; + BIT = "0" | "1"; + HEXDIG = DIGIT | "A"i | "B"i | "C"i | "D"i | "E"i | "F"i; + CRLF = CR LF; + WSP = SP | HTAB; + LWSP = ( WSP | ( CRLF WSP ) )*; + LWS = ( WSP* CRLF )? WSP+; + SWS = LWS?; + EQUAL = SWS "=" SWS; + LHEX = DIGIT | 0x61..0x66; + HCOLON = ( SP | HTAB )* ":" SWS; + separators = "(" | ")" | "<" | ">" | "@" | "," | ";" | ":" | "\\" | DQUOTE | "/" | "[" | "]" | "?" | "=" | "{" | "}" | SP | HTAB; + STAR = SWS "*" SWS; + SLASH = SWS "/" SWS; + LPAREN = SWS "(" SWS; + RPAREN = SWS ")" SWS; + COMMA = SWS "," SWS; + SEMI = SWS ";" SWS; + COLON = SWS ":" SWS; + LAQUOT = SWS "<"; + LDQUOT = SWS DQUOTE; + RAQUOT = ">" SWS; + RDQUOT = DQUOTE SWS; + UTF8_CONT = 0x80..0xbf; + ##### FIXME: UTF8_NONASCII up to 2bytes will fail on Android + UTF8_NONASCII = ( 0x80..0xff ); + #UTF8_NONASCII = ( 0xc0..0xdf UTF8_CONT ) | ( 0xe0..0xef UTF8_CONT{2} ) | ( 0xf0..0xf7 UTF8_CONT{3} ) | ( 0xf8..0xfb UTF8_CONT{4} ) | ( 0xfc..0xfd UTF8_CONT{5} ); ctext = 0x21..0x27 | 0x2a..0x5b | 0x5d..0x7e | UTF8_NONASCII | LWS; + qvalue = ( "0" ( "." DIGIT{,3} )? ) | ( "1" ( "." "0"{,3} )? ); + alphanum = ALPHA | DIGIT; + token = ( alphanum | "-" | "." | "!" | "%" | "*" | "_" | "+" | "`" | "'" | "~" )+; + ietf_token = token; + x_token = "x-"i token; + iana_token = token; + token_nodot = ( alphanum | "-" | "!" | "%" | "*" | "_" | "+" | "`" | "'" | "~" )+; + word = ( alphanum | "-" | "." | "!" | "%" | "*" | "_" | "+" | "`" | "'" | "~" | "(" | ")" | "<" | ">" | ":" | "\\" | DQUOTE | "/" | "[" | "]" | "?" | "{" | "}" )+; + domainlabel = alphanum | ( alphanum ( alphanum | "-" )* alphanum ); + toplabel = ALPHA | ( ALPHA ( alphanum | "-" )* alphanum ); + hostname = ( domainlabel "." )* toplabel "."?; + IPv4address = DIGIT{1,3} "." DIGIT{1,3} "." DIGIT{1,3} "." DIGIT{1,3}; + hex4 = HEXDIG{1,4}; + hexseq = hex4 ( ":" hex4 )*; + hexpart = hexseq | ( hexseq "::" hexseq? ) | ( "::" hexseq? ); + IPv6address = hexpart ( ":" IPv4address )?; + IPv6reference = "[" IPv6address "]"; + host = hostname | IPv4address | IPv6reference; + qdtext = LWS | "!" | 0x23..0x5b | 0x5d..0x7e | UTF8_NONASCII; + quoted_pair = "\\" ( 0x00..0x09 | 0x0b..0x0c | 0x0e..0x7f ); + quoted_string = SWS DQUOTE ( qdtext | quoted_pair )* DQUOTE; + gen_value = token | host | quoted_string; + generic_param = token ( EQUAL gen_value )?; + accept_param = ( "q"i EQUAL qvalue ) | generic_param; + mark = "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")"; + unreserved = alphanum | mark; + escaped = "%" HEXDIG HEXDIG; + user_unreserved = "&" | "=" | "+" | "$" | "," | ";" | "?" | "/"; + user = ( unreserved | escaped | user_unreserved )+; + visual_separator = "-" | "." | "(" | ")"; + phonedigit = DIGIT | visual_separator?; + global_number_digits = "+" phonedigit* DIGIT phonedigit*; + param_unreserved = "[" | "]" | "/" | ":" | "&" | "+" | "$"; + pct_encoded = "%" HEXDIG HEXDIG; + paramchar = param_unreserved | unreserved | pct_encoded; + pname = paramchar+; + pvalue = paramchar+; + parameter = ";" pname ( "=" pvalue )?; + extension = ";ext="i phonedigit+; + reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | ","; + uric = reserved | unreserved | escaped; + isdn_subaddress = ";isub="i uric+; + not_defined = token; + global_rn = not_defined; + hex_phonedigit = HEXDIG | visual_separator; + domainname = ( domainlabel "." )* toplabel "."?; + phonedigit_hex = HEXDIG | "*" | "#" | visual_separator?; + global_hex_digits = "+" phonedigit{1,3} phonedigit_hex*; + rn_descriptor = domainname | global_hex_digits; + rn_context = ";rn-context="i rn_descriptor; + local_rn = hex_phonedigit+ rn_context; + rn = ";rn="i ( global_rn | local_rn ); + global_cic = global_hex_digits; + cic_context = ";cic-context="i rn_descriptor; + local_cic = hex_phonedigit+ cic_context; + cic = ";cic="i ( global_cic | local_cic ); + npdi = ";npdi"i; + enum_dip_indicator = ";enumdi"i; + trunk_group_unreserved = "/" | "&" | "+" | "$"; + trunk_group_label = ( unreserved | escaped | trunk_group_unreserved )+; + trunk_group = ";tgrp="i trunk_group_label; + descriptor = domainname | global_number_digits; + trunk_context = ";trunk-context="i descriptor; + par = parameter | extension | isdn_subaddress | rn | cic | npdi | enum_dip_indicator | trunk_group | trunk_context; + global_number = global_number_digits par*; + local_number_digits = phonedigit_hex* ( HEXDIG | "*" | "#" ) phonedigit_hex*; + context = ";phone-context="i descriptor; + local_number = local_number_digits par* context par*; + telephone_subscriber = global_number | local_number; + password = ( unreserved | escaped | "&" | "=" | "+" | "$" | "," )*; + userinfo = ( user | telephone_subscriber ) ( ":" password )? "@"; + port = DIGIT+; + hostport = host ( ":" port )?; + other_transport = token; + transport_param = "transport="i ( "udp"i | "tcp"i | "sctp"i | "tls"i | "tls-sctp"i | other_transport ); + other_user = token; + user_param = "user="i ( "phone"i | "ip"i | "dialstring"i | other_user ); + ttl = DIGIT{1,3}; + ttl_param = "ttl="i ttl; + maddr_param = "maddr="i host; + lr_param = "lr"i; + option_tag = token; + other_compression = token; + compression_param = "comp="i ( "sigcomp"i | other_compression ); + target_param = "target"i EQUAL pvalue; + orig = "orig"i; + gr_param = "gr"i ( "=" pvalue )?; + other_param = pname ( "=" pvalue )?; + tag_param = "tag"i EQUAL token; + scheme = ALPHA ( ALPHA | DIGIT | "+" | "-" | "." )*; + + hnv_unreserved = "[" | "]" | "/" | "?" | ":" | "+" | "$"; + hname = ( hnv_unreserved | unreserved | escaped )+; + hvalue = ( hnv_unreserved | unreserved | escaped )*; + header = hname ( "=" hvalue )?; + headers = "?" header ( "&" header )*; + + Informational = "100" | "180" | "181" | "182" | "183"; + Success = "200" | "202"; + Redirection = "250" | "301" | "302" | "305" | "380"; + Client_Error = "400" | "401" | "402" | "403" | "404" | "405" | "406" | "407" | "408" | "410" | "412" | "413" | "414" | "415" | "416" | "417" | "420" | "421" | "422" | "423" | "428" | "429" | "433" | "436" | "440" | "437" | "438" | "470" | "480" | "481" | "482" | "483" | "484" | "485" | "486" | "487" | "488" | "489" | "491" | "493" | "494"; + Server_Error = "500" | "501" | "502" | "503" | "504" | "505" | "513" | "580"; + Global_Failure = "600" | "603" | "604" | "606"; + extension_code = DIGIT{3}; + delta_seconds = DIGIT+; + Status_Code = Informational | Success | Redirection | Client_Error | Server_Error | Global_Failure | extension_code; + cause_param = "cause"i EQUAL Status_Code; + + INVITEm = 0x49.0x4e.0x56.0x49.0x54.0x45; + ACKm = 0x41.0x43.0x4b; + OPTIONSm = 0x4f.0x50.0x54.0x49.0x4f.0x4e.0x53; + BYEm = 0x42.0x59.0x45; + CANCELm = 0x43.0x41.0x4e.0x43.0x45.0x4c; + REGISTERm = 0x52.0x45.0x47.0x49.0x53.0x54.0x45.0x52; + INFOm = 0x49.0x4e.0x46.0x4f; + PRACKm = 0x50.0x52.0x41.0x43.0x4b; + SUBSCRIBEm = 0x53.0x55.0x42.0x53.0x43.0x52.0x49.0x42.0x45; + NOTIFYm = 0x4e.0x4f.0x54.0x49.0x46.0x59; + UPDATEm = 0x55.0x50.0x44.0x41.0x54.0x45; + MESSAGEm = 0x4d.0x45.0x53.0x53.0x41.0x47.0x45; + REFERm = 0x52.0x45.0x46.0x45.0x52; + PUBLISHm = 0x50.0x55.0x42.0x4c.0x49.0x53.0x48; + extension_method = token; + Method = INVITEm | ACKm | OPTIONSm | BYEm | CANCELm | REGISTERm | INFOm | PRACKm | SUBSCRIBEm | NOTIFYm | UPDATEm | MESSAGEm | REFERm | PUBLISHm | extension_method; + method_param = "method="i Method; + +}%% diff --git a/tinySIP/ragel/tsip_parser_header.rl b/tinySIP/ragel/tsip_parser_header.rl new file mode 100644 index 0000000..da6d897 --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header.rl @@ -0,0 +1,863 @@ +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* DOUBANGO is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with DOUBANGO. +* +*/ + +/**@file tsip_parser_header.c + * @brief SIP headers parser. + * + * @author Mamadou Diop + * + + */ +#include "tinysip/parsers/tsip_parser_header.h" + +#include "tinysip/headers/tsip_headers.h" + +#include "tsk_debug.h" + +#undef ADD_HEADERS +#undef ADD_HEADER + +#define ADD_HEADERS(headers)\ + if(headers)\ + {\ + const tsk_list_item_t *item;\ + tsk_list_foreach(item, headers){\ + tsip_header_t *hdr = tsk_object_ref((void*)item->data);\ + tsk_list_push_back_data(message->headers, ((void**) &hdr));\ + }\ + \ + TSK_OBJECT_SAFE_FREE(headers);\ + } +#define ADD_HEADER(header)\ + if(header)\ + {\ + tsk_list_push_back_data(message->headers, ((void**) &header));\ + } + + +// Check if we have ",CRLF" ==> See WWW-Authenticate header +// As :>CRLF is preceded by any+ ==> p will be at least (start + 1) +// p point to CR +#define prev_not_comma(p) !(p && p[-1] == ',') + +/*********************************** +* Ragel state machine. +*/ +%%{ + machine tsip_machine_parser_headers; + + + # /*== Accept: ==*/ + action parse_header_Accept + { + tsip_header_Dummy_t *header = tsip_header_Dummy_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + //TSK_DEBUG_WARN("parse_header_Accept NOT IMPLEMENTED. Will be added as Dummy header."); + } + + # /*== Accept-Contact: ==*/ + action parse_header_Accept_Contact + { + tsip_header_Dummy_t *header = tsip_header_Dummy_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + //TSK_DEBUG_WARN("parse_header_Accept_Contact NOT IMPLEMENTED. Will be added as Dummy header."); + } + + # /*== Accept-Encoding: ==*/ + action parse_header_Accept_Encoding + { + tsip_header_Dummy_t *header = tsip_header_Dummy_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + //TSK_DEBUG_WARN("parse_header_Accept_Encoding NOT IMPLEMENTED. Will be added as Dummy header."); + } + + # /*== Accept-Language: ==*/ + action parse_header_Accept_Language + { + tsip_header_Dummy_t *header = tsip_header_Dummy_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + //TSK_DEBUG_WARN("parse_header_Accept_Language NOT IMPLEMENTED. Will be added as Dummy header."); + } + + # /*== Accept-Resource-Priority : ==*/ + action parse_header_Accept_Resource_Priority + { + tsip_header_Dummy_t *header = tsip_header_Dummy_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + //TSK_DEBUG_WARN("parse_header_Accept_Resource_Priority NOT IMPLEMENTED. Will be added as Dummy header."); + } + + # /*== Alert-Info: ==*/ + action parse_header_Alert_Info + { + tsip_header_Dummy_t *header = tsip_header_Dummy_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + //TSK_DEBUG_WARN("parse_header_Alert_Info NOT IMPLEMENTED. Will be added as Dummy header."); + } + + # /*== Allow: ==*/ + action parse_header_Allow + { + tsip_header_Allow_t *header = tsip_header_Allow_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + } + + # /*== Allow-Events: ==*/ + action parse_header_Allow_Events + { + tsip_header_Allow_Events_t *header = tsip_header_Allow_Events_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + } + + # /*== Authentication-Info: ==*/ + action parse_header_Authentication_Info + { + tsip_header_Dummy_t *header = tsip_header_Dummy_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + //TSK_DEBUG_WARN("parse_header_Authentication_Info NOT IMPLEMENTED. Will be added as Dummy header."); + } + + # /*== Authorization: ==*/ + action parse_header_Authorization + { + tsip_header_Authorization_t *header = tsip_header_Authorization_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + } + + # /*== Call-ID: ==*/ + action parse_header_Call_ID + { + if(!message->Call_ID){ + message->Call_ID = tsip_header_Call_ID_parse(state->tag_start, (state->tag_end-state->tag_start)); + } + else{ + tsip_header_Dummy_t *header = tsip_header_Dummy_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + TSK_DEBUG_WARN("The message already have 'Call-ID' header."); + } + } + + # /*== Call-Info: ==*/ + action parse_header_Call_Info + { + tsip_header_Dummy_t *header = tsip_header_Dummy_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + //TSK_DEBUG_WARN("parse_header_Call_Info NOT IMPLEMENTED. Will be added as Dummy header."); + } + + # /*== Contact: ==*/ + action parse_header_Contact + { + tsip_header_Contacts_L_t* headers = tsip_header_Contact_parse(state->tag_start, (state->tag_end-state->tag_start)); + if(headers) + { + tsk_list_item_t *item; + tsk_list_foreach(item, headers) + { + tsip_header_Contact_t *hdr = tsk_object_ref(item->data); + if(!message->Contact){ + message->Contact = hdr; + } + else{ + tsk_list_push_back_data(message->headers, ((void**) &hdr)); + } + } + + TSK_OBJECT_SAFE_FREE(headers); + } + } + + # /*== Content-Disposition: ==*/ + action parse_header_Content_Disposition + { + tsip_header_Dummy_t *header = tsip_header_Dummy_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + //TSK_DEBUG_WARN("parse_header_Content_Disposition NOT IMPLEMENTED. Will be added as Dummy header."); + } + + # /*== Content-Encoding: ==*/ + action parse_header_Content_Encoding + { + tsip_header_Dummy_t *header = tsip_header_Dummy_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + TSK_DEBUG_WARN("PARSE_HEADER_ACCEPT NOT IMPLEMENTED. Will be added as Dummy header."); + } + + # /*== Content-Language: ==*/ + action parse_header_Content_Language + { + tsip_header_Dummy_t *header = tsip_header_Dummy_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + //TSK_DEBUG_WARN("parse_header_Content_Language NOT IMPLEMENTED. Will be added as Dummy header."); + } + + # /*== Content-Length: ==*/ + action parse_header_Content_Length + { + if(!message->Content_Length){ + message->Content_Length = tsip_header_Content_Length_parse(state->tag_start, (state->tag_end-state->tag_start)); + } + else{ + tsip_header_Dummy_t *header = tsip_header_Dummy_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + TSK_DEBUG_WARN("The message already have 'Content-Length' header."); + } + } + + # /*== Content-Type: ==*/ + action parse_header_Content_Type + { + if(!message->Content_Type){ + message->Content_Type = tsip_header_Content_Type_parse(state->tag_start, (state->tag_end-state->tag_start)); + } + else{ + tsip_header_Dummy_t *header = tsip_header_Dummy_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + TSK_DEBUG_WARN("The message already have 'Content-Type' header."); + } + } + + # /*== CSeq: ==*/ + action parse_header_CSeq + { + if(!message->CSeq){ + message->CSeq = tsip_header_CSeq_parse(state->tag_start, (state->tag_end-state->tag_start)); + } + else{ + tsip_header_Dummy_t *header = tsip_header_Dummy_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + TSK_DEBUG_WARN("The message already have 'CSeq' header."); + } + } + + # /*== Date: ==*/ + action parse_header_Date + { + tsip_header_Date_t *header = tsip_header_Date_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + } + + # /*== Error-Info: ==*/ + action parse_header_Error_Info + { + tsip_header_Dummy_t *header = tsip_header_Dummy_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + //TSK_DEBUG_WARN("parse_header_Error_Info NOT IMPLEMENTED. Will be added as Dummy header."); + } + + # /*== Event: ==*/ + action parse_header_Event + { + tsip_header_Event_t *header = tsip_header_Event_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + } + + # /*== Expires: ==*/ + action parse_header_Expires + { + if(!message->Expires){ + message->Expires = tsip_header_Expires_parse(state->tag_start, (state->tag_end-state->tag_start)); + } + else{ + tsip_header_Dummy_t *header = tsip_header_Dummy_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + TSK_DEBUG_WARN("The message already have 'Expires' header."); + } + } + + # /*== From: ==*/ + action parse_header_From + { + if(!message->From){ + message->From = tsip_header_From_parse(state->tag_start, (state->tag_end-state->tag_start)); + } + else{ + tsip_header_Dummy_t *header = tsip_header_Dummy_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + TSK_DEBUG_WARN("The message already have 'From' header."); + } + } + + # /*== History-Info: ==*/ + action parse_header_History_Info + { + tsip_header_Dummy_t *header = tsip_header_Dummy_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + //TSK_DEBUG_WARN("parse_header_History_Info NOT IMPLEMENTED. Will be added as Dummy header."); + } + + # /*== Identity: ==*/ + action parse_header_Identity + { + tsip_header_Dummy_t *header = tsip_header_Dummy_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + //TSK_DEBUG_WARN("parse_header_Identity NOT IMPLEMENTED. Will be added as Dummy header."); + } + + # /*== Identity-Info: ==*/ + action parse_header_Identity_Info + { + tsip_header_Dummy_t *header = tsip_header_Dummy_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + //TSK_DEBUG_WARN("parse_header_Identity_Info NOT IMPLEMENTED. Will be added as Dummy header."); + } + + # /*== In_Reply-To: ==*/ + action parse_header_In_Reply_To + { + tsip_header_Dummy_t *header = tsip_header_Dummy_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + //TSK_DEBUG_WARN("parse_header_In_Reply_To NOT IMPLEMENTED. Will be added as Dummy header."); + } + + # /*== Join: ==*/ + action parse_header_Join + { + tsip_header_Dummy_t *header = tsip_header_Dummy_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + //TSK_DEBUG_WARN("parse_header_Join NOT IMPLEMENTED. Will be added as Dummy header."); + } + + # /*== Max-Forwards: ==*/ + action parse_header_Max_Forwards + { + tsip_header_Max_Forwards_t *header = tsip_header_Max_Forwards_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + } + + # /*== MIME-Version: ==*/ + action parse_header_MIME_Version + { + tsip_header_Dummy_t *header = tsip_header_Dummy_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + //TSK_DEBUG_WARN("parse_header_MIME_Version NOT IMPLEMENTED. Will be added as Dummy header."); + } + + # /*== Min-Expires: ==*/ + action parse_header_Min_Expires + { + tsip_header_Min_Expires_t *header = tsip_header_Min_Expires_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + } + + # /*== Min-SE: ==*/ + action parse_header_Min_SE + { + tsip_header_Min_SE_t *header = tsip_header_Min_SE_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + } + + # /*== Organization: ==*/ + action parse_header_Organization + { + tsip_header_Dummy_t *header = tsip_header_Dummy_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + //TSK_DEBUG_WARN("parse_header_Organization NOT IMPLEMENTED. Will be added as Dummy header."); + } + + # /*== P-Access-Network-Info: ==*/ + action parse_header_P_Access_Network_Info + { + tsip_header_P_Access_Network_Info_t *header = tsip_header_P_Access_Network_Info_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + } + + # /*== P-Answer-State: ==*/ + action parse_header_P_Answer_State + { + tsip_header_Dummy_t *header = tsip_header_Dummy_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + //TSK_DEBUG_WARN("parse_header_P_Answer_State NOT IMPLEMENTED. Will be added as Dummy header."); + } + + # /*== P-Asserted-Identity: ==*/ + action parse_header_P_Asserted_Identity + { + tsip_header_P_Asserted_Identities_L_t* headers = tsip_header_P_Asserted_Identity_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADERS(headers); + } + + # /*== P-Associated-URI: ==*/ + action parse_header_P_Associated_URI + { + tsip_header_P_Associated_URIs_L_t* headers = tsip_header_P_Associated_URI_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADERS(headers); + } + + # /*== P-Called-Party-ID: ==*/ + action parse_header_P_Called_Party_ID + { + tsip_header_Dummy_t *header = tsip_header_Dummy_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + //TSK_DEBUG_WARN("parse_header_P_Called_Party_ID NOT IMPLEMENTED. Will be added as Dummy header."); + } + + # /*== P-Charging-Function-Addresses : ==*/ + action parse_header_P_Charging_Function_Addresses + { + tsip_header_P_Charging_Function_Addressess_L_t* headers = tsip_header_P_Charging_Function_Addresses_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADERS(headers); + } + + # /*== P_Charging_Vector: ==*/ + action parse_header_P_Charging_Vector + { + tsip_header_Dummy_t *header = tsip_header_Dummy_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + //TSK_DEBUG_WARN("parse_header_P_Charging_Vector NOT IMPLEMENTED. Will be added as Dummy header."); + } + + # /*== P-DCS-Billing-Info: ==*/ + action parse_header_P_DCS_Billing_Info + { + tsip_header_Dummy_t *header = tsip_header_Dummy_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + //TSK_DEBUG_WARN("parse_header_P_DCS_Billing_Info NOT IMPLEMENTED. Will be added as Dummy header."); + } + + # /*== P-DCS-LAES: ==*/ + action parse_header_P_DCS_LAES + { + tsip_header_Dummy_t *header = tsip_header_Dummy_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + //TSK_DEBUG_WARN("parse_header_P_DCS_LAES NOT IMPLEMENTED. Will be added as Dummy header."); + } + + # /*== P-DCS-OSPS: ==*/ + action parse_header_P_DCS_OSPS + { + tsip_header_Dummy_t *header = tsip_header_Dummy_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + //TSK_DEBUG_WARN("parse_header_P_DCS_OSPS NOT IMPLEMENTED. Will be added as Dummy header."); + } + + # /*== P-DCS-Redirect: ==*/ + action parse_header_P_DCS_Redirect + { + tsip_header_Dummy_t *header = tsip_header_Dummy_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + //TSK_DEBUG_WARN("parse_header_P_DCS_Redirect NOT IMPLEMENTED. Will be added as Dummy header."); + } + + # /*== P-DCS-Trace-Party-ID: ==*/ + action parse_header_P_DCS_Trace_Party_ID + { + tsip_header_Dummy_t *header = tsip_header_Dummy_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + //TSK_DEBUG_WARN("parse_header_P_DCS_Trace_Party_ID NOT IMPLEMENTED. Will be added as Dummy header."); + } + + # /*== P-Early-Media: ==*/ + action parse_header_P_Early_Media + { + tsip_header_Dummy_t *header = tsip_header_Dummy_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + //TSK_DEBUG_WARN("parse_header_P_Early_Media NOT IMPLEMENTED. Will be added as Dummy header."); + } + + # /*== P-Media-Authorization: ==*/ + action parse_header_P_Media_Authorization + { + tsip_header_Dummy_t *header = tsip_header_Dummy_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + //TSK_DEBUG_WARN("parse_header_P_Media_Authorization NOT IMPLEMENTED. Will be added as Dummy header."); + } + + # /*== P-Preferred-Identity: ==*/ + action parse_header_P_Preferred_Identity + { + tsip_header_P_Preferred_Identity_t *header = tsip_header_P_Preferred_Identity_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + } + + # /*== P-Profile-Key: ==*/ + action parse_header_P_Profile_Key + { + tsip_header_Dummy_t *header = tsip_header_Dummy_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + //TSK_DEBUG_WARN("parse_header_P_Profile_Key NOT IMPLEMENTED. Will be added as Dummy header."); + } + + # /*== P-User-Database: ==*/ + action parse_header_P_User_Database + { + tsip_header_Dummy_t *header = tsip_header_Dummy_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + //TSK_DEBUG_WARN("parse_header_P_User_Database NOT IMPLEMENTED. Will be added as Dummy header."); + } + + # /*== P-Visited-Network-ID: ==*/ + action parse_header_P_Visited_Network_ID + { + tsip_header_Dummy_t *header = tsip_header_Dummy_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + //TSK_DEBUG_WARN("parse_header_P_Visited_Network_ID NOT IMPLEMENTED. Will be added as Dummy header."); + } + + # /*== Path: ==*/ + action parse_header_Path + { + tsip_header_Paths_L_t* headers = tsip_header_Path_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADERS(headers); + } + + # /* == Priority: ==*/ + action parse_header_Priority + { + tsip_header_Dummy_t *header = tsip_header_Dummy_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + //TSK_DEBUG_WARN("parse_header_Priority NOT IMPLEMENTED. Will be added as Dummy header."); + } + + # /*== Privacy: ==*/ + action parse_header_Privacy + { + tsip_header_Privacy_t *header = tsip_header_Privacy_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + } + + # /*== Authenticate: ==*/ + action parse_header_Proxy_Authenticate + { + tsip_header_Proxy_Authenticate_t *header = tsip_header_Proxy_Authenticate_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + } + + # /*== Proxy-Authorization: ==*/ + action parse_header_Proxy_Authorization + { + tsip_header_Proxy_Authorization_t *header = tsip_header_Proxy_Authorization_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + } + + # /*== Proxy-Require: ==*/ + action parse_header_Proxy_Require + { + tsip_header_Proxy_Require_t *header = tsip_header_Proxy_Require_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + } + + # /*== RAck: ==*/ + action parse_header_RAck + { + tsip_header_RAck_t *header = tsip_header_RAck_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + } + + # /*== Reason: ==*/ + action parse_header_Reason + { + tsip_header_Dummy_t *header = tsip_header_Dummy_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + //TSK_DEBUG_WARN("parse_header_Reason NOT IMPLEMENTED. Will be added as Dummy header."); + } + + # /*== Record-Route: ==*/ + action parse_header_Record_Route + { + tsip_header_Record_Routes_L_t* headers = tsip_header_Record_Route_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADERS(headers); + } + + # /*== Refer-Sub: ==*/ + action parse_header_Refer_Sub + { + tsip_header_Refer_Sub_t *header = tsip_header_Refer_Sub_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + } + + # /*== Refer-To: ==*/ + action parse_header_Refer_To + { + tsip_header_Refer_To_t *header = tsip_header_Refer_To_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + } + + # /*== Referred-By: ==*/ + action parse_header_Referred_By + { + tsip_header_Referred_By_t *header = tsip_header_Referred_By_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + } + + # /*== Reject-Contact: ==*/ + action parse_header_Reject_Contact + { + tsip_header_Dummy_t *header = tsip_header_Dummy_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + //TSK_DEBUG_WARN("parse_header_Reject_Contact NOT IMPLEMENTED. Will be added as Dummy header."); + } + + # /*== Replaces: ==*/ + action parse_header_Replaces + { + tsip_header_Dummy_t *header = tsip_header_Dummy_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + //TSK_DEBUG_WARN("parse_header_Replaces NOT IMPLEMENTED. Will be added as Dummy header."); + } + + # /*== Reply-To: ==*/ + action parse_header_Reply_To + { + tsip_header_Dummy_t *header = tsip_header_Dummy_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + //TSK_DEBUG_WARN("parse_header_Reply_To NOT IMPLEMENTED. Will be added as Dummy header."); + } + + # /*== Request-Disposition: ==*/ + action parse_header_Request_Disposition + { + tsip_header_Dummy_t *header = tsip_header_Dummy_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + //TSK_DEBUG_WARN("parse_header_Request_Disposition NOT IMPLEMENTED. Will be added as Dummy header."); + } + + # /*== Require: ==*/ + action parse_header_Require + { + tsip_header_Require_t *header = tsip_header_Require_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + } + + # /*== Resource-Priority: ==*/ + action parse_header_Resource_Priority + { + tsip_header_Dummy_t *header = tsip_header_Dummy_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + //TSK_DEBUG_WARN("parse_header_Resource_Priority NOT IMPLEMENTED. Will be added as Dummy header."); + } + + # /*== Retry-After: ==*/ + action parse_header_Retry_After + { + tsip_header_Dummy_t *header = tsip_header_Dummy_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + //TSK_DEBUG_WARN("parse_header_Retry_After NOT IMPLEMENTED. Will be added as Dummy header."); + } + + # /*== Route: ==*/ + action parse_header_Route + { + tsip_header_Routes_L_t* headers = tsip_header_Route_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADERS(headers); + } + + # /*== RSeq: ==*/ + action parse_header_RSeq + { + tsip_header_RSeq_t *header = tsip_header_RSeq_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + } + + # /*== Security_Client: ==*/ + action parse_header_Security_Client + { + tsip_header_Security_Clients_L_t* headers = tsip_header_Security_Client_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADERS(headers); + } + + # /*== Security-Server: ==*/ + action parse_header_Security_Server + { + tsip_header_Security_Servers_L_t* headers = tsip_header_Security_Server_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADERS(headers); + } + + # /*== Security-Verify: ==*/ + action parse_header_Security_Verify + { + tsip_header_Security_Verifies_L_t* headers = tsip_header_Security_Verify_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADERS(headers); + } + + # /*== Server: ==*/ + action parse_header_Server + { + tsip_header_Server_t *header = tsip_header_Server_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + } + + # /*== Service-Route: ==*/ + action parse_header_Service_Route + { + tsip_header_Service_Routes_L_t* headers = tsip_header_Service_Route_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADERS(headers); + } + + # /*== Session-Expires: ==*/ + action parse_header_Session_Expires + { + tsip_header_Session_Expires_t *header = tsip_header_Session_Expires_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + } + + # /*== SIP-ETag: ==*/ + action parse_header_SIP_ETag + { + tsip_header_SIP_ETag_t *header = tsip_header_SIP_ETag_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + } + + # /*== SIP-If-Match: ==*/ + action parse_header_SIP_If_Match + { + tsip_header_SIP_If_Match_t *header = tsip_header_SIP_If_Match_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + } + + # /*== Subject: ==*/ + action parse_header_Subject + { + tsip_header_Dummy_t *header = tsip_header_Dummy_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + //TSK_DEBUG_WARN("parse_header_Subject NOT IMPLEMENTED. Will be added as Dummy header."); + } + + # /*== Subscription-State: ==*/ + action parse_header_Subscription_State + { + tsip_header_Subscription_State_t* header = tsip_header_Subscription_State_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + } + + # /*== Supported: ==*/ + action parse_header_Supported + { + tsip_header_Supported_t *header = tsip_header_Supported_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + } + + # /*== Target-Dialog: ==*/ + action parse_header_Target_Dialog + { + tsip_header_Dummy_t *header = tsip_header_Dummy_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + //TSK_DEBUG_WARN("parse_header_Target_Dialog NOT IMPLEMENTED. Will be added as Dummy header."); + } + + # /*== Timestamp: ==*/ + action parse_header_Timestamp + { + tsip_header_Dummy_t *header = tsip_header_Dummy_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + //TSK_DEBUG_WARN("parse_header_Timestamp NOT IMPLEMENTED. Will be added as Dummy header."); + } + + # /*== To: ==*/ + action parse_header_To + { + if(!message->To){ + message->To = tsip_header_To_parse(state->tag_start, (state->tag_end-state->tag_start)); + } + else{ + tsip_header_Dummy_t *header = tsip_header_Dummy_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + TSK_DEBUG_WARN("The message already have 'To' header."); + } + } + + # /*== Unsupported: ==*/ + action parse_header_Unsupported + { + tsip_header_Dummy_t *header = tsip_header_Dummy_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + //TSK_DEBUG_WARN("parse_header_Unsupported NOT IMPLEMENTED. Will be added as Dummy header."); + } + + # /*== User-Agent: ==*/ + action parse_header_User_Agent + { + tsip_header_User_Agent_t *header = tsip_header_User_Agent_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + } + + # /*== Via: ==*/ + action parse_header_Via + { + tsip_header_Vias_L_t* headers = tsip_header_Via_parse(state->tag_start, (state->tag_end-state->tag_start)); + if(headers){ + tsk_list_item_t *item; + tsk_list_foreach(item, headers){ + tsip_header_Via_t *hdr = tsk_object_ref(item->data); + if(!message->firstVia){ + message->firstVia = hdr; + } + else{ + tsk_list_push_back_data(message->headers, ((void**) &hdr)); + } + } + + TSK_OBJECT_SAFE_FREE(headers); + } + } + + # /*== Warning: ==*/ + action parse_header_Warning + { + tsip_header_Warnings_L_t* headers = tsip_header_Warning_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADERS(headers); + } + + # /*== WWW-Authenticate: ==*/ + action parse_header_WWW_Authenticate + { + tsip_header_WWW_Authenticate_t *header = tsip_header_WWW_Authenticate_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + } + + # /*== extension_header: ==*/ + action parse_header_extension_header + { + tsip_header_Dummy_t *header = tsip_header_Dummy_parse(state->tag_start, (state->tag_end-state->tag_start)); + ADD_HEADER(header); + } + + action prev_not_comma{ + prev_not_comma(p) + } + + # Includes + include tsip_machine_utils "./ragel/tsip_machine_utils.rl"; + include tsip_machine_header "./ragel/tsip_machine_header.rl"; + + # Entry point + main := HEADER; +}%% + +tsk_bool_t tsip_header_parse(tsk_ragel_state_t *state, tsip_message_t *message) +{ + int cs = 0; + const char *p = state->tag_start; + const char *pe = state->tag_end; + const char *eof = pe; + + %%write data; + (void)(eof); + (void)(tsip_machine_parser_headers_first_final); + (void)(tsip_machine_parser_headers_error); + (void)(tsip_machine_parser_headers_en_main); + %%write init; + %%write exec; + + return ( cs >= %%{ write first_final; }%% ); + //return (cs == tsip_machine_parser_headers_first_final); +} diff --git a/tinySIP/ragel/tsip_parser_header_Accept_Contact.rl b/tinySIP/ragel/tsip_parser_header_Accept_Contact.rl new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_Accept_Contact.rl @@ -0,0 +1 @@ + diff --git a/tinySIP/ragel/tsip_parser_header_Accept_Encoding.rl b/tinySIP/ragel/tsip_parser_header_Accept_Encoding.rl new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_Accept_Encoding.rl @@ -0,0 +1 @@ + diff --git a/tinySIP/ragel/tsip_parser_header_Accept_Language.rl b/tinySIP/ragel/tsip_parser_header_Accept_Language.rl new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_Accept_Language.rl @@ -0,0 +1 @@ + diff --git a/tinySIP/ragel/tsip_parser_header_Accept_Resource_Priority.rl b/tinySIP/ragel/tsip_parser_header_Accept_Resource_Priority.rl new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_Accept_Resource_Priority.rl @@ -0,0 +1 @@ + diff --git a/tinySIP/ragel/tsip_parser_header_Alert_Info.rl b/tinySIP/ragel/tsip_parser_header_Alert_Info.rl new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_Alert_Info.rl @@ -0,0 +1 @@ + diff --git a/tinySIP/ragel/tsip_parser_header_Allow.rl b/tinySIP/ragel/tsip_parser_header_Allow.rl new file mode 100644 index 0000000..c68239a --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_Allow.rl @@ -0,0 +1,190 @@ +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* DOUBANGO is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with DOUBANGO. +* +*/ + +/**@file tsip_header_Allow.c + * @brief SIP Allow header. + * + * @author Mamadou Diop + * + + */ +#include "tinysip/headers/tsip_header_Allow.h" + +#include "tinysip/parsers/tsip_parser_uri.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" +#include + +/*********************************** +* Ragel state machine. +*/ +%%{ + machine tsip_machine_parser_header_Allow; + + # Includes + include tsip_machine_utils "./ragel/tsip_machine_utils.rl"; + + action tag + { + tag_start = p; + } + + action parse_method + { + TSK_PARSER_ADD_STRING(hdr_allow->methods); + } + + action eob + { + } + + Allow = "Allow"i HCOLON ( Method>tag %parse_method ( COMMA Method>tag %parse_method )* )?; + + # Entry point + main := Allow :>CRLF @eob; + +}%% + + +tsip_header_Allow_t* tsip_header_Allow_create() +{ + return tsk_object_new(tsip_header_Allow_def_t); +} + +int tsip_header_Allow_serialize(const tsip_header_t* header, tsk_buffer_t* output) +{ + if(header){ + const tsip_header_Allow_t *Allow = (const tsip_header_Allow_t *)header; + tsk_list_item_t *item; + tsk_string_t *str; + int ret = 0; + + tsk_list_foreach(item, Allow->methods){ + str = item->data; + if(item == Allow->methods->head){ + tsk_buffer_append(output, str->value, tsk_strlen(str->value)); + } + else{ + tsk_buffer_append_2(output, ",%s", str->value); + } + } + + return ret; + } + + return -1; +} + +tsip_header_Allow_t *tsip_header_Allow_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsip_header_Allow_t *hdr_allow = tsip_header_Allow_create(); + + const char *tag_start = tsk_null; + + %%write data; + (void)(eof); + (void)(void)(tsip_machine_parser_header_Allow_first_final); + (void)(void)(tsip_machine_parser_header_Allow_error); + (void)(void)(tsip_machine_parser_header_Allow_en_main); + %%write init; + %%write exec; + + if( cs < %%{ write first_final; }%% ){ + TSK_DEBUG_ERROR("Failed to parse SIP 'Allow' header."); + TSK_OBJECT_SAFE_FREE(hdr_allow); + } + + return hdr_allow; +} + +tsk_bool_t tsip_header_Allow_allows(const tsip_header_Allow_t* self, const char* method) +{ + const tsk_list_item_t* item; + const tsk_string_t* string; + + if(!self || !method){ + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + + tsk_list_foreach(item, self->methods){ + if(!(string = item->data)){ + continue; + } + if(tsk_striequals(string->value, method)){ + return tsk_true; + } + } + return tsk_false; +} + + + + + +//======================================================== +// Allow header object definition +// + +static tsk_object_t* tsip_header_Allow_ctor(tsk_object_t *self, va_list * app) +{ + tsip_header_Allow_t *Allow = self; + if(Allow){ + /*const char* methods = va_arg(*app, const char *); + if(methods && !tsk_strempty(methods)) + { + Allow->methods = tsip_header_Allow_parse(methods, tsk_strlen(methods)); + }*/ + TSIP_HEADER(Allow)->type = tsip_htype_Allow; + TSIP_HEADER(Allow)->serialize = tsip_header_Allow_serialize; + } + else{ + TSK_DEBUG_ERROR("Failed to create new Allow header."); + } + return self; +} + +static tsk_object_t* tsip_header_Allow_dtor(tsk_object_t *self) +{ + tsip_header_Allow_t *Allow = self; + if(Allow){ + TSK_OBJECT_SAFE_FREE(Allow->methods); + TSK_OBJECT_SAFE_FREE(TSIP_HEADER_PARAMS(Allow)); + } + else TSK_DEBUG_ERROR("Null Allow header."); + + return self; +} + +static const tsk_object_def_t tsip_header_Allow_def_s = +{ + sizeof(tsip_header_Allow_t), + tsip_header_Allow_ctor, + tsip_header_Allow_dtor, + tsk_null +}; +const tsk_object_def_t *tsip_header_Allow_def_t = &tsip_header_Allow_def_s; diff --git a/tinySIP/ragel/tsip_parser_header_Allow_Events.rl b/tinySIP/ragel/tsip_parser_header_Allow_Events.rl new file mode 100644 index 0000000..72dbab0 --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_Allow_Events.rl @@ -0,0 +1,170 @@ +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* DOUBANGO is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with DOUBANGO. +* +*/ + +/**@file tsip_header_Allow_events.c + * @brief SIP Allow-Events/u header. + * + * @author Mamadou Diop + * + + */ +#include "tinysip/headers/tsip_header_Allow_Events.h" + +#include "tinysip/parsers/tsip_parser_uri.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" + +#include + + +/*********************************** +* Ragel state machine. +*/ +%%{ + machine tsip_machine_parser_header_Allow_events; + + # Includes + include tsip_machine_utils "./ragel/tsip_machine_utils.rl"; + + action tag{ + tag_start = p; + } + + action parse_event{ + TSK_PARSER_ADD_STRING(hdr_allow_events->events); + } + + action eob{ + } + + event_package = token_nodot; + event_template = token_nodot; + event_type = event_package ( "." event_template )*; + + Allow_Events = ( "Allow-Events"i | "u"i ) HCOLON event_type>tag %parse_event ( COMMA event_type>tag %parse_event )*; + + # Entry point + main := Allow_Events :>CRLF @eob; + +}%% + +tsip_header_Allow_Events_t* tsip_header_Allow_Events_create() +{ + return tsk_object_new(tsip_header_Allow_Events_def_t); +} + +int tsip_header_Allow_Events_serialize(const tsip_header_t* header, tsk_buffer_t* output) +{ + if(header){ + const tsip_header_Allow_Events_t *Allow_Events = (const tsip_header_Allow_Events_t *)header; + tsk_list_item_t *item; + tsk_string_t *str; + int ret = 0; + + tsk_list_foreach(item, Allow_Events->events){ + str = item->data; + if(item == Allow_Events->events->head){ + tsk_buffer_append(output, str->value, tsk_strlen(str->value)); + } + else{ + tsk_buffer_append_2(output, ",%s", str->value); + } + } + + return ret; + } + + return -1; +} + +tsip_header_Allow_Events_t *tsip_header_Allow_Events_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsip_header_Allow_Events_t *hdr_allow_events = tsip_header_Allow_Events_create(); + + const char *tag_start = tsk_null; + + %%write data; + (void)(eof); + (void)(tsip_machine_parser_header_Allow_events_first_final); + (void)(tsip_machine_parser_header_Allow_events_error); + (void)(tsip_machine_parser_header_Allow_events_en_main); + %%write init; + %%write exec; + + if( cs < %%{ write first_final; }%% ){ + TSK_DEBUG_ERROR("Failed to parse SIP 'Allow-Events' header."); + TSK_OBJECT_SAFE_FREE(hdr_allow_events); + } + + return hdr_allow_events; +} + + + + + + + +//======================================================== +// Allow_events header object definition +// + +static tsk_object_t* tsip_header_Allow_Events_ctor(tsk_object_t *self, va_list * app) +{ + tsip_header_Allow_Events_t *Allow_events = self; + if(Allow_events){ + TSIP_HEADER(Allow_events)->type = tsip_htype_Allow_Events; + TSIP_HEADER(Allow_events)->serialize = tsip_header_Allow_Events_serialize; + } + else{ + TSK_DEBUG_ERROR("Failed to create new Allow-Events header."); + } + return self; +} + +static tsk_object_t* tsip_header_Allow_Events_dtor(tsk_object_t *self) +{ + tsip_header_Allow_Events_t *Allow_events = self; + if(Allow_events){ + TSK_OBJECT_SAFE_FREE(Allow_events->events); + TSK_OBJECT_SAFE_FREE(TSIP_HEADER_PARAMS(Allow_events)); + } + else{ + TSK_DEBUG_ERROR("Null Allow-Events header."); + } + + return self; +} + +static const tsk_object_def_t tsip_header_Allow_Events_def_s = +{ + sizeof(tsip_header_Allow_Events_t), + tsip_header_Allow_Events_ctor, + tsip_header_Allow_Events_dtor, + tsk_null +}; +const tsk_object_def_t *tsip_header_Allow_Events_def_t = &tsip_header_Allow_Events_def_s; diff --git a/tinySIP/ragel/tsip_parser_header_Authentication_Info.rl b/tinySIP/ragel/tsip_parser_header_Authentication_Info.rl new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_Authentication_Info.rl @@ -0,0 +1 @@ + diff --git a/tinySIP/ragel/tsip_parser_header_Authorization.rl b/tinySIP/ragel/tsip_parser_header_Authorization.rl new file mode 100644 index 0000000..ef6b223 --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_Authorization.rl @@ -0,0 +1,285 @@ +///* +//* Copyright (C) 2010-2011 Mamadou Diop. +//* +//* Contact: Mamadou Diop +//* +//* This file is part of Open Source Doubango Framework. +//* +//* DOUBANGO is free software: you can redistribute it and/or modify +//* it under the terms of the GNU General Public License as published by +//* the Free Software Foundation, either version 3 of the License, or +//* (at your option) any later version. +//* +//* DOUBANGO is distributed in the hope that it will be useful, +//* but WITHOUT ANY WARRANTY; without even the implied warranty of +//* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +//* GNU General Public License for more details. +//* +//* You should have received a copy of the GNU General Public License +//* along with DOUBANGO. +//* +//*/ +// +///**@file tsip_header_Authorization.c +// * @brief SIP Authorization header. +// * +// * @author Mamadou Diop +// * +// +// */ +//#include "tinysip/headers/tsip_header_Authorization.h" +// +//#include "tinysip/parsers/tsip_parser_uri.h" +// +//#include "tsk_debug.h" +//#include "tsk_memory.h" +//#include "tsk_time.h" +// +//#include +// + +// +///*********************************** +//* Ragel state machine. +//*/ +//%%{ +// machine tsip_machine_parser_header_Authorization; +// +// # Includes +// include tsip_machine_utils "./ragel/tsip_machine_utils.rl"; +// +// action tag +// { +// tag_start = p; +// } +// +// action is_digest +// { +// #//FIXME: Only Digest is supported +// hdr_Authorization->scheme = tsk_strdup("Digest"); +// } +// +// action parse_username +// { +// TSK_PARSER_SET_STRING(hdr_Authorization->username); +// tsk_strunquote(&hdr_Authorization->username); +// } +// +// action parse_realm +// { +// TSK_PARSER_SET_STRING(hdr_Authorization->realm); +// tsk_strunquote(&hdr_Authorization->realm); +// } +// +// action parse_nonce +// { +// TSK_PARSER_SET_STRING(hdr_Authorization->nonce); +// tsk_strunquote(&hdr_Authorization->nonce); +// } +// +// action parse_uri +// { +// TSK_PARSER_SET_STRING(hdr_Authorization->line.request.uri); +// } +// +// action parse_response +// { +// TSK_PARSER_SET_STRING(hdr_Authorization->response); +// tsk_strunquote(&hdr_Authorization->response); +// } +// +// action parse_algorithm +// { +// TSK_PARSER_SET_STRING(hdr_Authorization->algorithm); +// } +// +// action parse_cnonce +// { +// TSK_PARSER_SET_STRING(hdr_Authorization->cnonce); +// tsk_strunquote(&hdr_Authorization->cnonce); +// } +// +// action parse_opaque +// { +// TSK_PARSER_SET_STRING(hdr_Authorization->opaque); +// tsk_strunquote(&hdr_Authorization->opaque); +// } +// +// action parse_qop +// { +// TSK_PARSER_SET_STRING(hdr_Authorization->qop); +// //tsk_strunquote(&hdr_Authorization->qop); +// } +// +// action parse_nc +// { +// TSK_PARSER_SET_STRING(hdr_Authorization->nc); +// } +// +// action parse_param +// { +// TSK_PARSER_ADD_PARAM(TSIP_HEADER_PARAMS(hdr_Authorization)); +// } +// +// action eob +// { +// } +// +// #FIXME: Only Digest (MD5, AKAv1-MD5 and AKAv2-MD5) is supported +// qop_value = "auth" | "auth-int" | token; +// other_response = (any+); +// auth_param = generic_param>tag %parse_param; +// +// username = "username"i EQUAL quoted_string>tag %parse_username; +// realm = "realm"i EQUAL quoted_string>tag %parse_realm; +// nonce = "nonce"i EQUAL quoted_string>tag %parse_nonce; +// digest_uri = "uri"i EQUAL LDQUOT <: (any*)>tag %parse_uri :> RDQUOT; +// #dresponse = "response"i EQUAL LDQUOT <: (LHEX{32})>tag %parse_response :> RDQUOT; +// dresponse = "response"i EQUAL quoted_string>tag %parse_response; +// algorithm = "algorithm"i EQUAL <:token>tag %parse_algorithm; +// cnonce = "cnonce"i EQUAL quoted_string>tag %parse_cnonce; +// opaque = "opaque"i EQUAL quoted_string>tag %parse_opaque; +// message_qop = "qop"i EQUAL qop_value>tag %parse_qop; +// nonce_count = "nc"i EQUAL (LHEX{8})>tag %parse_nc; +// +// dig_resp = (username | realm | nonce | digest_uri | dresponse | algorithm | cnonce | opaque | message_qop | nonce_count)@1 | auth_param@0; +// digest_response = dig_resp ( COMMA <:dig_resp )*; +// credentials = ( "Digest"i LWS digest_response )>is_digest | other_response; +// Authorization = "Authorization"i HCOLON credentials; +// +// # Entry point +// main := Authorization :>CRLF @eob; +// +//}%% +// +//int tsip_header_Authorization_serialize(const tsip_header_t* header, tsk_buffer_t* output) +//{ +// if(header) +// { +// const tsip_header_Authorization_t *Authorization = header; +// if(Authorization && Authorization->scheme) +// { +// return tsk_buffer_append_2(output, "%s %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", +// Authorization->scheme, +// +// Authorization->username ? "username=\"" : "", +// Authorization->username ? Authorization->username : "", +// Authorization->username ? "\"" : "", +// +// Authorization->realm ? ",realm=\"" : "", +// Authorization->realm ? Authorization->realm : "", +// Authorization->realm ? "\"" : "", +// +// Authorization->nonce ? ",nonce=\"" : "", +// Authorization->nonce ? Authorization->nonce : "", +// Authorization->nonce ? "\"" : "", +// +// Authorization->line.request.uri ? ",uri=\"" : "", +// Authorization->line.request.uri ? Authorization->line.request.uri : "", +// Authorization->line.request.uri ? "\"" : "", +// +// Authorization->response ? ",response=\"" : "", +// Authorization->response ? Authorization->response : "", +// Authorization->response ? "\"" : "", +// +// Authorization->algorithm ? ",algorithm=" : "", +// Authorization->algorithm ? Authorization->algorithm : "", +// +// Authorization->cnonce ? ",cnonce=\"" : "", +// Authorization->cnonce ? Authorization->cnonce : "", +// Authorization->cnonce ? "\"" : "", +// +// Authorization->opaque ? ",opaque=\"" : "", +// Authorization->opaque ? Authorization->opaque : "", +// Authorization->opaque ? "\"" : "", +// +// Authorization->qop ? ",qop=" : "", +// Authorization->qop ? Authorization->qop : "", +// +// Authorization->nc ? ",nc=" : "", +// Authorization->nc ? Authorization->nc : "" +// ); +// } +// } +// return -1; +//} +// +//tsip_header_Authorization_t *tsip_header_Authorization_parse(const char *data, tsk_size_t size) +//{ +// int cs = 0; +// const char *p = data; +// const char *pe = p + size; +// const char *eof = pe; +// tsip_header_Authorization_t *hdr_Authorization = tsip_header_Authorization_create(); +// +// const char *tag_start = tsk_null; +// +// %%write data; +// %%write init; +// %%write exec; +// +// if( cs < %%{ write first_final; }%% ) +// { +// TSK_OBJECT_SAFE_FREE(hdr_Authorization); +// } +// +// return hdr_Authorization; +//} +// +// +// +// +// +// +// +////======================================================== +//// Authorization header object definition +//// +// +//static tsk_object_t* tsip_header_Authorization_ctor(tsk_object_t *self, va_list * app) +//{ +// tsip_header_Authorization_t *Authorization = self; +// if(Authorization) +// { +// TSIP_HEADER(Authorization)->type = tsip_htype_Authorization; +// TSIP_HEADER(Authorization)->serialize = tsip_header_Authorization_serialize; +// } +// else +// { +// TSK_DEBUG_ERROR("Failed to create new Authorization header."); +// } +// return self; +//} +// +//static tsk_object_t* tsip_header_Authorization_dtor(tsk_object_t *self) +//{ +// tsip_header_Authorization_t *Authorization = self; +// if(Authorization) +// { +// TSK_FREE(Authorization->scheme); +// TSK_FREE(Authorization->username); +// TSK_FREE(Authorization->realm); +// TSK_FREE(Authorization->nonce); +// TSK_FREE(Authorization->line.request.uri); +// TSK_FREE(Authorization->response); +// TSK_FREE(Authorization->algorithm); +// TSK_FREE(Authorization->cnonce); +// TSK_FREE(Authorization->opaque); +// TSK_FREE(Authorization->qop); +// TSK_FREE(Authorization->nc); +// +// TSK_OBJECT_SAFE_FREE(TSIP_HEADER_PARAMS(Authorization)); +// } +// else TSK_DEBUG_ERROR("Null Authorization header."); +// +// return self; +//} +// +//static const tsk_object_def_t tsip_header_Authorization_def_s = +//{ +// sizeof(tsip_header_Authorization_t), +// tsip_header_Authorization_ctor, +// tsip_header_Authorization_dtor, +// 0 +//}; +//const void *tsip_header_Authorization_def_t = &tsip_header_Authorization_def_s; diff --git a/tinySIP/ragel/tsip_parser_header_CSeq.rl b/tinySIP/ragel/tsip_parser_header_CSeq.rl new file mode 100644 index 0000000..8457d5a --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_CSeq.rl @@ -0,0 +1,168 @@ +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* DOUBANGO is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with DOUBANGO. +* +*/ + +/**@file tsip_header_CSeq.c + * @brief SIP CSeq header. + * + * @author Mamadou Diop + * + + */ +#include "tinysip/headers/tsip_header_CSeq.h" + +#include "tinysip/parsers/tsip_parser_uri.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" + +extern tsip_request_type_t tsip_request_get_type(const char* method); + +/*********************************** +* Ragel state machine. +*/ +%%{ + machine tsip_machine_parser_header_CSeq; + + # Includes + include tsip_machine_utils "./ragel/tsip_machine_utils.rl"; + + action tag{ + tag_start = p; + } + + action parse_method{ + TSK_PARSER_SET_STRING(hdr_cseq->method); + } + + action parse_seq{ + TSK_PARSER_SET_UINT(hdr_cseq->seq); + } + + action eob{ + } + + CSeq = "CSeq"i HCOLON DIGIT+>tag %parse_seq LWS Method >tag %parse_method; + + # Entry point + main := CSeq :>CRLF @eob; + +}%% + + +tsip_header_CSeq_t* tsip_header_CSeq_create(int32_t seq, const char*method) +{ + return tsk_object_new(TSIP_HEADER_CSEQ_VA_ARGS(seq, method)); +} + +int tsip_header_CSeq_serialize(const tsip_header_t* header, tsk_buffer_t* output) +{ + if(header){ + const tsip_header_CSeq_t *CSeq = (const tsip_header_CSeq_t *)header; + return tsk_buffer_append_2(output, "%u %s", CSeq->seq, CSeq->method); + } + return -1; +} + +tsip_header_CSeq_t *tsip_header_CSeq_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsip_header_CSeq_t *hdr_cseq = tsip_header_CSeq_create(TSIP_HEADER_CSEQ_NONE, tsk_null); + + const char *tag_start = tsk_null; + + %%write data; + (void)(eof); + (void)(tsip_machine_parser_header_CSeq_first_final); + (void)(tsip_machine_parser_header_CSeq_error); + (void)(tsip_machine_parser_header_CSeq_en_main); + %%write init; + %%write exec; + + if( cs < %%{ write first_final; }%% ){ + TSK_DEBUG_ERROR("Failed to parse 'CSeq' header."); + TSK_OBJECT_SAFE_FREE(hdr_cseq); + } + else { + hdr_cseq->type = tsip_request_get_type(hdr_cseq->method); + } + + return hdr_cseq; +} + + + + + + + +//======================================================== +// CSeq header object definition +// + +static tsk_object_t* tsip_header_CSeq_ctor(tsk_object_t *self, va_list * app) +{ + tsip_header_CSeq_t *CSeq = self; + if(CSeq){ + TSIP_HEADER(CSeq)->type = tsip_htype_CSeq; + TSIP_HEADER(CSeq)->serialize = tsip_header_CSeq_serialize; + CSeq->seq = va_arg(*app, uint32_t); + CSeq->method = tsk_strdup(va_arg(*app, const char*)); + + if(!tsk_strnullORempty(CSeq->method)){ + CSeq->type = tsip_request_get_type(CSeq->method); + } + else{ + CSeq->type = tsip_NONE; + } + } + else{ + TSK_DEBUG_ERROR("Failed to create new CSeq header."); + } + return self; +} + +static tsk_object_t* tsip_header_CSeq_dtor(tsk_object_t *self) +{ + tsip_header_CSeq_t *CSeq = self; + if(CSeq){ + TSK_FREE(CSeq->method); + TSK_OBJECT_SAFE_FREE(TSIP_HEADER_PARAMS(CSeq)); + } + else{ + TSK_DEBUG_ERROR("Null CSeq header."); + } + + return self; +} + +static const tsk_object_def_t tsip_header_CSeq_def_s = +{ + sizeof(tsip_header_CSeq_t), + tsip_header_CSeq_ctor, + tsip_header_CSeq_dtor, + tsk_null +}; +const tsk_object_def_t *tsip_header_CSeq_def_t = &tsip_header_CSeq_def_s; + diff --git a/tinySIP/ragel/tsip_parser_header_Call_ID.rl b/tinySIP/ragel/tsip_parser_header_Call_ID.rl new file mode 100644 index 0000000..b2c2c78 --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_Call_ID.rl @@ -0,0 +1,163 @@ +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* DOUBANGO is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with DOUBANGO. +* +*/ + +/**@file tsip_header_Call_ID.c + * @brief SIP Call-ID/i header. + * + * @author Mamadou Diop + * + + */ +#include "tinysip/headers/tsip_header_Call_ID.h" + +#include "tinysip/parsers/tsip_parser_uri.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" +#include "tsk_time.h" + +#include + + + +/*********************************** +* Ragel state machine. +*/ +%%{ + machine tsip_machine_parser_header_Call_ID; + + # Includes + include tsip_machine_utils "./ragel/tsip_machine_utils.rl"; + + action tag{ + tag_start = p; + } + + action parse_value{ + TSK_PARSER_SET_STRING(hdr_call_id->value); + } + + action eob{ + } + + callid = word ( "@" word )?; + Call_ID = ( "Call-ID"i | "i"i ) HCOLON callid>tag %parse_value; + + # Entry point + main := Call_ID :>CRLF @eob; + +}%% + + +tsip_header_Call_ID_t* tsip_header_Call_ID_create(const char* call_id) +{ + return tsk_object_new(TSIP_HEADER_CALL_ID_VA_ARGS(call_id)); +} + +int tsip_header_Call_ID_serialize(const tsip_header_t* header, tsk_buffer_t* output) +{ + if(header){ + const tsip_header_Call_ID_t *Call_ID = (const tsip_header_Call_ID_t *)header; + if(Call_ID->value){ + return tsk_buffer_append(output, Call_ID->value, tsk_strlen(Call_ID->value)); + } + } + return -1; +} + +int tsip_header_Call_ID_random(tsk_uuidstring_t *result) +{ + return tsk_uuidgenerate(result); +} + +tsip_header_Call_ID_t *tsip_header_Call_ID_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsip_header_Call_ID_t *hdr_call_id = tsip_header_Call_ID_create(0); + + const char *tag_start = tsk_null; + + %%write data; + (void)(eof); + (void)(tsip_machine_parser_header_Call_ID_first_final); + (void)(tsip_machine_parser_header_Call_ID_error); + (void)(tsip_machine_parser_header_Call_ID_en_main); + %%write init; + %%write exec; + + if( cs < %%{ write first_final; }%% ){ + TSK_DEBUG_ERROR("Failed to parse SIP 'Call-ID' header."); + TSK_OBJECT_SAFE_FREE(hdr_call_id); + } + + return hdr_call_id; +} + + + + + + + +//======================================================== +// Call_ID header object definition +// + +static tsk_object_t* tsip_header_Call_ID_ctor(tsk_object_t *self, va_list * app) +{ + tsip_header_Call_ID_t *Call_ID = self; + if(Call_ID){ + Call_ID->value = tsk_strdup(va_arg(*app, const char *)); + TSIP_HEADER(Call_ID)->type = tsip_htype_Call_ID; + TSIP_HEADER(Call_ID)->serialize = tsip_header_Call_ID_serialize; + } + else{ + TSK_DEBUG_ERROR("Failed to create new Call-ID header."); + } + return self; +} + +static tsk_object_t* tsip_header_Call_ID_dtor(tsk_object_t *self) +{ + tsip_header_Call_ID_t *Call_ID = self; + if(Call_ID){ + TSK_FREE(Call_ID->value); + TSK_OBJECT_SAFE_FREE(TSIP_HEADER_PARAMS(Call_ID)); + } + else{ + TSK_DEBUG_ERROR("Null Call-ID header."); + } + + return self; +} + +static const tsk_object_def_t tsip_header_Call_ID_def_s = +{ + sizeof(tsip_header_Call_ID_t), + tsip_header_Call_ID_ctor, + tsip_header_Call_ID_dtor, + tsk_null +}; +const tsk_object_def_t *tsip_header_Call_ID_def_t = &tsip_header_Call_ID_def_s; diff --git a/tinySIP/ragel/tsip_parser_header_Call_Info.rl b/tinySIP/ragel/tsip_parser_header_Call_Info.rl new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_Call_Info.rl @@ -0,0 +1 @@ + diff --git a/tinySIP/ragel/tsip_parser_header_Contact.rl b/tinySIP/ragel/tsip_parser_header_Contact.rl new file mode 100644 index 0000000..07571a9 --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_Contact.rl @@ -0,0 +1,256 @@ +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* DOUBANGO is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with DOUBANGO. +* +*/ + +/**@file tsip_header_Contact.c + * @brief SIP Contact/m header. + * + * @author Mamadou Diop + * + + */ +#include "tinysip/headers/tsip_header_Contact.h" + +#include "tinysip/parsers/tsip_parser_uri.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" + + + +/*********************************** +* Ragel state machine. +*/ +%%{ + machine tsip_machine_parser_header_Contact; + + # Includes + include tsip_machine_utils "./ragel/tsip_machine_utils.rl"; + + action tag{ + tag_start = p; + } + + action create_contact{ + if(!curr_contact){ + curr_contact = tsip_header_Contact_create(); + } + } + + action parse_display_name{ + if(curr_contact){ + TSK_PARSER_SET_STRING(curr_contact->display_name); + tsk_strunquote(&curr_contact->display_name); + } + } + + action parse_uri{ + if(curr_contact && !curr_contact->uri){ + int len = (int)(p - tag_start); + if((curr_contact->uri = tsip_uri_parse(tag_start, (tsk_size_t)len)) && curr_contact->display_name){ + curr_contact->uri->display_name = tsk_strdup(curr_contact->display_name); + } + } + } + + action parse_expires{ + if(curr_contact){ + TSK_PARSER_SET_INTEGER(curr_contact->expires); + } + } + + action parse_param{ + if(curr_contact){ + TSK_PARSER_ADD_PARAM(TSIP_HEADER_PARAMS(curr_contact)); + } + } + + action add_contact{ + if(curr_contact){ + tsk_list_push_back_data(hdr_contacts, ((void**) &curr_contact)); + } + } + + action eob{ + } + + URI = (scheme HCOLON any+)>tag %parse_uri; + display_name = (( token LWS )+ | quoted_string)>tag %parse_display_name; + my_name_addr = display_name? :>LAQUOT<: URI :>RAQUOT; + + c_p_expires = "expires"i EQUAL delta_seconds>tag %parse_expires; + contact_extension = (generic_param)>tag %parse_param; + contact_params = c_p_expires@1 | contact_extension@0; + contact_param = ( (my_name_addr | URI) :> (SEMI contact_params)* ) >create_contact %add_contact; + Contact = ( "Contact"i | "m"i ) HCOLON ( STAR | ( contact_param ( COMMA contact_param )* ) ); + + # Entry point + main := Contact :>CRLF @eob; + +}%% + + +tsip_header_Contact_t* tsip_header_Contact_create() +{ + return tsk_object_new(tsip_header_Contact_def_t); +} + +int tsip_header_Contact_serialize(const tsip_header_t* header, tsk_buffer_t* output) +{ + if(header){ + const tsip_header_Contact_t *Contact = (const tsip_header_Contact_t *)header; + int ret = 0; + + /* Uri with hacked display-name*/ + if((ret = tsip_uri_serialize(Contact->uri, tsk_true, tsk_true, output))){ + return ret; + } + + /* Expires */ + if(Contact->expires >=0){ + tsk_buffer_append_2(output, ";expires=%lld", Contact->expires); + } + + return ret; + } + + return -1; +} + + +tsip_header_Contacts_L_t *tsip_header_Contact_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsip_header_Contacts_L_t *hdr_contacts = tsk_list_create(); + + const char *tag_start = tsk_null; + tsip_header_Contact_t *curr_contact = 0; + + %%write data; + (void)(eof); + (void)(tsip_machine_parser_header_Contact_first_final); + (void)(tsip_machine_parser_header_Contact_error); + (void)(tsip_machine_parser_header_Contact_en_main); + %%write init; + %%write exec; + + if( cs < %%{ write first_final; }%% ){ + TSK_DEBUG_ERROR("Failed to parse SIP 'Contact' header."); + TSK_OBJECT_SAFE_FREE(curr_contact); + TSK_OBJECT_SAFE_FREE(hdr_contacts); + } + + return hdr_contacts; +} + + + + +//======================================================== +// Contact header object definition +// + +static tsk_object_t* tsip_header_Contact_ctor(tsk_object_t *self, va_list * app) +{ + tsip_header_Contact_t *Contact = self; + if(Contact){ + TSIP_HEADER(Contact)->type = tsip_htype_Contact; + TSIP_HEADER(Contact)->serialize = tsip_header_Contact_serialize; + Contact->expires = -1; + } + else{ + TSK_DEBUG_ERROR("Failed to create new Contact header."); + } + return self; +} + +static tsk_object_t* tsip_header_Contact_dtor(tsk_object_t *self) +{ + tsip_header_Contact_t *Contact = self; + if(Contact){ + TSK_FREE(Contact->display_name); + TSK_OBJECT_SAFE_FREE(Contact->uri); + + TSK_OBJECT_SAFE_FREE(TSIP_HEADER_PARAMS(Contact)); + } + else{ + TSK_DEBUG_ERROR("Null Contact header."); + } + + return self; +} + +static const tsk_object_def_t tsip_header_Contact_def_s = +{ + sizeof(tsip_header_Contact_t), + tsip_header_Contact_ctor, + tsip_header_Contact_dtor, + tsk_null +}; +const tsk_object_def_t *tsip_header_Contact_def_t = &tsip_header_Contact_def_s; + + +////======================================================== +//// Contact object definition +//// +// +///**@ingroup tsip_header_Contact_group +//*/ +//static tsk_object_t* tsip_contact_ctor(tsk_object_t *self, va_list * app) +//{ +// tsip_contact_t *contact = self; +// if(contact) +// { +// contact->expires = -1; +// } +// else +// { +// TSK_DEBUG_ERROR("Failed to create new Contact object."); +// } +// return self; +//} +// +//static tsk_object_t* tsip_contact_dtor(tsk_object_t *self) +//{ +// tsip_contact_t *contact = self; +// if(contact) +// { +// TSK_FREE(contact->display_name); +// TSK_OBJECT_SAFE_FREE(TSIP_HEADER_PARAMS(contact)); +// +// TSK_OBJECT_SAFE_FREE(contact->uri); +// } +// else TSK_DEBUG_ERROR("Null Contact object."); +// +// return self; +//} +// +//static const tsk_object_def_t tsip_contact_def_s = +//{ +// sizeof(tsip_contact_t), +// tsip_contact_ctor, +// tsip_contact_dtor, +// 0 +//}; +//const void *tsip_contact_def_t = &tsip_contact_def_s; diff --git a/tinySIP/ragel/tsip_parser_header_Content_Disposition.rl b/tinySIP/ragel/tsip_parser_header_Content_Disposition.rl new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_Content_Disposition.rl @@ -0,0 +1 @@ + diff --git a/tinySIP/ragel/tsip_parser_header_Content_Encoding.rl b/tinySIP/ragel/tsip_parser_header_Content_Encoding.rl new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_Content_Encoding.rl @@ -0,0 +1 @@ + diff --git a/tinySIP/ragel/tsip_parser_header_Content_Language.rl b/tinySIP/ragel/tsip_parser_header_Content_Language.rl new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_Content_Language.rl @@ -0,0 +1 @@ + diff --git a/tinySIP/ragel/tsip_parser_header_Content_Length.rl b/tinySIP/ragel/tsip_parser_header_Content_Length.rl new file mode 100644 index 0000000..fdb08cc --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_Content_Length.rl @@ -0,0 +1,157 @@ +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* DOUBANGO is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with DOUBANGO. +* +*/ + +/**@file tsip_header_Content_Length.c + * @brief SIP Content-Length/l header. + * + * @author Mamadou Diop + * + + */ +#include "tinysip/headers/tsip_header_Content_Length.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" + + + +/*********************************** +* Ragel state machine. +*/ +%%{ + machine tsip_machine_parser_header_Content_Length; + + # Includes + include tsip_machine_utils "./ragel/tsip_machine_utils.rl"; + + action tag{ + tag_start = p; + } + + action parse_content_length{ + TSK_PARSER_SET_INTEGER(hdr_clength->length); + } + + action eob{ + } + + Content_Length = ( "Content-Length"i | "l"i ) HCOLON (DIGIT+)>tag %parse_content_length; + + # Entry point + main := Content_Length :>CRLF @eob; + +}%% + + +tsip_header_Content_Length_t* tsip_header_Content_Length_create(uint32_t length) +{ + return tsk_object_new(TSIP_HEADER_CONTENT_LENGTH_VA_ARGS(length)); +} + +tsip_header_Content_Length_t* tsip_header_Content_Length_create_null() +{ + return tsip_header_Content_Length_create(0); +} + +int tsip_header_Content_Length_serialize(const tsip_header_t* header, tsk_buffer_t* output) +{ + if(header){ + const tsip_header_Content_Length_t *Content_Length = (const tsip_header_Content_Length_t *)header; + return tsk_buffer_append_2(output, "%u", Content_Length->length); + } + + return -1; +} + +tsip_header_Content_Length_t *tsip_header_Content_Length_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsip_header_Content_Length_t *hdr_clength = tsip_header_Content_Length_create(0); + + const char *tag_start = tsk_null; + + %%write data; + (void)(eof); + (void)(tsip_machine_parser_header_Content_Length_first_final); + (void)(tsip_machine_parser_header_Content_Length_error); + (void)(tsip_machine_parser_header_Content_Length_en_main); + %%write init; + %%write exec; + + if( cs < %%{ write first_final; }%% ){ + TSK_DEBUG_ERROR("Failed to parse SIP 'Content-Length' header."); + TSK_OBJECT_SAFE_FREE(hdr_clength); + } + + return hdr_clength; +} + + + + + + + +//======================================================== +// Content_Length header object definition +// + +static tsk_object_t* tsip_header_Content_Length_ctor(tsk_object_t *self, va_list * app) +{ + tsip_header_Content_Length_t *Content_Length = self; + if(Content_Length){ + Content_Length->length = va_arg(*app, uint32_t); + + TSIP_HEADER(Content_Length)->type = tsip_htype_Content_Length; + TSIP_HEADER(Content_Length)->serialize = tsip_header_Content_Length_serialize; + } + else{ + TSK_DEBUG_ERROR("Failed to create new Content_Length header."); + } + return self; +} + +static tsk_object_t* tsip_header_Content_Length_dtor(tsk_object_t *self) +{ + tsip_header_Content_Length_t *Content_Length = self; + if(Content_Length){ + TSK_OBJECT_SAFE_FREE(TSIP_HEADER_PARAMS(Content_Length)); + } + else{ + TSK_DEBUG_ERROR("Null Content_Length header."); + } + + return self; +} + +static const tsk_object_def_t tsip_header_Content_Length_def_s = +{ + sizeof(tsip_header_Content_Length_t), + tsip_header_Content_Length_ctor, + tsip_header_Content_Length_dtor, + tsk_null +}; +const tsk_object_def_t *tsip_header_Content_Length_def_t = &tsip_header_Content_Length_def_s; + diff --git a/tinySIP/ragel/tsip_parser_header_Content_Type.rl b/tinySIP/ragel/tsip_parser_header_Content_Type.rl new file mode 100644 index 0000000..4903996 --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_Content_Type.rl @@ -0,0 +1,181 @@ +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* DOUBANGO is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with DOUBANGO. +* +*/ + +/**@file tsip_header_Content_Type.c + * @brief SIP Content-Type/c header. + * + * @author Mamadou Diop + * + + */ +#include "tinysip/headers/tsip_header_Content_Type.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" + +#include + + + +/*********************************** +* Ragel state machine. +*/ +%%{ + machine tsip_machine_parser_header_Content_Type; + + # Includes + include tsip_machine_utils "./ragel/tsip_machine_utils.rl"; + + action tag{ + tag_start = p; + } + + action parse_content_type{ + TSK_PARSER_SET_STRING(hdr_ctype->type); + } + + action parse_param{ + TSK_PARSER_ADD_PARAM(TSIP_HEADER_PARAMS(hdr_ctype)); + } + + action eob{ + } + + extension_token = ietf_token | x_token; + + m_attribute = token; + m_value = token | quoted_string; + m_parameter = (m_attribute EQUAL m_value)>tag %parse_param; + + discrete_type = "text"i | "image"i | "audio"i | "video"i | "application"i | extension_token; + composite_type = "message"i | "multipart"i | extension_token; + m_type = discrete_type | composite_type; + m_subtype = extension_token | iana_token; + + media_type = (m_type SLASH m_subtype)@1 >tag %parse_content_type ((SEMI m_parameter)*)@0; + + Content_Type = ( "Content-Type"i | "c"i ) HCOLON media_type; + + # Entry point + main := Content_Type :>CRLF @eob; + +}%% + +tsip_header_Content_Type_t* tsip_header_Content_Type_create(const char* type) +{ + return tsk_object_new(TSIP_HEADER_CONTENT_TYPE_VA_ARGS(type)); +} + +tsip_header_Content_Type_t* tsip_header_Content_Type_create_null() +{ + return tsip_header_Content_Type_create(tsk_null); +} + +int tsip_header_Content_Type_serialize(const tsip_header_t* header, tsk_buffer_t* output) +{ + if(header){ + const tsip_header_Content_Type_t *Content_Type = (const tsip_header_Content_Type_t *)header; + if(Content_Type->type){ + return tsk_buffer_append(output, Content_Type->type, tsk_strlen(Content_Type->type)); + } + else{ + return -2; + } + } + + return -1; +} + +tsip_header_Content_Type_t *tsip_header_Content_Type_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsip_header_Content_Type_t *hdr_ctype = tsip_header_Content_Type_create_null(); + + const char *tag_start = tsk_null; + + %%write data; + (void)(eof); + (void)(tsip_machine_parser_header_Content_Type_first_final); + (void)(tsip_machine_parser_header_Content_Type_error); + (void)(tsip_machine_parser_header_Content_Type_en_main); + %%write init; + %%write exec; + + if( cs < %%{ write first_final; }%% ){ + TSK_DEBUG_ERROR("Failed to parse SIP 'Content-Type' header."); + TSK_OBJECT_SAFE_FREE(hdr_ctype); + } + + return hdr_ctype; +} + + + + + + + +//======================================================== +// Content_Type header object definition +// + +static tsk_object_t* tsip_header_Content_Type_ctor(tsk_object_t *self, va_list * app) +{ + tsip_header_Content_Type_t *Content_Type = self; + if(Content_Type){ + TSIP_HEADER(Content_Type)->type = tsip_htype_Content_Type; + TSIP_HEADER(Content_Type)->serialize = tsip_header_Content_Type_serialize; + + Content_Type->type = tsk_strdup( va_arg(*app, const char*) ); + } + else{ + TSK_DEBUG_ERROR("Failed to create new Content_Type header."); + } + return self; +} + +static tsk_object_t* tsip_header_Content_Type_dtor(tsk_object_t *self) +{ + tsip_header_Content_Type_t *Content_Type = self; + if(Content_Type){ + TSK_FREE(Content_Type->type); + TSK_OBJECT_SAFE_FREE(TSIP_HEADER_PARAMS(Content_Type)); + } + else{ + TSK_DEBUG_ERROR("Null Content_Type header."); + } + + return self; +} + +static const tsk_object_def_t tsip_header_Content_Type_def_s = +{ + sizeof(tsip_header_Content_Type_t), + tsip_header_Content_Type_ctor, + tsip_header_Content_Type_dtor, + tsk_null +}; +const tsk_object_def_t *tsip_header_Content_Type_def_t = &tsip_header_Content_Type_def_s; + diff --git a/tinySIP/ragel/tsip_parser_header_Date.rl b/tinySIP/ragel/tsip_parser_header_Date.rl new file mode 100644 index 0000000..2fd4300 --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_Date.rl @@ -0,0 +1,221 @@ +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* DOUBANGO is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with DOUBANGO. +* +*/ + +/**@file tsip_header_Date.c + * @brief SIP DUmmy header. + * + * @author Mamadou Diop + * + + */ +#include "tinysip/headers/tsip_header_Date.h" + +#include "tinysip/parsers/tsip_parser_uri.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" + +#include + + + +/*********************************** +* Ragel state machine. +*/ +%%{ + machine tsip_machine_parser_header_Date; + + # Includes + include tsip_machine_utils "./ragel/tsip_machine_utils.rl"; + + action tag{ + tag_start = p; + } + + action parse_wkday{ + TSK_PARSER_SET_STRING(hdr_Date->wkday); + } + + action parse_day{ + TSK_PARSER_SET_INTEGER(hdr_Date->day); + } + + action parse_month{ + TSK_PARSER_SET_STRING(hdr_Date->month); + } + + action parse_year{ + TSK_PARSER_SET_INTEGER(hdr_Date->year); + } + + action parse_h{ + TSK_PARSER_SET_INTEGER(hdr_Date->time.h); + } + + action parse_m{ + TSK_PARSER_SET_INTEGER(hdr_Date->time.m); + } + + action parse_s{ + TSK_PARSER_SET_INTEGER(hdr_Date->time.s); + } + + action eob{ + } + + wkday = "Mon"i | "Tue"i | "Wed"i | "Thu"i | "Fri"i | "Sat"i | "Sun"i; + month = "Jan"i | "Feb"i | "Mar"i | "Apr"i | "May"i | "Jun"i | "Jul"i | "Aug"i | "Sep"i | "Oct"i | "Nov"i | "Dec"i; + date1 = DIGIT{2}>tag %parse_day SP month>tag %parse_month SP DIGIT{4}>tag %parse_year; + time = DIGIT{2}>tag %parse_h ":" DIGIT{2}>tag %parse_m ":" DIGIT{2}>tag %parse_s; + rfc1123_date = wkday>tag %parse_wkday "," SP date1 SP time SP "GMT"i; + SIP_date = rfc1123_date; + Date = "Date"i HCOLON SIP_date; + + # Entry point + main := Date :>CRLF @eob; + +}%% + +tsip_header_Date_t* tsip_header_Date_create(const char* wkday, const char* month, int8_t day, int16_t year, int8_t h, int8_t m, int8_t s) +{ + return tsk_object_new(TSIP_HEADER_DATE_VA_ARGS(wkday, month, day, year, h, m, s)); +} + +tsip_header_Date_t* tsip_header_Date_create_null() +{ + return tsip_header_Date_create(tsk_null, tsk_null, -1, -1, -1, -1, -1); +} + +int tsip_header_Date_serialize(const tsip_header_t* header, tsk_buffer_t* output) +{ + /* Date: Wed, 28 Apr 2010 23:42:50 GMT */ + if(header){ + const tsip_header_Date_t *Date = (const tsip_header_Date_t *)header; + if(Date->month){ + tsk_buffer_append_2(output, "%s, %d %s %d %d:%d:%d GMT", + Date->wkday, Date->day, Date->month, Date->year, Date->time.h, Date->time.m, Date->time.s); + } + return 0; + } + + return -1; +} + +tsip_header_Date_t *tsip_header_Date_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsip_header_Date_t *hdr_Date = tsip_header_Date_create_null(); + + const char *tag_start = tsk_null; + + %%write data; + (void)(eof); + (void)(tsip_machine_parser_header_Date_first_final); + (void)(tsip_machine_parser_header_Date_error); + (void)(tsip_machine_parser_header_Date_en_main); + %%write init; + %%write exec; + + if( cs < %%{ write first_final; }%% ){ + TSK_DEBUG_ERROR("Failed to parse 'Date' header."); + TSK_OBJECT_SAFE_FREE(hdr_Date); + } + + return hdr_Date; +} + + + + + + + +//======================================================== +// Date header object definition +// + +static tsk_object_t* tsip_header_Date_ctor(tsk_object_t *self, va_list * app) +{ + tsip_header_Date_t *Date = self; + if(Date){ + const char* wkday; + const char* month; + TSIP_HEADER(Date)->type = tsip_htype_Date; + TSIP_HEADER(Date)->serialize = tsip_header_Date_serialize; + Date->day = Date->time.h = Date->time.m = Date->time.s = -1; + Date->year = -1; + + if((wkday = va_arg(*app, const char*))){ + month = va_arg(*app, const char*); + + Date->wkday = tsk_strdup(wkday); + Date->month = tsk_strdup(month); + +#if defined __GNUC__ + Date->day = (int8_t)va_arg(*app, int); + Date->year = (int16_t)va_arg(*app, int); + Date->time.h = (int8_t)va_arg(*app, int); + Date->time.m = (int8_t)va_arg(*app, int); + Date->time.s = (int8_t)va_arg(*app, int); +#else + Date->day = va_arg(*app, int8_t); + Date->year = va_arg(*app, int16_t); + Date->time.h = va_arg(*app, int8_t); + Date->time.m = va_arg(*app, int8_t); + Date->time.s = va_arg(*app, int8_t); +#endif + } + } + else{ + TSK_DEBUG_ERROR("Failed to create new Date header."); + } + return self; +} + +static tsk_object_t* tsip_header_Date_dtor(tsk_object_t *self) +{ + tsip_header_Date_t *Date = self; + if(Date){ + TSK_FREE(Date->wkday); + TSK_FREE(Date->month); + + TSK_OBJECT_SAFE_FREE(TSIP_HEADER_PARAMS(Date)); + } + else{ + TSK_DEBUG_ERROR("Null Date header."); + } + + return self; +} + +static const tsk_object_def_t tsip_header_Date_def_s = +{ + sizeof(tsip_header_Date_t), + tsip_header_Date_ctor, + tsip_header_Date_dtor, + tsk_null +}; +const tsk_object_def_t *tsip_header_Date_def_t = &tsip_header_Date_def_s; + diff --git a/tinySIP/ragel/tsip_parser_header_Dummy.rl b/tinySIP/ragel/tsip_parser_header_Dummy.rl new file mode 100644 index 0000000..d9dff8a --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_Dummy.rl @@ -0,0 +1,170 @@ +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* DOUBANGO is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with DOUBANGO. +* +*/ + +/**@file tsip_header_Dummy.c + * @brief SIP DUmmy header. + * + * @author Mamadou Diop + * + + */ +#include "tinysip/headers/tsip_header_Dummy.h" + +#include "tinysip/parsers/tsip_parser_uri.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" + +#include + + + +/*********************************** +* Ragel state machine. +*/ +%%{ + machine tsip_machine_parser_header_Dummy; + + # Includes + include tsip_machine_utils "./ragel/tsip_machine_utils.rl"; + + action tag{ + tag_start = p; + } + + action parse_name{ + TSK_PARSER_SET_STRING(hdr_Dummy->name); + } + + action parse_value{ + TSK_PARSER_SET_STRING(hdr_Dummy->value); + } + + action eob{ + } + + Dummy = token>tag %parse_name SP* HCOLON SP*<: any*>tag %parse_value; + + # Entry point + main := Dummy :>CRLF @eob; + +}%% + +tsip_header_Dummy_t* tsip_header_Dummy_create(const char* name, const char* value) +{ + return tsk_object_new(TSIP_HEADER_DUMMY_VA_ARGS(name, value)); +} + +tsip_header_Dummy_t* tsip_header_Dummy_create_null() +{ + return tsip_header_Dummy_create(tsk_null, tsk_null); +} + +int tsip_header_Dummy_serialize(const tsip_header_t* header, tsk_buffer_t* output) +{ + if(header){ + const tsip_header_Dummy_t *Dummy = (const tsip_header_Dummy_t *)header; + if(Dummy->value){ + tsk_buffer_append(output, Dummy->value, tsk_strlen(Dummy->value)); + } + return 0; + } + + return -1; +} + +tsip_header_Dummy_t *tsip_header_Dummy_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsip_header_Dummy_t *hdr_Dummy = tsip_header_Dummy_create_null(); + + const char *tag_start = tsk_null; + + %%write data; + (void)(eof); + (void)(tsip_machine_parser_header_Dummy_first_final); + (void)(tsip_machine_parser_header_Dummy_error); + (void)(tsip_machine_parser_header_Dummy_en_main); + %%write init; + %%write exec; + + if( cs < %%{ write first_final; }%% ){ + TSK_DEBUG_ERROR("Failed to parse 'Dummy' header."); + TSK_OBJECT_SAFE_FREE(hdr_Dummy); + } + + return hdr_Dummy; +} + + + + + + + +//======================================================== +// Dummy header object definition +// + +static tsk_object_t* tsip_header_Dummy_ctor(tsk_object_t *self, va_list * app) +{ + tsip_header_Dummy_t *Dummy = self; + if(Dummy){ + TSIP_HEADER(Dummy)->type = tsip_htype_Dummy; + TSIP_HEADER(Dummy)->serialize = tsip_header_Dummy_serialize; + + Dummy->name = tsk_strdup(va_arg(*app, const char*)); + Dummy->value = tsk_strdup(va_arg(*app, const char*)); + } + else{ + TSK_DEBUG_ERROR("Failed to create new Dummy header."); + } + return self; +} + +static tsk_object_t* tsip_header_Dummy_dtor(tsk_object_t *self) +{ + tsip_header_Dummy_t *Dummy = self; + if(Dummy){ + TSK_FREE(Dummy->name); + TSK_FREE(Dummy->value); + + TSK_OBJECT_SAFE_FREE(TSIP_HEADER_PARAMS(Dummy)); + } + else{ + TSK_DEBUG_ERROR("Null Dummy header."); + } + + return self; +} + +static const tsk_object_def_t tsip_header_Dummy_def_s = +{ + sizeof(tsip_header_Dummy_t), + tsip_header_Dummy_ctor, + tsip_header_Dummy_dtor, + tsk_null +}; +const tsk_object_def_t *tsip_header_Dummy_def_t = &tsip_header_Dummy_def_s; diff --git a/tinySIP/ragel/tsip_parser_header_Error_Info.rl b/tinySIP/ragel/tsip_parser_header_Error_Info.rl new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_Error_Info.rl @@ -0,0 +1 @@ + diff --git a/tinySIP/ragel/tsip_parser_header_Event.rl b/tinySIP/ragel/tsip_parser_header_Event.rl new file mode 100644 index 0000000..42bfe34 --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_Event.rl @@ -0,0 +1,168 @@ +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* DOUBANGO is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with DOUBANGO. +* +*/ + +/**@file tsip_header_Event.c + * @brief SIP Event/o header as per RFC 3265.. + * + * @author Mamadou Diop + * + + */ +#include "tinysip/headers/tsip_header_Event.h" + +#include "tinysip/parsers/tsip_parser_uri.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" + +#include + + + +/*********************************** +* Ragel state machine. +*/ +%%{ + machine tsip_machine_parser_header_Event; + + # Includes + include tsip_machine_utils "./ragel/tsip_machine_utils.rl"; + + action tag{ + tag_start = p; + } + + action parse_package{ + TSK_PARSER_SET_STRING(hdr_event->package); + } + + action parse_param{ + TSK_PARSER_ADD_PARAM(TSIP_HEADER_PARAMS(hdr_event)); + } + + action eob{ + } + + event_param = generic_param>tag %parse_param; + event_package = token_nodot; + event_template = token_nodot; + event_type = (event_package ( "." event_template )*)>tag %parse_package; + + Event = ( "Event"i | "o"i ) HCOLON event_type ( SEMI event_param )*; + + # Entry point + main := Event :>CRLF @eob; + +}%% + + +tsip_header_Event_t* tsip_header_Event_create(const char* package) +{ + return tsk_object_new(TSIP_HEADER_EVENT_VA_ARGS(package)); +} + +int tsip_header_Event_serialize(const tsip_header_t* header, tsk_buffer_t* output) +{ + if(header){ + const tsip_header_Event_t *Event = (const tsip_header_Event_t *)header; + if(Event->package){ + return tsk_buffer_append(output, Event->package, tsk_strlen(Event->package)); + } + return 0; + } + + return -1; +} + +tsip_header_Event_t *tsip_header_Event_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsip_header_Event_t *hdr_event = tsip_header_Event_create(tsk_null); + + const char *tag_start = tsk_null; + + %%write data; + (void)(eof); + (void)(tsip_machine_parser_header_Event_first_final); + (void)(tsip_machine_parser_header_Event_error); + (void)(tsip_machine_parser_header_Event_en_main); + %%write init; + %%write exec; + + if( cs < %%{ write first_final; }%% ){ + TSK_DEBUG_ERROR("Failed to parse 'Event' header."); + TSK_OBJECT_SAFE_FREE(hdr_event); + } + + return hdr_event; +} + + + + + + + +//======================================================== +// Event header object definition +// + +static tsk_object_t* tsip_header_Event_ctor(tsk_object_t *self, va_list * app) +{ + tsip_header_Event_t *Event = self; + if(Event){ + TSIP_HEADER(Event)->type = tsip_htype_Event; + TSIP_HEADER(Event)->serialize = tsip_header_Event_serialize; + Event->package = tsk_strdup(va_arg(*app, const char*)); + } + else{ + TSK_DEBUG_ERROR("Failed to create new Event header."); + } + return self; +} + +static tsk_object_t* tsip_header_Event_dtor(tsk_object_t *self) +{ + tsip_header_Event_t *Event = self; + if(Event){ + TSK_FREE(Event->package); + TSK_OBJECT_SAFE_FREE(TSIP_HEADER_PARAMS(Event)); + } + else{ + TSK_DEBUG_ERROR("Null Event header."); + } + + return self; +} + +static const tsk_object_def_t tsip_header_Event_def_s = +{ + sizeof(tsip_header_Event_t), + tsip_header_Event_ctor, + tsip_header_Event_dtor, + tsk_null +}; +const tsk_object_def_t *tsip_header_Event_def_t = &tsip_header_Event_def_s; + diff --git a/tinySIP/ragel/tsip_parser_header_Expires.rl b/tinySIP/ragel/tsip_parser_header_Expires.rl new file mode 100644 index 0000000..786bb4f --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_Expires.rl @@ -0,0 +1,155 @@ +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* DOUBANGO is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with DOUBANGO. +* +*/ + +/**@file tsip_header_Expires.c + * @brief SIP Expires header. + * + * @author Mamadou Diop + * + + */ +#include "tinysip/headers/tsip_header_Expires.h" + +#include "tinysip/parsers/tsip_parser_uri.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" + + + +/*********************************** +* Ragel state machine. +*/ +%%{ + machine tsip_machine_parser_header_Expires; + + # Includes + include tsip_machine_utils "./ragel/tsip_machine_utils.rl"; + + action tag{ + tag_start = p; + } + + action parse_delta_seconds{ + TSK_PARSER_SET_INTEGER(hdr_expires->delta_seconds); + } + + action eob{ + } + + Expires = "Expires"i HCOLON delta_seconds>tag %parse_delta_seconds; + + # Entry point + main := Expires :>CRLF @eob; + +}%% + +tsip_header_Expires_t* tsip_header_Expires_create(int64_t delta_seconds) +{ + return tsk_object_new(TSIP_HEADER_EXPIRES_VA_ARGS(delta_seconds)); +} + +int tsip_header_Expires_serialize(const tsip_header_t* header, tsk_buffer_t* output) +{ + if(header){ + const tsip_header_Expires_t *Expires = (const tsip_header_Expires_t *)header; + if(Expires->delta_seconds >=0){ + return tsk_buffer_append_2(output, "%lld", Expires->delta_seconds); + } + return 0; + } + + return -1; +} + +tsip_header_Expires_t *tsip_header_Expires_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsip_header_Expires_t *hdr_expires = tsip_header_Expires_create(TSIP_HEADER_EXPIRES_NONE); + + const char *tag_start = tsk_null; + + %%write data; + (void)(eof); + (void)(tsip_machine_parser_header_Expires_first_final); + (void)(tsip_machine_parser_header_Expires_error); + (void)(tsip_machine_parser_header_Expires_en_main); + %%write init; + %%write exec; + + if( cs < %%{ write first_final; }%% ){ + TSK_DEBUG_ERROR("Failed to parse 'Expires' header."); + TSK_OBJECT_SAFE_FREE(hdr_expires); + } + + return hdr_expires; +} + + + + + + + +//======================================================== +// Expires header object definition +// + +static tsk_object_t* tsip_header_Expires_ctor(tsk_object_t *self, va_list * app) +{ + tsip_header_Expires_t *Expires = self; + if(Expires){ + TSIP_HEADER(Expires)->type = tsip_htype_Expires; + TSIP_HEADER(Expires)->serialize = tsip_header_Expires_serialize; + Expires->delta_seconds = va_arg(*app, int64_t); + } + else{ + TSK_DEBUG_ERROR("Failed to create new Expires header."); + } + return self; +} + +static tsk_object_t* tsip_header_Expires_dtor(tsk_object_t *self) +{ + tsip_header_Expires_t *Expires = self; + if(Expires){ + TSK_OBJECT_SAFE_FREE(TSIP_HEADER_PARAMS(Expires)); + } + else{ + TSK_DEBUG_ERROR("Null Expires header."); + } + + return self; +} + +static const tsk_object_def_t tsip_header_Expires_def_s = +{ + sizeof(tsip_header_Expires_t), + tsip_header_Expires_ctor, + tsip_header_Expires_dtor, + tsk_null +}; +const tsk_object_def_t *tsip_header_Expires_def_t = &tsip_header_Expires_def_s; + diff --git a/tinySIP/ragel/tsip_parser_header_From.rl b/tinySIP/ragel/tsip_parser_header_From.rl new file mode 100644 index 0000000..09c1588 --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_From.rl @@ -0,0 +1,196 @@ +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* DOUBANGO is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with DOUBANGO. +* +*/ + +/**@file tsip_header_From.c + * @brief SIP From/f header as per RFC 3261 subclause 20.20. + * + * @author Mamadou Diop + * + + */ +#include "tinysip/headers/tsip_header_From.h" + +#include "tinysip/parsers/tsip_parser_uri.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" + + + +/*********************************** +* Ragel state machine. +*/ +%%{ + machine tsip_machine_parser_header_From; + + # Includes + include tsip_machine_utils "./ragel/tsip_machine_utils.rl"; + + action tag{ + tag_start = p; + } + + action parse_uri{ + int len = (int)(p - tag_start); + if(hdr_from && !hdr_from->uri){ + if((hdr_from->uri = tsip_uri_parse(tag_start, (tsk_size_t)len)) && hdr_from->display_name){ + hdr_from->uri->display_name = tsk_strdup(hdr_from->display_name); + } + } + } + + action parse_display_name{ + TSK_PARSER_SET_STRING(hdr_from->display_name); + tsk_strunquote(&hdr_from->display_name); + } + + action parse_tag{ + TSK_PARSER_SET_STRING(hdr_from->tag); + } + + action parse_param{ + TSK_PARSER_ADD_PARAM(TSIP_HEADER_PARAMS(hdr_from)); + } + + action eob{ + } + + URI = (scheme HCOLON any+)>tag %parse_uri; + display_name = (( token LWS )+ | quoted_string)>tag %parse_display_name; + my_name_addr = display_name? :>LAQUOT<: URI :>RAQUOT; + my_tag_param = "tag"i EQUAL token>tag %parse_tag; + from_param = (my_tag_param)@1 | (generic_param)@0 >tag %parse_param; + from_spec = ( my_name_addr | URI ) :> ( SEMI from_param )*; + + From = ( "From"i | "f"i ) HCOLON from_spec; + + # Entry point + main := From :>CRLF @eob; + +}%% + + +tsip_header_From_t* tsip_header_From_create(const char* display_name, const tsip_uri_t* uri, const char* tag) +{ + return tsk_object_new(TSIP_HEADER_FROM_VA_ARGS(display_name, uri, tag)); +} + +int tsip_header_From_serialize(const tsip_header_t* header, tsk_buffer_t* output) +{ + int ret = -1; + if(header){ + const tsip_header_From_t *From = (const tsip_header_From_t *)header; + + /* Uri with hacked display-name*/ + if((ret = tsip_uri_serialize(From->uri, tsk_true, tsk_true, output))){ + return ret; + } + if(From->tag){ + ret = tsk_buffer_append_2(output, ";tag=%s", From->tag); + } + } + return ret; +} + +tsip_header_From_t *tsip_header_From_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsip_header_From_t *hdr_from = tsip_header_From_create(tsk_null, tsk_null, tsk_null); + + const char *tag_start = tsk_null; + + %%write data; + (void)(eof); + (void)(tsip_machine_parser_header_From_first_final); + (void)(tsip_machine_parser_header_From_error); + (void)(tsip_machine_parser_header_From_en_main); + %%write init; + %%write exec; + + if( cs < %%{ write first_final; }%% ){ + TSK_DEBUG_ERROR("Failed to parse 'From' header."); + TSK_OBJECT_SAFE_FREE(hdr_from); + } + + return hdr_from; +} + + + + + + + +//======================================================== +// From header object definition +// + +static tsk_object_t* tsip_header_From_ctor(tsk_object_t *self, va_list * app) +{ + tsip_header_From_t *From = self; + if(From){ + const char* display_name = va_arg(*app, const char *); + const tsip_uri_t* uri = va_arg(*app, const tsip_uri_t *); + const char* tag = va_arg(*app, const char *); + + From->display_name = tsk_strdup(display_name); + if(uri) From->uri = tsk_object_ref((void *)uri); + From->tag = tsk_strdup(tag); + + TSIP_HEADER(From)->type = tsip_htype_From; + TSIP_HEADER(From)->serialize = tsip_header_From_serialize; + } + else{ + TSK_DEBUG_ERROR("Failed to create new From header."); + } + return self; +} + +static tsk_object_t* tsip_header_From_dtor(tsk_object_t *self) +{ + tsip_header_From_t *From = self; + if(From){ + TSK_FREE(From->display_name); + TSK_FREE(From->tag); + + TSK_OBJECT_SAFE_FREE(From->uri); + TSK_OBJECT_SAFE_FREE(TSIP_HEADER_PARAMS(From)); + } + else{ + TSK_DEBUG_ERROR("Null From header."); + } + + return self; +} + +static const tsk_object_def_t tsip_header_From_def_s = +{ + sizeof(tsip_header_From_t), + tsip_header_From_ctor, + tsip_header_From_dtor, + tsk_null +}; +const tsk_object_def_t *tsip_header_From_def_t = &tsip_header_From_def_s; + diff --git a/tinySIP/ragel/tsip_parser_header_History_Info.rl b/tinySIP/ragel/tsip_parser_header_History_Info.rl new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_History_Info.rl @@ -0,0 +1 @@ + diff --git a/tinySIP/ragel/tsip_parser_header_Identity.rl b/tinySIP/ragel/tsip_parser_header_Identity.rl new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_Identity.rl @@ -0,0 +1 @@ + diff --git a/tinySIP/ragel/tsip_parser_header_Identity_Info.rl b/tinySIP/ragel/tsip_parser_header_Identity_Info.rl new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_Identity_Info.rl @@ -0,0 +1 @@ + diff --git a/tinySIP/ragel/tsip_parser_header_In_Reply_To.rl b/tinySIP/ragel/tsip_parser_header_In_Reply_To.rl new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_In_Reply_To.rl @@ -0,0 +1 @@ + diff --git a/tinySIP/ragel/tsip_parser_header_Join.rl b/tinySIP/ragel/tsip_parser_header_Join.rl new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_Join.rl @@ -0,0 +1 @@ + diff --git a/tinySIP/ragel/tsip_parser_header_MIME_Version.rl b/tinySIP/ragel/tsip_parser_header_MIME_Version.rl new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_MIME_Version.rl @@ -0,0 +1 @@ + diff --git a/tinySIP/ragel/tsip_parser_header_Max_Forwards.rl b/tinySIP/ragel/tsip_parser_header_Max_Forwards.rl new file mode 100644 index 0000000..17d337a --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_Max_Forwards.rl @@ -0,0 +1,155 @@ +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* DOUBANGO is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with DOUBANGO. +* +*/ + +/**@file tsip_header_Max_Forwards.c + * @brief SIP Max-Forwards header. + * + * @author Mamadou Diop + * + + */ +#include "tinysip/headers/tsip_header_Max_Forwards.h" + +#include "tinysip/parsers/tsip_parser_uri.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" + + + +/*********************************** +* Ragel state machine. +*/ +%%{ + machine tsip_machine_parser_header_Max_Forwards; + + # Includes + include tsip_machine_utils "./ragel/tsip_machine_utils.rl"; + + action tag{ + tag_start = p; + } + + action parse_value{ + TSK_PARSER_SET_INTEGER(hdr_maxf->value); + } + + action eob{ + } + + Max_Forwards = "Max-Forwards"i HCOLON (DIGIT+)>tag %parse_value; + + # Entry point + main := Max_Forwards :>CRLF @eob; + +}%% + + +tsip_header_Max_Forwards_t* tsip_header_Max_Forwards_create(int32_t max) +{ + return tsk_object_new(TSIP_HEADER_MAX_FORWARDS_VA_ARGS(max)); +} + +int tsip_header_Max_Forwards_serialize(const tsip_header_t* header, tsk_buffer_t* output) +{ + if(header){ + const tsip_header_Max_Forwards_t *Max_Forwards = (const tsip_header_Max_Forwards_t *)header; + if(Max_Forwards->value >= 0){ + return tsk_buffer_append_2(output, "%d", Max_Forwards->value); + } + return 0; + } + + return -1; +} + +tsip_header_Max_Forwards_t *tsip_header_Max_Forwards_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsip_header_Max_Forwards_t *hdr_maxf = tsip_header_Max_Forwards_create(TSIP_HEADER_MAX_FORWARDS_NONE); + + const char *tag_start = tsk_null; + + %%write data; + (void)(eof); + (void)(tsip_machine_parser_header_Max_Forwards_first_final); + (void)(tsip_machine_parser_header_Max_Forwards_error); + (void)(tsip_machine_parser_header_Max_Forwards_en_main); + %%write init; + %%write exec; + + if( cs < %%{ write first_final; }%% ){ + TSK_DEBUG_ERROR("Failed to parse 'Max-Forward' header."); + TSK_OBJECT_SAFE_FREE(hdr_maxf); + } + + return hdr_maxf; +} + + + + + + + +//======================================================== +// Max_Forwards header object definition +// + +static tsk_object_t* tsip_header_Max_Forwards_ctor(tsk_object_t *self, va_list * app) +{ + tsip_header_Max_Forwards_t *Max_Forwards = self; + if(Max_Forwards){ + TSIP_HEADER(Max_Forwards)->type = tsip_htype_Max_Forwards; + TSIP_HEADER(Max_Forwards)->serialize = tsip_header_Max_Forwards_serialize; + Max_Forwards->value = va_arg(*app, int32_t); + } + else{ + TSK_DEBUG_ERROR("Failed to create new Max_Forwards header."); + } + return self; +} + +static tsk_object_t* tsip_header_Max_Forwards_dtor(tsk_object_t *self) +{ + tsip_header_Max_Forwards_t *Max_Forwards = self; + if(Max_Forwards){ + TSK_OBJECT_SAFE_FREE(TSIP_HEADER_PARAMS(Max_Forwards)); + } + else{ + TSK_DEBUG_ERROR("Null Max_Forwards header."); + } + + return self; +} + +static const tsk_object_def_t tsip_header_Max_Forwards_def_s = +{ + sizeof(tsip_header_Max_Forwards_t), + tsip_header_Max_Forwards_ctor, + tsip_header_Max_Forwards_dtor, + tsk_null +}; +const tsk_object_def_t *tsip_header_Max_Forwards_def_t = &tsip_header_Max_Forwards_def_s; diff --git a/tinySIP/ragel/tsip_parser_header_Min_Expires.rl b/tinySIP/ragel/tsip_parser_header_Min_Expires.rl new file mode 100644 index 0000000..857db8d --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_Min_Expires.rl @@ -0,0 +1,160 @@ +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* DOUBANGO is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with DOUBANGO. +* +*/ + +/**@file tsip_header_Min_Expires.c + * @brief SIP Min-Expiress header. + * + * @author Mamadou Diop + * + + */ +#include "tinysip/headers/tsip_header_Min_Expires.h" + +#include "tinysip/parsers/tsip_parser_uri.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" + + + +/*********************************** +* Ragel state machine. +*/ +%%{ + machine tsip_machine_parser_header_Min_Expires; + + # Includes + include tsip_machine_utils "./ragel/tsip_machine_utils.rl"; + + action tag{ + tag_start = p; + } + + action parse_value{ + TSK_PARSER_SET_INTEGER(hdr_minE->value); + } + + action eob{ + } + + Min_Expires = "Min-Expires"i HCOLON (delta_seconds)>tag %parse_value; + + # Entry point + main := Min_Expires :>CRLF @eob; + +}%% + +tsip_header_Min_Expires_t* tsip_header_Min_Expires_create(int32_t value) +{ + return tsk_object_new(TSIP_HEADER_MIN_EXPIRES_VA_ARGS(value)); +} + +tsip_header_Min_Expires_t* tsip_header_Min_Expires_create_null() +{ + return tsip_header_Min_Expires_create(TSIP_HEADER_MIN_EXPIRES_NONE); +} + +int tsip_header_Min_Expires_serialize(const tsip_header_t* header, tsk_buffer_t* output) +{ + if(header){ + const tsip_header_Min_Expires_t *Min_Expires = (const tsip_header_Min_Expires_t *)header; + if(Min_Expires->value >=0){ + return tsk_buffer_append_2(output, "%d", Min_Expires->value); + } + return 0; + } + + return -1; +} + +tsip_header_Min_Expires_t *tsip_header_Min_Expires_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsip_header_Min_Expires_t *hdr_minE = tsip_header_Min_Expires_create_null(); + + const char *tag_start = tsk_null; + + %%write data; + (void)(eof); + (void)(tsip_machine_parser_header_Min_Expires_first_final); + (void)(tsip_machine_parser_header_Min_Expires_error); + (void)(tsip_machine_parser_header_Min_Expires_en_main); + %%write init; + %%write exec; + + if( cs < %%{ write first_final; }%% ){ + TSK_DEBUG_ERROR("Failed to parse 'Min-Expires' header."); + TSK_OBJECT_SAFE_FREE(hdr_minE); + } + + return hdr_minE; +} + + + + + + + +//======================================================== +// Min-Expires header object definition +// + +static tsk_object_t* tsip_header_Min_Expires_ctor(tsk_object_t *self, va_list * app) +{ + tsip_header_Min_Expires_t *Min_Expires = self; + if(Min_Expires){ + TSIP_HEADER(Min_Expires)->type = tsip_htype_Min_Expires; + TSIP_HEADER(Min_Expires)->serialize = tsip_header_Min_Expires_serialize; + Min_Expires->value = va_arg(*app, int32_t); + } + else{ + TSK_DEBUG_ERROR("Failed to create new Min_Expires header."); + } + return self; +} + +static tsk_object_t* tsip_header_Min_Expires_dtor(tsk_object_t *self) +{ + tsip_header_Min_Expires_t *Min_Expires = self; + if(Min_Expires) + { + TSK_OBJECT_SAFE_FREE(TSIP_HEADER_PARAMS(Min_Expires)); + } + else{ + TSK_DEBUG_ERROR("Null Min_Expires header."); + } + + return self; +} + +static const tsk_object_def_t tsip_header_Min_Expires_def_s = +{ + sizeof(tsip_header_Min_Expires_t), + tsip_header_Min_Expires_ctor, + tsip_header_Min_Expires_dtor, + tsk_null +}; +const tsk_object_def_t *tsip_header_Min_Expires_def_t = &tsip_header_Min_Expires_def_s; diff --git a/tinySIP/ragel/tsip_parser_header_Min_SE.rl b/tinySIP/ragel/tsip_parser_header_Min_SE.rl new file mode 100644 index 0000000..bac17d2 --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_Min_SE.rl @@ -0,0 +1,160 @@ + +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* DOUBANGO is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with DOUBANGO. +* +*/ + +/**@file tsip_header_Min_SE.c + * @brief SIP Min-SE header. + * + * @author Mamadou Diop + * + + */ +#include "tinysip/headers/tsip_header_Min_SE.h" + +#include "tinysip/parsers/tsip_parser_uri.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" + + + +/*********************************** +* Ragel state machine. +*/ +%%{ + machine tsip_machine_parser_header_Min_SE; + + # Includes + include tsip_machine_utils "./ragel/tsip_machine_utils.rl"; + + action tag{ + tag_start = p; + } + + action parse_delta_seconds{ + TSK_PARSER_SET_INTEGER(hdr_minse->delta_seconds); + } + + action parse_param{ + TSK_PARSER_ADD_PARAM(TSIP_HEADER_PARAMS(hdr_minse)); + } + + action eob{ + } + + Min_SE = "Min-SE"i HCOLON delta_seconds>tag %parse_delta_seconds ( SEMI generic_param>tag %parse_param )*; + + # Entry point + main := Min_SE :>CRLF @eob; + +}%% + +tsip_header_Min_SE_t* tsip_header_Min_SE_create(int64_t delta_seconds) +{ + return tsk_object_new(TSIP_HEADER_MIN_SE_VA_ARGS(delta_seconds)); +} + +int tsip_header_Min_SE_serialize(const tsip_header_t* header, tsk_buffer_t* output) +{ + if(header){ + const tsip_header_Min_SE_t *MinSE = (const tsip_header_Min_SE_t *)header; + if(MinSE->delta_seconds >=0){ + return tsk_buffer_append_2(output, "%lld", MinSE->delta_seconds); + } + return 0; + } + + return -1; +} + +tsip_header_Min_SE_t *tsip_header_Min_SE_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsip_header_Min_SE_t *hdr_minse = tsip_header_Min_SE_create(TSIP_SESSION_EXPIRES_MIN_VALUE); + + const char *tag_start = tsk_null; + + %%write data; + (void)(eof); + (void)(tsip_machine_parser_header_Min_SE_first_final); + (void)(tsip_machine_parser_header_Min_SE_error); + (void)(tsip_machine_parser_header_Min_SE_en_main); + %%write init; + %%write exec; + + if( cs < %%{ write first_final; }%% ){ + TSK_DEBUG_ERROR("Failed to parse 'Min-SE' header."); + TSK_OBJECT_SAFE_FREE(hdr_minse); + } + + return hdr_minse; +} + + + + + + + +//======================================================== +// MinSE header object definition +// + +static tsk_object_t* tsip_header_Min_SE_ctor(tsk_object_t *self, va_list * app) +{ + tsip_header_Min_SE_t *MinSE = self; + if(MinSE){ + TSIP_HEADER(MinSE)->type = tsip_htype_Min_SE; + TSIP_HEADER(MinSE)->serialize = tsip_header_Min_SE_serialize; + MinSE->delta_seconds = va_arg(*app, int64_t); + } + else{ + TSK_DEBUG_ERROR("Failed to create new MinSE header."); + } + return self; +} + +static tsk_object_t* tsip_header_Min_SE_dtor(tsk_object_t *self) +{ + tsip_header_Min_SE_t *MinSE = self; + if(MinSE){ + TSK_OBJECT_SAFE_FREE(TSIP_HEADER_PARAMS(MinSE)); + } + else{ + TSK_DEBUG_ERROR("Null MinSE header."); + } + + return self; +} + +static const tsk_object_def_t tsip_header_Min_SE_def_s = +{ + sizeof(tsip_header_Min_SE_t), + tsip_header_Min_SE_ctor, + tsip_header_Min_SE_dtor, + tsk_null +}; +const tsk_object_def_t *tsip_header_Min_SE_def_t = &tsip_header_Min_SE_def_s; + diff --git a/tinySIP/ragel/tsip_parser_header_Organization.rl b/tinySIP/ragel/tsip_parser_header_Organization.rl new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_Organization.rl @@ -0,0 +1 @@ + diff --git a/tinySIP/ragel/tsip_parser_header_P_Access_Network_Info.rl b/tinySIP/ragel/tsip_parser_header_P_Access_Network_Info.rl new file mode 100644 index 0000000..042ae85 --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_P_Access_Network_Info.rl @@ -0,0 +1,170 @@ +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* DOUBANGO is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with DOUBANGO. +* +*/ + +/**@file tsip_header_P_Access_Network_Info.c + * @brief SIP P_Access_Network_Info header as per RFC 3455. + * + * Header field where proxy ACK BYE CAN INV OPT REG + ___________________________________________________________ + P-Access-Network-Info dr - o - o o o + + Header field SUB NOT PRA INF UPD MSG REF + ___________________________________________________________ + P-Access-Network-Info o o o o o o o + * + * @author Mamadou Diop + * + + */ +#include "tinysip/headers/tsip_header_P_Access_Network_Info.h" + +#include "tinysip/parsers/tsip_parser_uri.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" + +#include + + + +/*********************************** +* Ragel state machine. +*/ +%%{ + machine tsip_machine_parser_header_P_Access_Network_Info; + + # Includes + include tsip_machine_utils "./ragel/tsip_machine_utils.rl"; + + action tag{ + tag_start = p; + } + + action parse_value{ + TSK_PARSER_SET_STRING(hdr_ani->value); + } + + action eob{ + } + + P_Access_Network_Info = "P-Access-Network-Info"i HCOLON (any*)>tag %parse_value; + + # Entry point + main := P_Access_Network_Info :>CRLF @eob; + +}%% + + +tsip_header_P_Access_Network_Info_t* tsip_header_P_Access_Network_Info_create(const char* value) +{ + return tsk_object_new(TSIP_HEADER_P_ACCESS_NETWORK_INFO_VA_ARGS(value)); +} + +tsip_header_P_Access_Network_Info_t* tsip_header_P_Access_Network_Info_create_null() +{ + return tsip_header_P_Access_Network_Info_create(tsk_null); +} + +int tsip_header_P_Access_Network_Info_serialize(const tsip_header_t* header, tsk_buffer_t* output) +{ + if(header){ + const tsip_header_P_Access_Network_Info_t *P_Access_Network_Info = (const tsip_header_P_Access_Network_Info_t *)header; + if(P_Access_Network_Info->value){ + tsk_buffer_append(output, P_Access_Network_Info->value, tsk_strlen(P_Access_Network_Info->value)); + } + return 0; + } + + return -1; +} + +tsip_header_P_Access_Network_Info_t *tsip_header_P_Access_Network_Info_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsip_header_P_Access_Network_Info_t *hdr_ani = tsip_header_P_Access_Network_Info_create_null(); + + const char *tag_start = tsk_null; + + %%write data; + (void)(eof); + (void)(tsip_machine_parser_header_P_Access_Network_Info_first_final); + (void)(tsip_machine_parser_header_P_Access_Network_Info_error); + (void)(tsip_machine_parser_header_P_Access_Network_Info_en_main); + %%write init; + %%write exec; + + if( cs < %%{ write first_final; }%% ){ + TSK_DEBUG_ERROR("Failed to parse 'P-Access-Network-Info' header."); + TSK_OBJECT_SAFE_FREE(hdr_ani); + } + + return hdr_ani; +} + + + + + + + +//======================================================== +// P_Access_Network_Info header object definition +// + +static tsk_object_t* tsip_header_P_Access_Network_Info_ctor(tsk_object_t *self, va_list * app) +{ + tsip_header_P_Access_Network_Info_t *P_Access_Network_Info = self; + if(P_Access_Network_Info){ + P_Access_Network_Info->value = tsk_strdup(va_arg(*app, const char *)); + TSIP_HEADER(P_Access_Network_Info)->type = tsip_htype_P_Access_Network_Info; + TSIP_HEADER(P_Access_Network_Info)->serialize = tsip_header_P_Access_Network_Info_serialize; + } + else{ + TSK_DEBUG_ERROR("Failed to create new P_Access_Network_Info header."); + } + return self; +} + +static tsk_object_t* tsip_header_P_Access_Network_Info_dtor(tsk_object_t *self) +{ + tsip_header_P_Access_Network_Info_t *P_Access_Network_Info = self; + if(P_Access_Network_Info){ + TSK_FREE(P_Access_Network_Info->value); + } + else{ + TSK_DEBUG_ERROR("Null P_Access_Network_Info header."); + } + + return self; +} + +static const tsk_object_def_t tsip_header_P_Access_Network_Info_def_s = +{ + sizeof(tsip_header_P_Access_Network_Info_t), + tsip_header_P_Access_Network_Info_ctor, + tsip_header_P_Access_Network_Info_dtor, + tsk_null +}; +const tsk_object_def_t *tsip_header_P_Access_Network_Info_def_t = &tsip_header_P_Access_Network_Info_def_s; diff --git a/tinySIP/ragel/tsip_parser_header_P_Answer_State.rl b/tinySIP/ragel/tsip_parser_header_P_Answer_State.rl new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_P_Answer_State.rl @@ -0,0 +1 @@ + diff --git a/tinySIP/ragel/tsip_parser_header_P_Asserted_Identity.rl b/tinySIP/ragel/tsip_parser_header_P_Asserted_Identity.rl new file mode 100644 index 0000000..9f61e70 --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_P_Asserted_Identity.rl @@ -0,0 +1,200 @@ +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* DOUBANGO is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with DOUBANGO. +* +*/ + +/**@file tsip_header_P_Asserted_Identity.c + * @brief SIP P-Asserted-Identity header as per RFC 3325. + * + * @author Mamadou Diop + * + + */ +#include "tinysip/headers/tsip_header_P_Asserted_Identity.h" + +#include "tinysip/parsers/tsip_parser_uri.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" +#include "tsk_time.h" + +#include + + + +/*********************************** +* Ragel state machine. +*/ +%%{ + machine tsip_machine_parser_header_P_Asserted_Identity; + + # Includes + include tsip_machine_utils "./ragel/tsip_machine_utils.rl"; + + action tag{ + tag_start = p; + } + + action create_p_asserted_identity{ + if(!curr_p_asserted_identity){ + curr_p_asserted_identity = tsip_header_P_Asserted_Identity_create(); + } + } + + action parse_display_name{ + if(curr_p_asserted_identity){ + TSK_PARSER_SET_STRING(curr_p_asserted_identity->display_name); + tsk_strunquote(&curr_p_asserted_identity->display_name); + } + } + + action parse_uri{ + if(curr_p_asserted_identity && !curr_p_asserted_identity->uri){ + int len = (int)(p - tag_start); + if(curr_p_asserted_identity && !curr_p_asserted_identity->uri){ + if((curr_p_asserted_identity->uri = tsip_uri_parse(tag_start, (tsk_size_t)len)) && curr_p_asserted_identity->display_name){ + curr_p_asserted_identity->uri->display_name = tsk_strdup(curr_p_asserted_identity->display_name); + } + } + } + } + + action add_p_asserted_identity{ + if(curr_p_asserted_identity){ + tsk_list_push_back_data(hdr_p_asserted_identities, ((void**) &curr_p_asserted_identity)); + } + } + + action eob{ + } + + + URI = (scheme HCOLON any+)>tag %parse_uri; + display_name = (( token LWS )+ | quoted_string)>tag %parse_display_name; + my_name_addr = display_name? :>LAQUOT<: URI :>RAQUOT; + + PAssertedID_value = (my_name_addr | URI) >create_p_asserted_identity %add_p_asserted_identity; + PAssertedID = "P-Asserted-Identity"i HCOLON PAssertedID_value ( COMMA PAssertedID_value )*; + P_Asserted_Identity = PAssertedID; + + # Entry point + main := P_Asserted_Identity :>CRLF @eob; + +}%% + +tsip_header_P_Asserted_Identity_t* tsip_header_P_Asserted_Identity_create() +{ + return tsk_object_new(tsip_header_P_Asserted_Identity_def_t); +} + +int tsip_header_P_Asserted_Identity_serialize(const tsip_header_t* header, tsk_buffer_t* output) +{ + if(header){ + const tsip_header_P_Asserted_Identity_t *P_Asserted_Identity = (const tsip_header_P_Asserted_Identity_t *)header; + int ret = 0; + + /* Uri with hacked display-name*/ + if((ret = tsip_uri_serialize(P_Asserted_Identity->uri, tsk_true, tsk_true, output))){ + return ret; + } + + return ret; + } + + return -1; +} + +tsip_header_P_Asserted_Identities_L_t *tsip_header_P_Asserted_Identity_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsip_header_P_Asserted_Identities_L_t *hdr_p_asserted_identities = tsk_list_create(); + + const char *tag_start = tsk_null; + tsip_header_P_Asserted_Identity_t *curr_p_asserted_identity = 0; + + %%write data; + (void)(eof); + (void)(tsip_machine_parser_header_P_Asserted_Identity_first_final); + (void)(tsip_machine_parser_header_P_Asserted_Identity_error); + (void)(tsip_machine_parser_header_P_Asserted_Identity_en_main); + %%write init; + %%write exec; + + if( cs < %%{ write first_final; }%% ){ + TSK_DEBUG_ERROR("Failed to parse 'P-Asserted-Identity' header."); + TSK_OBJECT_SAFE_FREE(curr_p_asserted_identity); + TSK_OBJECT_SAFE_FREE(hdr_p_asserted_identities); + } + + return hdr_p_asserted_identities; +} + + + + + +//======================================================== +// P_Asserted_Identity header object definition +// + +/**@ingroup tsip_header_P_Asserted_Identity_group +*/ +static tsk_object_t* tsip_header_P_Asserted_Identity_ctor(tsk_object_t *self, va_list * app) +{ + tsip_header_P_Asserted_Identity_t *P_Asserted_Identity = self; + if(P_Asserted_Identity){ + TSIP_HEADER(P_Asserted_Identity)->type = tsip_htype_P_Asserted_Identity; + TSIP_HEADER(P_Asserted_Identity)->serialize = tsip_header_P_Asserted_Identity_serialize; + } + else{ + TSK_DEBUG_ERROR("Failed to create new P_Asserted_Identity header."); + } + return self; +} + +/**@ingroup tsip_header_P_Asserted_Identity_group +*/ +static tsk_object_t* tsip_header_P_Asserted_Identity_dtor(tsk_object_t *self) +{ + tsip_header_P_Asserted_Identity_t *P_Asserted_Identity = self; + if(P_Asserted_Identity){ + TSK_FREE(P_Asserted_Identity->display_name); + TSK_OBJECT_SAFE_FREE(P_Asserted_Identity->uri); + + TSK_OBJECT_SAFE_FREE(TSIP_HEADER_PARAMS(P_Asserted_Identity)); + } + else{ + TSK_DEBUG_ERROR("Null P_Asserted_Identity header."); + } + + return self; +} + +static const tsk_object_def_t tsip_header_P_Asserted_Identity_def_s = +{ + sizeof(tsip_header_P_Asserted_Identity_t), + tsip_header_P_Asserted_Identity_ctor, + tsip_header_P_Asserted_Identity_dtor, + tsk_null +}; +const tsk_object_def_t *tsip_header_P_Asserted_Identity_def_t = &tsip_header_P_Asserted_Identity_def_s; diff --git a/tinySIP/ragel/tsip_parser_header_P_Associated_URI.rl b/tinySIP/ragel/tsip_parser_header_P_Associated_URI.rl new file mode 100644 index 0000000..5fb4afd --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_P_Associated_URI.rl @@ -0,0 +1,212 @@ +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* DOUBANGO is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with DOUBANGO. +* +*/ + +/**@file tsip_header_P_Associated_URI.c + * @brief SIP P-Associated-URI header as per RFC 3455. + * + * @author Mamadou Diop + * + + */ +#include "tinysip/headers/tsip_header_P_Associated_URI.h" + +#include "tinysip/parsers/tsip_parser_uri.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" +#include "tsk_time.h" + +#include + + + +/*********************************** +* Ragel state machine. +*/ +%%{ + machine tsip_machine_parser_header_P_Associated_URI; + + # Includes + include tsip_machine_utils "./ragel/tsip_machine_utils.rl"; + + action tag{ + tag_start = p; + } + + action create_p_associated_uri{ + if(!curr_p_associated_uri){ + curr_p_associated_uri = tsip_header_P_Associated_URI_create_null(); + } + } + + action parse_display_name{ + if(curr_p_associated_uri){ + TSK_PARSER_SET_STRING(curr_p_associated_uri->display_name); + tsk_strunquote(&curr_p_associated_uri->display_name); + } + } + + action parse_uri{ + if(curr_p_associated_uri && !curr_p_associated_uri->uri){ + int len = (int)(p - tag_start); + if(curr_p_associated_uri && !curr_p_associated_uri->uri){ + if((curr_p_associated_uri->uri = tsip_uri_parse(tag_start, (tsk_size_t)len)) && curr_p_associated_uri->display_name){ + curr_p_associated_uri->uri->display_name = tsk_strdup(curr_p_associated_uri->display_name); + } + } + } + } + + action parse_param{ + if(curr_p_associated_uri){ + TSK_PARSER_ADD_PARAM(TSIP_HEADER_PARAMS(curr_p_associated_uri)); + } + } + + action add_p_associated_uri{ + if(curr_p_associated_uri){ + tsk_list_push_back_data(hdr_p_associated_uris, ((void**) &curr_p_associated_uri)); + } + } + + action eob{ + } + + + URI = (scheme HCOLON any+)>tag %parse_uri; + display_name = (( token LWS )+ | quoted_string)>tag %parse_display_name; + my_name_addr = display_name? :>LAQUOT<: URI :>RAQUOT; + + ai_param = (generic_param)>tag %parse_param; + p_aso_uri_spec = (my_name_addr ( SEMI ai_param )*) >create_p_associated_uri %add_p_associated_uri; + P_Associated_URI = "P-Associated-URI"i HCOLON p_aso_uri_spec ( COMMA p_aso_uri_spec )*; + + # Entry point + main := P_Associated_URI :>CRLF @eob; + +}%% + +tsip_header_P_Associated_URI_t* tsip_header_P_Associated_URI_create(const tsip_uri_t* uri) +{ + return tsk_object_new(TSIP_HEADER_P_ASSOCIATED_URI_VA_ARGS(uri)); +} + +tsip_header_P_Associated_URI_t* tsip_header_P_Associated_URI_create_null() +{ + return tsip_header_P_Associated_URI_create(tsk_null); +} + +int tsip_header_P_Associated_URI_serialize(const tsip_header_t* header, tsk_buffer_t* output) +{ + if(header){ + const tsip_header_P_Associated_URI_t *P_Associated_URI = (const tsip_header_P_Associated_URI_t *)header; + int ret = 0; + + /* Uri with hacked display-name*/ + if((ret = tsip_uri_serialize(P_Associated_URI->uri, tsk_true, tsk_true, output))){ + return ret; + } + + return ret; + } + + return -1; +} + +tsip_header_P_Associated_URIs_L_t *tsip_header_P_Associated_URI_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsip_header_P_Associated_URIs_L_t *hdr_p_associated_uris = tsk_list_create(); + + const char *tag_start = tsk_null; + tsip_header_P_Associated_URI_t *curr_p_associated_uri = tsk_null; + + %%write data; + (void)(eof); + (void)(tsip_machine_parser_header_P_Associated_URI_first_final); + (void)(tsip_machine_parser_header_P_Associated_URI_error); + (void)(tsip_machine_parser_header_P_Associated_URI_en_main); + %%write init; + %%write exec; + + if( cs < %%{ write first_final; }%% ){ + TSK_DEBUG_ERROR("Failed to parse 'P-Associated-URI' header."); + TSK_OBJECT_SAFE_FREE(curr_p_associated_uri); + TSK_OBJECT_SAFE_FREE(hdr_p_associated_uris); + } + + return hdr_p_associated_uris; +} + + + + + +//======================================================== +// P_Associated_URI header object definition +// + +static tsk_object_t* tsip_header_P_Associated_URI_ctor(tsk_object_t *self, va_list * app) +{ + tsip_header_P_Associated_URI_t *P_Associated_URI = self; + if(P_Associated_URI){ + const tsip_uri_t* uri = va_arg(*app, const tsip_uri_t*); + + TSIP_HEADER(P_Associated_URI)->type = tsip_htype_P_Associated_URI; + TSIP_HEADER(P_Associated_URI)->serialize = tsip_header_P_Associated_URI_serialize; + if(uri){ + P_Associated_URI->uri = tsk_object_ref((void*)uri); + } + } + else{ + TSK_DEBUG_ERROR("Failed to create new P_Associated_URI header."); + } + return self; +} + +static tsk_object_t* tsip_header_P_Associated_URI_dtor(tsk_object_t *self) +{ + tsip_header_P_Associated_URI_t *P_Associated_URI = self; + if(P_Associated_URI){ + TSK_FREE(P_Associated_URI->display_name); + TSK_OBJECT_SAFE_FREE(P_Associated_URI->uri); + + TSK_OBJECT_SAFE_FREE(TSIP_HEADER_PARAMS(P_Associated_URI)); + } + else{ + TSK_DEBUG_ERROR("Null P_Associated_URI header."); + } + + return self; +} + +static const tsk_object_def_t tsip_header_P_Associated_URI_def_s = +{ + sizeof(tsip_header_P_Associated_URI_t), + tsip_header_P_Associated_URI_ctor, + tsip_header_P_Associated_URI_dtor, + tsk_null +}; +const tsk_object_def_t *tsip_header_P_Associated_URI_def_t = &tsip_header_P_Associated_URI_def_s; diff --git a/tinySIP/ragel/tsip_parser_header_P_Called_Party_ID.rl b/tinySIP/ragel/tsip_parser_header_P_Called_Party_ID.rl new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_P_Called_Party_ID.rl @@ -0,0 +1 @@ + diff --git a/tinySIP/ragel/tsip_parser_header_P_Charging_Function_Addresses.rl b/tinySIP/ragel/tsip_parser_header_P_Charging_Function_Addresses.rl new file mode 100644 index 0000000..429acac --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_P_Charging_Function_Addresses.rl @@ -0,0 +1,195 @@ +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* DOUBANGO is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with DOUBANGO. +* +*/ + +/**@file tsip_header_P_Charging_Function_Addresses.c + * @brief SIP P-Charging-Function-Addresses header as per RFC 3455. + * + * @author Mamadou Diop + * + + */ +#include "tinysip/headers/tsip_header_P_Charging_Function_Addresses.h" + +#include "tinysip/parsers/tsip_parser_uri.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" +#include "tsk_time.h" + +#include + + + +/*********************************** +* Ragel state machine. +*/ +%%{ + machine tsip_machine_parser_header_P_Charging_Function_Addresses; + + # Includes + include tsip_machine_utils "./ragel/tsip_machine_utils.rl"; + + action tag{ + tag_start = p; + } + + action create_p_charging_function_addresses{ + if(!curr_p_charging_function_addresses){ + curr_p_charging_function_addresses = tsip_header_P_Charging_Function_Addresses_create(); + } + } + + action parse_ccf{ + if(!curr_p_charging_function_addresses->ccf){ + TSK_PARSER_SET_STRING(curr_p_charging_function_addresses->ccf); + } + } + + action parse_ecf{ + if(!curr_p_charging_function_addresses->ecf){ + TSK_PARSER_SET_STRING(curr_p_charging_function_addresses->ecf); + } + } + + action parse_param{ + if(curr_p_charging_function_addresses){ + TSK_PARSER_ADD_PARAM(TSIP_HEADER_PARAMS(curr_p_charging_function_addresses)); + } + } + + action add_p_charging_function_addresses{ + if(curr_p_charging_function_addresses){ + tsk_list_push_back_data(hdr_p_charging_function_addressess, ((void**) &curr_p_charging_function_addresses)); + } + } + + action eob{ + } + + ccf = "ccf"i EQUAL gen_value; + ecf = "ecf"i EQUAL gen_value; + charge_addr_params = (ccf>tag %parse_ccf | ecf>tag %parse_ecf | generic_param>tag %parse_param) >create_p_charging_function_addresses %add_p_charging_function_addresses; + P_Charging_Addr = "P-Charging-Function-Addresses"i HCOLON charge_addr_params ( SEMI charge_addr_params )*; + P_Charging_Function_Addresses = P_Charging_Addr; + + # Entry point + main := P_Charging_Function_Addresses :>CRLF @eob; + +}%% + + +tsip_header_P_Charging_Function_Addresses_t* tsip_header_P_Charging_Function_Addresses_create() +{ + return tsk_object_new(tsip_header_P_Charging_Function_Addresses_def_t); +} + +int tsip_header_P_Charging_Function_Addresses_serialize(const tsip_header_t* header, tsk_buffer_t* output) +{ + if(header){ + const tsip_header_P_Charging_Function_Addresses_t *P_Charging_Function_Addresses = (const tsip_header_P_Charging_Function_Addresses_t *)header; + return tsk_buffer_append_2(output, "%s%s%s%s%s", + P_Charging_Function_Addresses->ecf ? "ecf=" : "", + P_Charging_Function_Addresses->ecf ? P_Charging_Function_Addresses->ecf : "", + + (P_Charging_Function_Addresses->ecf && P_Charging_Function_Addresses->ccf) ? ";" : "", + + P_Charging_Function_Addresses->ccf ? "ccf=" : "", + P_Charging_Function_Addresses->ccf ? P_Charging_Function_Addresses->ccf : "" + ); + } + + return -1; +} + +tsip_header_P_Charging_Function_Addressess_L_t *tsip_header_P_Charging_Function_Addresses_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsip_header_P_Charging_Function_Addressess_L_t *hdr_p_charging_function_addressess = tsk_list_create(); + + const char *tag_start = tsk_null; + tsip_header_P_Charging_Function_Addresses_t *curr_p_charging_function_addresses = 0; + + %%write data; + (void)(eof); + (void)(tsip_machine_parser_header_P_Charging_Function_Addresses_first_final); + (void)(tsip_machine_parser_header_P_Charging_Function_Addresses_error); + (void)(tsip_machine_parser_header_P_Charging_Function_Addresses_en_main); + %%write init; + %%write exec; + + if( cs < %%{ write first_final; }%% ){ + TSK_DEBUG_ERROR("Failed to parse 'P-Charging-Function-Addresses' header."); + TSK_OBJECT_SAFE_FREE(curr_p_charging_function_addresses); + TSK_OBJECT_SAFE_FREE(hdr_p_charging_function_addressess); + } + + return hdr_p_charging_function_addressess; +} + + + + + +//======================================================== +// P_Charging_Function_Addresses header object definition +// + +static tsk_object_t* tsip_header_P_Charging_Function_Addresses_ctor(tsk_object_t *self, va_list * app) +{ + tsip_header_P_Charging_Function_Addresses_t *P_Charging_Function_Addresses = self; + if(P_Charging_Function_Addresses){ + TSIP_HEADER(P_Charging_Function_Addresses)->type = tsip_htype_P_Charging_Function_Addresses; + TSIP_HEADER(P_Charging_Function_Addresses)->serialize = tsip_header_P_Charging_Function_Addresses_serialize; + } + else{ + TSK_DEBUG_ERROR("Failed to create new P_Charging_Function_Addresses header."); + } + return self; +} + +static tsk_object_t* tsip_header_P_Charging_Function_Addresses_dtor(tsk_object_t *self) +{ + tsip_header_P_Charging_Function_Addresses_t *P_Charging_Function_Addresses = self; + if(P_Charging_Function_Addresses){ + TSK_FREE(P_Charging_Function_Addresses->ecf); + TSK_FREE(P_Charging_Function_Addresses->ccf); + + TSK_OBJECT_SAFE_FREE(TSIP_HEADER_PARAMS(P_Charging_Function_Addresses)); + } + else{ + TSK_DEBUG_ERROR("Null P_Charging_Function_Addresses header."); + } + + return self; +} + +static const tsk_object_def_t tsip_header_P_Charging_Function_Addresses_def_s = +{ + sizeof(tsip_header_P_Charging_Function_Addresses_t), + tsip_header_P_Charging_Function_Addresses_ctor, + tsip_header_P_Charging_Function_Addresses_dtor, + tsk_null +}; +const tsk_object_def_t *tsip_header_P_Charging_Function_Addresses_def_t = &tsip_header_P_Charging_Function_Addresses_def_s; diff --git a/tinySIP/ragel/tsip_parser_header_P_Charging_Vector.rl b/tinySIP/ragel/tsip_parser_header_P_Charging_Vector.rl new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_P_Charging_Vector.rl @@ -0,0 +1 @@ + diff --git a/tinySIP/ragel/tsip_parser_header_P_DCS_Billing_Info.rl b/tinySIP/ragel/tsip_parser_header_P_DCS_Billing_Info.rl new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_P_DCS_Billing_Info.rl @@ -0,0 +1 @@ + diff --git a/tinySIP/ragel/tsip_parser_header_P_DCS_LAES.rl b/tinySIP/ragel/tsip_parser_header_P_DCS_LAES.rl new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_P_DCS_LAES.rl @@ -0,0 +1 @@ + diff --git a/tinySIP/ragel/tsip_parser_header_P_DCS_OSPS.rl b/tinySIP/ragel/tsip_parser_header_P_DCS_OSPS.rl new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_P_DCS_OSPS.rl @@ -0,0 +1 @@ + diff --git a/tinySIP/ragel/tsip_parser_header_P_DCS_Redirect.rl b/tinySIP/ragel/tsip_parser_header_P_DCS_Redirect.rl new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_P_DCS_Redirect.rl @@ -0,0 +1 @@ + diff --git a/tinySIP/ragel/tsip_parser_header_P_DCS_Trace_Party_ID.rl b/tinySIP/ragel/tsip_parser_header_P_DCS_Trace_Party_ID.rl new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_P_DCS_Trace_Party_ID.rl @@ -0,0 +1 @@ + diff --git a/tinySIP/ragel/tsip_parser_header_P_Early_Media.rl b/tinySIP/ragel/tsip_parser_header_P_Early_Media.rl new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_P_Early_Media.rl @@ -0,0 +1 @@ + diff --git a/tinySIP/ragel/tsip_parser_header_P_Media_Authorization.rl b/tinySIP/ragel/tsip_parser_header_P_Media_Authorization.rl new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_P_Media_Authorization.rl @@ -0,0 +1 @@ + diff --git a/tinySIP/ragel/tsip_parser_header_P_Preferred_Identity.rl b/tinySIP/ragel/tsip_parser_header_P_Preferred_Identity.rl new file mode 100644 index 0000000..03e1720 --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_P_Preferred_Identity.rl @@ -0,0 +1,198 @@ +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* DOUBANGO is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with DOUBANGO. +* +*/ + +/**@file tsip_header_P_Preferred_Identity.c + * @brief SIP P-Preferred-Identity header as per RFC 3325. + * Header field where proxy ACK BYE CAN INV OPT REG + * ------------ ----- ----- --- --- --- --- --- --- + * P-Preferred-Identity adr - o - o o - + * + * + * SUB NOT REF INF UPD PRA + * --- --- --- --- --- --- + * o o o - - - + * + * @author Mamadou Diop + * + + */ +#include "tinysip/headers/tsip_header_P_Preferred_Identity.h" + +#include "tinysip/parsers/tsip_parser_uri.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" + + + +/*********************************** +* Ragel state machine. +*/ +%%{ + machine tsip_machine_parser_header_P_Preferred_Identity; + + # Includes + include tsip_machine_utils "./ragel/tsip_machine_utils.rl"; + + action tag{ + tag_start = p; + } + + action parse_uri{ + if(!hdr_pi->uri) /* Only one URI */{ + int len = (int)(p - tag_start); + if(hdr_pi && !hdr_pi->uri){ + if((hdr_pi->uri = tsip_uri_parse(tag_start, (tsk_size_t)len)) && hdr_pi->display_name){ + hdr_pi->uri->display_name = tsk_strdup(hdr_pi->display_name); + } + } + } + } + + action parse_display_name{ + if(!hdr_pi->display_name){ + TSK_PARSER_SET_STRING(hdr_pi->display_name); + tsk_strunquote(&hdr_pi->display_name); + } + + } + + action eob{ + } + + #/* FIXME: Only one URI is added --> According to the ABNF the header could have more than one URI. */ + + URI = (scheme HCOLON any+)>tag %parse_uri; + display_name = (( token LWS )+ | quoted_string)>tag %parse_display_name; + my_name_addr = display_name? :>LAQUOT<: URI :>RAQUOT; + + PPreferredID_value = (my_name_addr)>0 | (URI)>1; + PPreferredID = "P-Preferred-Identity"i HCOLON PPreferredID_value>1 ( COMMA PPreferredID_value )*>0; + + # Entry point + main := PPreferredID :>CRLF @eob; + +}%% + + +tsip_header_P_Preferred_Identity_t* tsip_header_P_Preferred_Identity_create(const tsip_uri_t* uri) +{ + return tsk_object_new(TSIP_HEADER_P_PREFERRED_IDENTITY_VA_ARGS(uri)); +} + +tsip_header_P_Preferred_Identity_t* tsip_header_P_Preferred_Identity_create_null() +{ + return tsip_header_P_Preferred_Identity_create(tsk_null); +} + +int tsip_header_Preferred_Identity_serialize(const tsip_header_t* header, tsk_buffer_t* output) +{ + if(header){ + int ret; + const tsip_header_P_Preferred_Identity_t *P_Preferred_Identity = (const tsip_header_P_Preferred_Identity_t *)header; + + /* Uri with hacked display-name*/ + if((ret = tsip_uri_serialize(P_Preferred_Identity->uri, tsk_true, tsk_true, output))){ + return ret; + } + return ret; + } + return -1; +} + +tsip_header_P_Preferred_Identity_t *tsip_header_P_Preferred_Identity_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsip_header_P_Preferred_Identity_t *hdr_pi = tsip_header_P_Preferred_Identity_create_null(); + + const char *tag_start = tsk_null; + + %%write data; + (void)(eof); + (void)(tsip_machine_parser_header_P_Preferred_Identity_first_final); + (void)(tsip_machine_parser_header_P_Preferred_Identity_error); + (void)(tsip_machine_parser_header_P_Preferred_Identity_en_main); + %%write init; + %%write exec; + + if( cs < %%{ write first_final; }%% ){ + TSK_DEBUG_ERROR("Failed to parse 'P-Preferred-Identity' header."); + TSK_OBJECT_SAFE_FREE(hdr_pi); + } + + return hdr_pi; +} + + + + + + + +//======================================================== +// P_Preferred_Identity header object definition +// + +static tsk_object_t* tsip_header_P_Preferred_Identity_ctor(tsk_object_t *self, va_list * app) +{ + tsip_header_P_Preferred_Identity_t *P_Preferred_Identity = self; + if(P_Preferred_Identity){ + const tsip_uri_t* uri = va_arg(*app, const tsip_uri_t*); + + TSIP_HEADER(P_Preferred_Identity)->type = tsip_htype_P_Preferred_Identity; + TSIP_HEADER(P_Preferred_Identity)->serialize = tsip_header_Preferred_Identity_serialize; + + if(uri){ + P_Preferred_Identity->uri = tsk_object_ref((void*)uri); + } + } + else{ + TSK_DEBUG_ERROR("Failed to create new P_Preferred_Identity header."); + } + return self; +} + +static tsk_object_t* tsip_header_P_Preferred_Identity_dtor(tsk_object_t *self) +{ + tsip_header_P_Preferred_Identity_t *P_Preferred_Identity = self; + if(P_Preferred_Identity){ + TSK_FREE(P_Preferred_Identity->display_name); + TSK_OBJECT_SAFE_FREE(P_Preferred_Identity->uri); + } + else{ + TSK_DEBUG_ERROR("Null P_Preferred_Identity header."); + } + + return self; +} + +static const tsk_object_def_t tsip_header_P_Preferred_Identity_def_s = +{ + sizeof(tsip_header_P_Preferred_Identity_t), + tsip_header_P_Preferred_Identity_ctor, + tsip_header_P_Preferred_Identity_dtor, + tsk_null +}; +const tsk_object_def_t *tsip_header_P_Preferred_Identity_def_t = &tsip_header_P_Preferred_Identity_def_s; diff --git a/tinySIP/ragel/tsip_parser_header_P_Profile_Key.rl b/tinySIP/ragel/tsip_parser_header_P_Profile_Key.rl new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_P_Profile_Key.rl @@ -0,0 +1 @@ + diff --git a/tinySIP/ragel/tsip_parser_header_P_User_Database.rl b/tinySIP/ragel/tsip_parser_header_P_User_Database.rl new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_P_User_Database.rl @@ -0,0 +1 @@ + diff --git a/tinySIP/ragel/tsip_parser_header_P_Visited_Network_ID.rl b/tinySIP/ragel/tsip_parser_header_P_Visited_Network_ID.rl new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_P_Visited_Network_ID.rl @@ -0,0 +1 @@ + diff --git a/tinySIP/ragel/tsip_parser_header_Path.rl b/tinySIP/ragel/tsip_parser_header_Path.rl new file mode 100644 index 0000000..e4fadad --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_Path.rl @@ -0,0 +1,214 @@ +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* DOUBANGO is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with DOUBANGO. +* +*/ + +/**@file tsip_header_Path.c + * @brief SIP Service-Path header as per RFC 3608. + * + * @author Mamadou Diop + * + + */ +#include "tinysip/headers/tsip_header_Path.h" + +#include "tinysip/parsers/tsip_parser_uri.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" +#include "tsk_time.h" + +#include + + + +/*********************************** +* Ragel state machine. +*/ +%%{ + machine tsip_machine_parser_header_Path; + + # Includes + include tsip_machine_utils "./ragel/tsip_machine_utils.rl"; + + action tag{ + tag_start = p; + } + + action create_path{ + if(!curr_path){ + curr_path = tsip_header_Path_create_null(); + } + } + + action parse_display_name{ + if(curr_path){ + TSK_PARSER_SET_STRING(curr_path->display_name); + tsk_strunquote(&curr_path->display_name); + } + } + + action parse_uri{ + if(curr_path && !curr_path->uri){ + int len = (int)(p - tag_start); + if(curr_path && !curr_path->uri){ + if((curr_path->uri = tsip_uri_parse(tag_start, (tsk_size_t)len)) && curr_path->display_name){ + curr_path->uri->display_name = tsk_strdup(curr_path->display_name); + } + } + } + } + + action parse_param{ + if(curr_path){ + TSK_PARSER_ADD_PARAM(TSIP_HEADER_PARAMS(curr_path)); + } + } + + action add_path{ + if(curr_path){ + tsk_list_push_back_data(hdr_paths, ((void**) &curr_path)); + } + } + + action eob{ + } + + + URI = (scheme HCOLON any+)>tag %parse_uri; + display_name = (( token LWS )+ | quoted_string)>tag %parse_display_name; + my_name_addr = display_name? :>LAQUOT<: URI :>RAQUOT; + + rr_param = (generic_param)>tag %parse_param; + + path_value = (my_name_addr ( SEMI rr_param )*) >create_path %add_path; + Path = "Path" HCOLON path_value (COMMA path_value)*; + + # Entry point + main := Path :>CRLF @eob; + +}%% + + +tsip_header_Path_t* tsip_header_Path_create(const tsip_uri_t* uri) +{ + return tsk_object_new(TSIP_HEADER_PATH_VA_ARGS(uri)); +} + +tsip_header_Path_t* tsip_header_Path_create_null() +{ + return tsip_header_Path_create(tsk_null); +} + +int tsip_header_Path_serialize(const tsip_header_t* header, tsk_buffer_t* output) +{ + if(header){ + const tsip_header_Path_t *Path = (const tsip_header_Path_t *)header; + int ret = 0; + + /* Uri with hacked display-name*/ + if((ret = tsip_uri_serialize(Path->uri, tsk_true, tsk_true, output))){ + return ret; + } + + return ret; + } + + return -1; +} + +tsip_header_Paths_L_t *tsip_header_Path_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsip_header_Paths_L_t *hdr_paths = tsk_list_create(); + + const char *tag_start = tsk_null; + tsip_header_Path_t *curr_path = tsk_null; + + %%write data; + (void)(eof); + (void)(tsip_machine_parser_header_Path_first_final); + (void)(tsip_machine_parser_header_Path_error); + (void)(tsip_machine_parser_header_Path_en_main); + %%write init; + %%write exec; + + if( cs < %%{ write first_final; }%% ){ + TSK_DEBUG_ERROR("Failed to parse 'Path' header."); + TSK_OBJECT_SAFE_FREE(curr_path); + TSK_OBJECT_SAFE_FREE(hdr_paths); + } + + return hdr_paths; +} + + + + + +//======================================================== +// Path header object definition +// + +static tsk_object_t* tsip_header_Path_ctor(tsk_object_t *self, va_list * app) +{ + tsip_header_Path_t *Path = self; + if(Path){ + const tsip_uri_t* uri = va_arg(*app, const tsip_uri_t*); + + TSIP_HEADER(Path)->type = tsip_htype_Path; + TSIP_HEADER(Path)->serialize = tsip_header_Path_serialize; + if(uri){ + Path->uri = tsk_object_ref((void*)uri); + } + } + else{ + TSK_DEBUG_ERROR("Failed to create new Path header."); + } + return self; +} + +static tsk_object_t* tsip_header_Path_dtor(tsk_object_t *self) +{ + tsip_header_Path_t *Path = self; + if(Path){ + TSK_FREE(Path->display_name); + TSK_OBJECT_SAFE_FREE(Path->uri); + + TSK_OBJECT_SAFE_FREE(TSIP_HEADER_PARAMS(Path)); + } + else{ + TSK_DEBUG_ERROR("Null Path header."); + } + + return self; +} + +static const tsk_object_def_t tsip_header_Path_def_s = +{ + sizeof(tsip_header_Path_t), + tsip_header_Path_ctor, + tsip_header_Path_dtor, + tsk_null +}; +const tsk_object_def_t *tsip_header_Path_def_t = &tsip_header_Path_def_s; diff --git a/tinySIP/ragel/tsip_parser_header_Priority.rl b/tinySIP/ragel/tsip_parser_header_Priority.rl new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_Priority.rl @@ -0,0 +1 @@ + diff --git a/tinySIP/ragel/tsip_parser_header_Privacy.rl b/tinySIP/ragel/tsip_parser_header_Privacy.rl new file mode 100644 index 0000000..75e7ade --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_Privacy.rl @@ -0,0 +1,176 @@ +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* DOUBANGO is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with DOUBANGO. +* +*/ + +/**@file tsip_header_Privacy.c + * @brief SIP Privacy header. + * + * Header field where proxy ACK BYE CAN INV OPT REG + * ___________________________________________________________ + * Privacy amrd o o o o o o + * + * Header field SUB NOT PRK IFO UPD MSG + * ___________________________________________________________ + * Privacy o o o o o o + * + * @author Mamadou Diop + * + + */ +#include "tinysip/headers/tsip_header_Privacy.h" + +#include "tinysip/parsers/tsip_parser_uri.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" + +#include + + + +/*********************************** +* Ragel state machine. +*/ +%%{ + machine tsip_machine_parser_header_Privacy; + + # Includes + include tsip_machine_utils "./ragel/tsip_machine_utils.rl"; + + action tag{ + tag_start = p; + } + + action parse_priv_value{ + TSK_PARSER_ADD_STRING(hdr_privacy->values); + } + + action eob{ + } + + priv_value = ("header"i | "session"i | "user"i | "none"i | "critical"i | "id"i | "history"i)@1 | token@0; + Privacy_hdr = "Privacy"i HCOLON priv_value>tag %parse_priv_value ( ";" priv_value>tag %parse_priv_value )*; + + # Entry point + main := Privacy_hdr :>CRLF @eob; + +}%% + +tsip_header_Privacy_t* tsip_header_Privacy_create() +{ + return tsk_object_new(tsip_header_Privacy_def_t); +} + +int tsip_header_Privacy_serialize(const tsip_header_t* header, tsk_buffer_t* output) +{ + if(header){ + const tsip_header_Privacy_t *Privacy = (const tsip_header_Privacy_t *)header; + tsk_list_item_t *item; + tsk_string_t *str; + int ret = 0; + + tsk_list_foreach(item, Privacy->values){ + str = item->data; + if(item == Privacy->values->head){ + ret = tsk_buffer_append(output, str->value, tsk_strlen(str->value)); + } + else{ + ret = tsk_buffer_append_2(output, ";%s", str->value); + } + } + + return ret; + } + + return -1; +} + + +tsip_header_Privacy_t *tsip_header_Privacy_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsip_header_Privacy_t *hdr_privacy = tsip_header_Privacy_create(); + + const char *tag_start = tsk_null; + + %%write data; + (void)(eof); + (void)(tsip_machine_parser_header_Privacy_first_final); + (void)(tsip_machine_parser_header_Privacy_error); + (void)(tsip_machine_parser_header_Privacy_en_main); + %%write init; + %%write exec; + + if( cs < %%{ write first_final; }%% ){ + TSK_DEBUG_ERROR("Failed to parse 'Privacy' header."); + TSK_OBJECT_SAFE_FREE(hdr_privacy); + } + + return hdr_privacy; +} + + + + + + + +//======================================================== +// Privacy header object definition +// + +static tsk_object_t* tsip_header_Privacy_ctor(tsk_object_t *self, va_list * app) +{ + tsip_header_Privacy_t *Privacy = self; + if(Privacy){ + TSIP_HEADER(Privacy)->type = tsip_htype_Privacy; + TSIP_HEADER(Privacy)->serialize = tsip_header_Privacy_serialize; + } + else{ + TSK_DEBUG_ERROR("Failed to create new Privacy header."); + } + return self; +} + +static tsk_object_t* tsip_header_Privacy_dtor(tsk_object_t *self) +{ + tsip_header_Privacy_t *Privacy = self; + if(Privacy){ + TSK_OBJECT_SAFE_FREE(Privacy->values); + } + else{ + TSK_DEBUG_ERROR("Null Privacy header."); + } + + return self; +} + +static const tsk_object_def_t tsip_header_Privacy_def_s = +{ + sizeof(tsip_header_Privacy_t), + tsip_header_Privacy_ctor, + tsip_header_Privacy_dtor, + tsk_null +}; +const tsk_object_def_t *tsip_header_Privacy_def_t = &tsip_header_Privacy_def_s; diff --git a/tinySIP/ragel/tsip_parser_header_Proxy_Authenticate.rl b/tinySIP/ragel/tsip_parser_header_Proxy_Authenticate.rl new file mode 100644 index 0000000..0a8de4c --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_Proxy_Authenticate.rl @@ -0,0 +1,245 @@ +///* +//* Copyright (C) 2010-2011 Mamadou Diop. +//* +//* Contact: Mamadou Diop +//* +//* This file is part of Open Source Doubango Framework. +//* +//* DOUBANGO is free software: you can redistribute it and/or modify +//* it under the terms of the GNU General Public License as published by +//* the Free Software Foundation, either version 3 of the License, or +//* (at your option) any later version. +//* +//* DOUBANGO is distributed in the hope that it will be useful, +//* but WITHOUT ANY WARRANTY; without even the implied warranty of +//* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +//* GNU General Public License for more details. +//* +//* You should have received a copy of the GNU General Public License +//* along with DOUBANGO. +//* +//*/ +// +///**@file tsip_header_Proxy_Authenticate.c +// * @brief SIP Proxy-Authenticate header. +// * +// * @author Mamadou Diop +// * +// +// */ +//#include "tinysip/headers/tsip_header_Proxy_Authenticate.h" +// +//#include "tinysip/parsers/tsip_parser_uri.h" +// +//#include "tsk_debug.h" +//#include "tsk_memory.h" +//#include "tsk_time.h" +// +//#include +// + +// +///*********************************** +//* Ragel state machine. +//*/ +//%%{ +// machine tsip_machine_parser_header_Proxy_Authenticate; +// +// # Includes +// include tsip_machine_utils "./ragel/tsip_machine_utils.rl"; +// +// action tag +// { +// tag_start = p; +// } +// +// action is_digest +// { +// #//FIXME: Only Digest is supported +// hdr_Proxy_Authenticate->scheme = tsk_strdup("Digest"); +// } +// +// action parse_realm +// { +// TSK_PARSER_SET_STRING(hdr_Proxy_Authenticate->realm); +// tsk_strunquote(&hdr_Proxy_Authenticate->realm); +// } +// +// action parse_domain +// { +// TSK_PARSER_SET_STRING(hdr_Proxy_Authenticate->domain); +// //tsk_strunquote(&hdr_Proxy_Authenticate->domain); +// } +// +// action parse_nonce +// { +// TSK_PARSER_SET_STRING(hdr_Proxy_Authenticate->nonce); +// tsk_strunquote(&hdr_Proxy_Authenticate->nonce); +// } +// +// action parse_opaque +// { +// TSK_PARSER_SET_STRING(hdr_Proxy_Authenticate->opaque); +// tsk_strunquote(&hdr_Proxy_Authenticate->opaque); +// } +// +// action parse_stale +// { +// hdr_Proxy_Authenticate->stale = tsk_strniequals(tag_start, "true", 4); +// } +// +// action parse_algorithm +// { +// TSK_PARSER_SET_STRING(hdr_Proxy_Authenticate->algorithm); +// } +// +// action parse_qop +// { +// TSK_PARSER_SET_STRING(hdr_Proxy_Authenticate->qop); +// //tsk_strunquote(&hdr_Proxy_Authenticate->qop); +// } +// +// action parse_param +// { +// TSK_PARSER_ADD_PARAM(TSIP_HEADER_PARAMS(hdr_Proxy_Authenticate)); +// } +// +// action eob +// { +// } +// +// #FIXME: Only Digest (MD5, AKAv1-MD5 and AKAv2-MD5) is supported +// other_challenge = (any+); +// auth_param = generic_param>tag %parse_param; +// +// realm = "realm"i EQUAL quoted_string>tag %parse_realm; +// domain = "domain"i EQUAL LDQUOT <: (any*)>tag %parse_domain :> RDQUOT; +// nonce = "nonce"i EQUAL quoted_string>tag %parse_nonce; +// opaque = "opaque"i EQUAL quoted_string>tag %parse_opaque; +// stale = "stale"i EQUAL ( "true"i | "false"i )>tag %parse_stale; +// algorithm = "algorithm"i EQUAL <:token>tag %parse_algorithm; +// qop_options = "qop"i EQUAL LDQUOT <: (any*)>tag %parse_qop :> RDQUOT; +// +// digest_cln = (realm | domain | nonce | opaque | stale | algorithm | qop_options)@1 | auth_param@0; +// challenge = ( "Digest"i LWS digest_cln ( COMMA digest_cln )* )>is_digest | other_challenge; +// Proxy_Authenticate = "Proxy-Authenticate"i HCOLON challenge; +// +// # Entry point +// main := Proxy_Authenticate :>CRLF @eob; +// +//}%% +// +//int tsip_header_Proxy_Authenticate_serialize(const tsip_header_t* header, tsk_buffer_t* output) +//{ +// if(header) +// { +// const tsip_header_Proxy_Authenticate_t *Proxy_Authenticate = header; +// if(Proxy_Authenticate && Proxy_Authenticate->scheme) +// { +// return tsk_buffer_append_2(output, "%s realm=\"%s\"%s%s%s%s%s%s%s%s%s%s%s%s,stale=%s%s%s", +// Proxy_Authenticate->scheme, +// Proxy_Authenticate->realm ? Proxy_Authenticate->realm : "", +// +// Proxy_Authenticate->domain ? ",domain=\"" : "", +// Proxy_Authenticate->domain ? Proxy_Authenticate->domain : "", +// Proxy_Authenticate->domain ? "\"" : "", +// +// +// Proxy_Authenticate->qop ? ",qop=\"" : "", +// Proxy_Authenticate->qop ? Proxy_Authenticate->qop : "", +// Proxy_Authenticate->qop ? "\"" : "", +// +// +// Proxy_Authenticate->nonce ? ",nonce=\"" : "", +// Proxy_Authenticate->nonce ? Proxy_Authenticate->nonce : "", +// Proxy_Authenticate->nonce ? "\"" : "", +// +// Proxy_Authenticate->opaque ? ",opaque=\"" : "", +// Proxy_Authenticate->opaque ? Proxy_Authenticate->opaque : "", +// Proxy_Authenticate->opaque ? "\"" : "", +// +// Proxy_Authenticate->stale ? "TRUE" : "FALSE", +// +// Proxy_Authenticate->algorithm ? ",algorithm=" : "", +// Proxy_Authenticate->algorithm ? Proxy_Authenticate->algorithm : "" +// ); +// } +// } +// return -1; +//} +// +//tsip_header_Proxy_Authenticate_t *tsip_header_Proxy_Authenticate_parse(const char *data, tsk_size_t size) +//{ +// int cs = 0; +// const char *p = data; +// const char *pe = p + size; +// const char *eof = pe; +// tsip_header_Proxy_Authenticate_t *hdr_Proxy_Authenticate = TSIP_HEADER_PROXY_AUTHENTICATE_CREATE(); +// +// const char *tag_start = tsk_null; +// +// %%write data; +// %%write init; +// %%write exec; +// +// if( cs < %%{ write first_final; }%% ) +// { +// TSK_OBJECT_SAFE_FREE(hdr_Proxy_Authenticate); +// } +// +// return hdr_Proxy_Authenticate; +//} +// +// +// +// +// +// +// +////======================================================== +//// Proxy_Authenticate header object definition +//// +// +//static tsk_object_t* tsip_header_Proxy_Authenticate_ctor(tsk_object_t *self, va_list * app) +//{ +// tsip_header_Proxy_Authenticate_t *Proxy_Authenticate = self; +// if(Proxy_Authenticate) +// { +// TSIP_HEADER(Proxy_Authenticate)->type = tsip_htype_Proxy_Authenticate; +// TSIP_HEADER(Proxy_Authenticate)->serialize = tsip_header_Proxy_Authenticate_serialize; +// } +// else +// { +// TSK_DEBUG_ERROR("Failed to create new Proxy_Authenticate header."); +// } +// return self; +//} +// +//static tsk_object_t* tsip_header_Proxy_Authenticate_dtor(tsk_object_t *self) +//{ +// tsip_header_Proxy_Authenticate_t *Proxy_Authenticate = self; +// if(Proxy_Authenticate) +// { +// TSK_FREE(Proxy_Authenticate->scheme); +// TSK_FREE(Proxy_Authenticate->realm); +// TSK_FREE(Proxy_Authenticate->domain); +// TSK_FREE(Proxy_Authenticate->nonce); +// TSK_FREE(Proxy_Authenticate->opaque); +// TSK_FREE(Proxy_Authenticate->algorithm); +// TSK_FREE(Proxy_Authenticate->qop); +// +// TSK_OBJECT_SAFE_FREE(TSIP_HEADER_PARAMS(Proxy_Authenticate)); +// } +// else TSK_DEBUG_ERROR("Null Proxy_Authenticate header."); +// +// return self; +//} +// +//static const tsk_object_def_t tsip_header_Proxy_Authenticate_def_s = +//{ +// sizeof(tsip_header_Proxy_Authenticate_t), +// tsip_header_Proxy_Authenticate_ctor, +// tsip_header_Proxy_Authenticate_dtor, +// 0 +//}; +//const void *tsip_header_Proxy_Authenticate_def_t = &tsip_header_Proxy_Authenticate_def_s; diff --git a/tinySIP/ragel/tsip_parser_header_Proxy_Authorization.rl b/tinySIP/ragel/tsip_parser_header_Proxy_Authorization.rl new file mode 100644 index 0000000..1e8437b --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_Proxy_Authorization.rl @@ -0,0 +1,286 @@ +///* +//* Copyright (C) 2010-2011 Mamadou Diop. +//* +//* Contact: Mamadou Diop +//* +//* This file is part of Open Source Doubango Framework. +//* +//* DOUBANGO is free software: you can redistribute it and/or modify +//* it under the terms of the GNU General Public License as published by +//* the Free Software Foundation, either version 3 of the License, or +//* (at your option) any later version. +//* +//* DOUBANGO is distributed in the hope that it will be useful, +//* but WITHOUT ANY WARRANTY; without even the implied warranty of +//* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +//* GNU General Public License for more details. +//* +//* You should have received a copy of the GNU General Public License +//* along with DOUBANGO. +//* +//*/ +// +///**@file tsip_header_Proxy_Authorization.c +// * @brief SIP Proxy-Authenticate header. +// * +// * @author Mamadou Diop +// * +// +// */ +//#include "tinysip/headers/tsip_header_Proxy_Authorization.h" +// +//#include "tinysip/parsers/tsip_parser_uri.h" +// +//#include "tsk_debug.h" +//#include "tsk_memory.h" +//#include "tsk_time.h" +// +//#include +// + +// +///*********************************** +//* Ragel state machine. +//*/ +//%%{ +// machine tsip_machine_parser_header_Proxy_Authorization; +// +// # Includes +// include tsip_machine_utils "./ragel/tsip_machine_utils.rl"; +// +// action tag +// { +// tag_start = p; +// } +// +// action is_digest +// { +// #//FIXME: Only Digest is supported +// hdr_Proxy_Authorization->scheme = tsk_strdup("Digest"); +// } +// +// action parse_username +// { +// TSK_PARSER_SET_STRING(hdr_Proxy_Authorization->username); +// tsk_strunquote(&hdr_Proxy_Authorization->username); +// } +// +// action parse_realm +// { +// TSK_PARSER_SET_STRING(hdr_Proxy_Authorization->realm); +// tsk_strunquote(&hdr_Proxy_Authorization->realm); +// } +// +// action parse_nonce +// { +// TSK_PARSER_SET_STRING(hdr_Proxy_Authorization->nonce); +// tsk_strunquote(&hdr_Proxy_Authorization->nonce); +// } +// +// action parse_uri +// { +// TSK_PARSER_SET_STRING(hdr_Proxy_Authorization->line.request.uri); +// } +// +// action parse_response +// { +// TSK_PARSER_SET_STRING(hdr_Proxy_Authorization->response); +// tsk_strunquote(&hdr_Proxy_Authorization->response); +// } +// +// action parse_algorithm +// { +// TSK_PARSER_SET_STRING(hdr_Proxy_Authorization->algorithm); +// } +// +// action parse_cnonce +// { +// TSK_PARSER_SET_STRING(hdr_Proxy_Authorization->cnonce); +// tsk_strunquote(&hdr_Proxy_Authorization->cnonce); +// } +// +// action parse_opaque +// { +// TSK_PARSER_SET_STRING(hdr_Proxy_Authorization->opaque); +// tsk_strunquote(&hdr_Proxy_Authorization->opaque); +// } +// +// action parse_qop +// { +// TSK_PARSER_SET_STRING(hdr_Proxy_Authorization->qop); +// //tsk_strunquote(&hdr_Proxy_Authorization->qop); +// } +// +// action parse_nc +// { +// TSK_PARSER_SET_STRING(hdr_Proxy_Authorization->nc); +// TSK_DEBUG_INFO("PROXY_AUTHORIZATION:PARSE_NC"); +// } +// +// action parse_param +// { +// TSK_PARSER_ADD_PARAM(TSIP_HEADER_PARAMS(hdr_Proxy_Authorization)); +// } +// +// action eob +// { +// } +// +// #FIXME: Only Digest (MD5, AKAv1-MD5 and AKAv2-MD5) is supported +// qop_value = "auth" | "auth-int" | token; +// other_response = (any+); +// auth_param = generic_param>tag %parse_param; +// +// username = "username"i EQUAL quoted_string>tag %parse_username; +// realm = "realm"i EQUAL quoted_string>tag %parse_realm; +// nonce = "nonce"i EQUAL quoted_string>tag %parse_nonce; +// digest_uri = "uri"i EQUAL LDQUOT <: (any*)>tag %parse_uri :> RDQUOT; +// #dresponse = "response"i EQUAL LDQUOT <: (LHEX{32})>tag %parse_response :> RDQUOT; +// dresponse = "response"i EQUAL quoted_string>tag %parse_response; +// algorithm = "algorithm"i EQUAL <:token>tag %parse_algorithm; +// cnonce = "cnonce"i EQUAL quoted_string>tag %parse_cnonce; +// opaque = "opaque"i EQUAL quoted_string>tag %parse_opaque; +// message_qop = "qop"i EQUAL qop_value>tag %parse_qop; +// nonce_count = "nc"i EQUAL (LHEX{8})>tag %parse_nc; +// +// dig_resp = (username | realm | nonce | digest_uri | dresponse | algorithm | cnonce | opaque | message_qop | nonce_count)@1 | auth_param@0; +// digest_response = dig_resp ( COMMA dig_resp )*; +// credentials = ( "Digest"i LWS digest_response )>is_digest | other_response; +// Proxy_Authorization = "Proxy-Authorization"i HCOLON credentials; +// +// # Entry point +// main := Proxy_Authorization :>CRLF @eob; +// +//}%% +// +//int tsip_header_Proxy_Authorization_serialize(const tsip_header_t* header, tsk_buffer_t* output) +//{ +// if(header) +// { +// const tsip_header_Proxy_Authorization_t *Proxy_Authorization = header; +// if(Proxy_Authorization && Proxy_Authorization->scheme) +// { +// return tsk_buffer_append_2(output, "%s %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", +// Proxy_Authorization->scheme, +// +// Proxy_Authorization->username ? "username=\"" : "", +// Proxy_Authorization->username ? Proxy_Authorization->username : "", +// Proxy_Authorization->username ? "\"" : "", +// +// Proxy_Authorization->realm ? ",realm=\"" : "", +// Proxy_Authorization->realm ? Proxy_Authorization->realm : "", +// Proxy_Authorization->realm ? "\"" : "", +// +// Proxy_Authorization->nonce ? ",nonce=\"" : "", +// Proxy_Authorization->nonce ? Proxy_Authorization->nonce : "", +// Proxy_Authorization->nonce ? "\"" : "", +// +// Proxy_Authorization->line.request.uri ? ",uri=\"" : "", +// Proxy_Authorization->line.request.uri ? Proxy_Authorization->line.request.uri : "", +// Proxy_Authorization->line.request.uri ? "\"" : "", +// +// Proxy_Authorization->response ? ",response=\"" : "", +// Proxy_Authorization->response ? Proxy_Authorization->response : "", +// Proxy_Authorization->response ? "\"" : "", +// +// Proxy_Authorization->algorithm ? ",algorithm=" : "", +// Proxy_Authorization->algorithm ? Proxy_Authorization->algorithm : "", +// +// Proxy_Authorization->cnonce ? ",cnonce=\"" : "", +// Proxy_Authorization->cnonce ? Proxy_Authorization->cnonce : "", +// Proxy_Authorization->cnonce ? "\"" : "", +// +// Proxy_Authorization->opaque ? ",opaque=\"" : "", +// Proxy_Authorization->opaque ? Proxy_Authorization->opaque : "", +// Proxy_Authorization->opaque ? "\"" : "", +// +// Proxy_Authorization->qop ? ",qop=" : "", +// Proxy_Authorization->qop ? Proxy_Authorization->qop : "", +// +// Proxy_Authorization->nc ? ",nc=" : "", +// Proxy_Authorization->nc ? Proxy_Authorization->nc : "" +// ); +// } +// } +// return -1; +//} +// +//tsip_header_Proxy_Authorization_t *tsip_header_Proxy_Authorization_parse(const char *data, tsk_size_t size) +//{ +// int cs = 0; +// const char *p = data; +// const char *pe = p + size; +// const char *eof = pe; +// tsip_header_Proxy_Authorization_t *hdr_Proxy_Authorization = TSIP_HEADER_PROXY_AUTHORIZATION_CREATE(); +// +// const char *tag_start = tsk_null; +// +// %%write data; +// %%write init; +// %%write exec; +// +// if( cs < %%{ write first_final; }%% ) +// { +// TSK_OBJECT_SAFE_FREE(hdr_Proxy_Authorization); +// } +// +// return hdr_Proxy_Authorization; +//} +// +// +// +// +// +// +// +////======================================================== +//// Proxy_Authorization header object definition +//// +// +//static tsk_object_t* tsip_header_Proxy_Authorization_ctor(tsk_object_t *self, va_list * app) +//{ +// tsip_header_Proxy_Authorization_t *Proxy_Authorization = self; +// if(Proxy_Authorization) +// { +// TSIP_HEADER(Proxy_Authorization)->type = tsip_htype_Proxy_Authorization; +// TSIP_HEADER(Proxy_Authorization)->serialize = tsip_header_Proxy_Authorization_serialize; +// } +// else +// { +// TSK_DEBUG_ERROR("Failed to create new Proxy_Authorization header."); +// } +// return self; +//} +// +//static tsk_object_t* tsip_header_Proxy_Authorization_dtor(tsk_object_t *self) +//{ +// tsip_header_Proxy_Authorization_t *Proxy_Authorization = self; +// if(Proxy_Authorization) +// { +// TSK_FREE(Proxy_Authorization->scheme); +// TSK_FREE(Proxy_Authorization->username); +// TSK_FREE(Proxy_Authorization->realm); +// TSK_FREE(Proxy_Authorization->nonce); +// TSK_FREE(Proxy_Authorization->line.request.uri); +// TSK_FREE(Proxy_Authorization->response); +// TSK_FREE(Proxy_Authorization->algorithm); +// TSK_FREE(Proxy_Authorization->cnonce); +// TSK_FREE(Proxy_Authorization->opaque); +// TSK_FREE(Proxy_Authorization->qop); +// TSK_FREE(Proxy_Authorization->nc); +// +// TSK_OBJECT_SAFE_FREE(TSIP_HEADER_PARAMS(Proxy_Authorization)); +// } +// else TSK_DEBUG_ERROR("Null Proxy_Authorization header."); +// +// return self; +//} +// +//static const tsk_object_def_t tsip_header_Proxy_Authorization_def_s = +//{ +// sizeof(tsip_header_Proxy_Authorization_t), +// tsip_header_Proxy_Authorization_ctor, +// tsip_header_Proxy_Authorization_dtor, +// 0 +//}; +//const void *tsip_header_Proxy_Authorization_def_t = &tsip_header_Proxy_Authorization_def_s; diff --git a/tinySIP/ragel/tsip_parser_header_Proxy_Require.rl b/tinySIP/ragel/tsip_parser_header_Proxy_Require.rl new file mode 100644 index 0000000..3799872 --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_Proxy_Require.rl @@ -0,0 +1,181 @@ + +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* DOUBANGO is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with DOUBANGO. +* +*/ + +/**@file tsip_header_Proxy_Require.c + * @brief SIP Proxy-Require header. + * + * @author Mamadou Diop + * + + */ +#include "tinysip/headers/tsip_header_Proxy_Require.h" + +#include "tinysip/parsers/tsip_parser_uri.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" + +#include + + +/*********************************** +* Ragel state machine. +*/ +%%{ + machine tsip_machine_parser_header_Proxy_Require; + + # Includes + include tsip_machine_utils "./ragel/tsip_machine_utils.rl"; + + action tag{ + tag_start = p; + } + + action parse_option{ + TSK_PARSER_ADD_STRING(hdr_proxyrequire->options); + } + + action eob{ + } + + Proxy_Require = "Proxy-Require"i HCOLON option_tag>tag %parse_option ( COMMA option_tag>tag %parse_option )*; + + # Entry point + main := Proxy_Require :>CRLF @eob; + +}%% + + +tsip_header_Proxy_Require_t* tsip_header_Proxy_Require_create(const char* option) +{ + return tsk_object_new(TSIP_HEADER_PROXY_REQUIRE_VA_ARGS(option)); +} + +tsip_header_Proxy_Require_t* tsip_header_Proxy_Require_create_null() +{ + return tsip_header_Proxy_Require_create(tsk_null); +} + +int tsip_header_Proxy_Require_serialize(const tsip_header_t* header, tsk_buffer_t* output) +{ + if(header){ + const tsip_header_Proxy_Require_t *Proxy_Require = (const tsip_header_Proxy_Require_t *)header; + tsk_list_item_t *item; + tsk_string_t *str; + int ret = 0; + + tsk_list_foreach(item, Proxy_Require->options){ + str = item->data; + if(item == Proxy_Require->options->head){ + ret = tsk_buffer_append(output, str->value, tsk_strlen(str->value)); + } + else{ + ret = tsk_buffer_append_2(output, ",%s", str->value); + } + } + + return ret; + } + + return -1; +} + +tsip_header_Proxy_Require_t *tsip_header_Proxy_Require_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsip_header_Proxy_Require_t *hdr_proxyrequire = tsip_header_Proxy_Require_create_null(); + + const char *tag_start = tsk_null; + + %%write data; + (void)(eof); + (void)(tsip_machine_parser_header_Proxy_Require_first_final); + (void)(tsip_machine_parser_header_Proxy_Require_error); + (void)(tsip_machine_parser_header_Proxy_Require_en_main); + %%write init; + %%write exec; + + if( cs < %%{ write first_final; }%% ){ + TSK_DEBUG_ERROR("Failed to parse 'Privacy' header."); + TSK_OBJECT_SAFE_FREE(hdr_proxyrequire); + } + + return hdr_proxyrequire; +} + + + + + + + +//======================================================== +// Proxy_Require header object definition +// + +static tsk_object_t* tsip_header_Proxy_Require_ctor(tsk_object_t *self, va_list * app) +{ + tsip_header_Proxy_Require_t *Proxy_Require = self; + if(Proxy_Require){ + const char* option; + + TSIP_HEADER(Proxy_Require)->type = tsip_htype_Proxy_Require; + TSIP_HEADER(Proxy_Require)->serialize = tsip_header_Proxy_Require_serialize; + + if((option = va_arg(*app, const char*))){ + tsk_string_t* string = tsk_string_create(option); + Proxy_Require->options = tsk_list_create(); + + tsk_list_push_back_data(Proxy_Require->options, ((void**) &string)); + } + } + else{ + TSK_DEBUG_ERROR("Failed to create new Proxy_Require header."); + } + return self; +} + +static tsk_object_t* tsip_header_Proxy_Require_dtor(tsk_object_t *self) +{ + tsip_header_Proxy_Require_t *Proxy_Require = self; + if(Proxy_Require){ + TSK_OBJECT_SAFE_FREE(Proxy_Require->options); + } + else{ + TSK_DEBUG_ERROR("Null Proxy_Require header."); + } + + return self; +} + +static const tsk_object_def_t tsip_header_Proxy_Require_def_s = +{ + sizeof(tsip_header_Proxy_Require_t), + tsip_header_Proxy_Require_ctor, + tsip_header_Proxy_Require_dtor, + tsk_null +}; +const tsk_object_def_t *tsip_header_Proxy_Require_def_t = &tsip_header_Proxy_Require_def_s; diff --git a/tinySIP/ragel/tsip_parser_header_RAck.rl b/tinySIP/ragel/tsip_parser_header_RAck.rl new file mode 100644 index 0000000..181ecbf --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_RAck.rl @@ -0,0 +1,170 @@ + + +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* DOUBANGO is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with DOUBANGO. +* +*/ + +/**@file tsip_header_RAck.c + * @brief SIP RAck header as per RFC 3262. + * + * @author Mamadou Diop + * + + */ +#include "tinysip/headers/tsip_header_RAck.h" + +#include "tinysip/parsers/tsip_parser_uri.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" + + +/*********************************** +* Ragel state machine. +*/ +%%{ + machine tsip_machine_parser_header_RAck; + + # Includes + include tsip_machine_utils "./ragel/tsip_machine_utils.rl"; + + action tag{ + tag_start = p; + } + + action parse_seq{ + TSK_PARSER_SET_UINT(hdr_rack->seq); + } + + action parse_cseq{ + TSK_PARSER_SET_UINT(hdr_rack->cseq); + } + + action parse_method{ + TSK_PARSER_SET_STRING(hdr_rack->method); + } + + action eob{ + } + + RAck = "RAck"i HCOLON DIGIT+>tag %parse_seq LWS DIGIT+>tag %parse_cseq LWS Method>tag %parse_method; + + # Entry point + main := RAck :>CRLF @eob; + +}%% + + +tsip_header_RAck_t* tsip_header_RAck_create(uint32_t seq, uint32_t cseq, const char* method) +{ + return tsk_object_new(TSIP_HEADER_RACK_VA_ARGS(seq, cseq, method)); +} + +tsip_header_RAck_t* tsip_header_RAck_create_null() +{ + return tsip_header_RAck_create(0, 0, tsk_null); +} + +int tsip_header_RAck_serialize(const tsip_header_t* header, tsk_buffer_t* output) +{ + if(header){ + const tsip_header_RAck_t *RAck = (const tsip_header_RAck_t *)header; + return tsk_buffer_append_2(output, "%u %u %s", RAck->seq, RAck->cseq, RAck->method); + } + return -1; +} + +tsip_header_RAck_t *tsip_header_RAck_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsip_header_RAck_t *hdr_rack = tsip_header_RAck_create_null(); + + const char *tag_start = tsk_null; + + %%write data; + (void)(eof); + (void)(tsip_machine_parser_header_RAck_first_final); + (void)(tsip_machine_parser_header_RAck_error); + (void)(tsip_machine_parser_header_RAck_en_main); + %%write init; + %%write exec; + + if( cs < %%{ write first_final; }%% ){ + TSK_DEBUG_ERROR("Failed to parse 'RAck' header."); + TSK_OBJECT_SAFE_FREE(hdr_rack); + } + + return hdr_rack; +} + + + + + + + +//======================================================== +// RAck header object definition +// + +static tsk_object_t* tsip_header_RAck_ctor(tsk_object_t *self, va_list * app) +{ + tsip_header_RAck_t *RAck = self; + if(RAck){ + TSIP_HEADER(RAck)->type = tsip_htype_RAck; + TSIP_HEADER(RAck)->serialize = tsip_header_RAck_serialize; + RAck->seq = va_arg(*app, uint32_t); + RAck->cseq = va_arg(*app, uint32_t); + RAck->method = tsk_strdup( va_arg(*app, const char*) ); + } + else{ + TSK_DEBUG_ERROR("Failed to create new RAck header."); + } + return self; +} + +static tsk_object_t* tsip_header_RAck_dtor(tsk_object_t *self) +{ + tsip_header_RAck_t *RAck = self; + if(RAck){ + TSK_FREE(RAck->method); + + TSK_OBJECT_SAFE_FREE(TSIP_HEADER_PARAMS(RAck)); + } + else{ + TSK_DEBUG_ERROR("Null RAck header."); + } + + return self; +} + +static const tsk_object_def_t tsip_header_RAck_def_s = +{ + sizeof(tsip_header_RAck_t), + tsip_header_RAck_ctor, + tsip_header_RAck_dtor, + tsk_null +}; +const tsk_object_def_t *tsip_header_RAck_def_t = &tsip_header_RAck_def_s; + diff --git a/tinySIP/ragel/tsip_parser_header_RSeq.rl b/tinySIP/ragel/tsip_parser_header_RSeq.rl new file mode 100644 index 0000000..e6a9f2b --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_RSeq.rl @@ -0,0 +1,158 @@ + +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* DOUBANGO is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with DOUBANGO. +* +*/ + +/**@file tsip_header_RSeq.c + * @brief SIP RSeq header as per RFC 3262. + * + * @author Mamadou Diop + * + + */ +#include "tinysip/headers/tsip_header_RSeq.h" + +#include "tinysip/parsers/tsip_parser_uri.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" + + + +/*********************************** +* Ragel state machine. +*/ +%%{ + machine tsip_machine_parser_header_RSeq; + + # Includes + include tsip_machine_utils "./ragel/tsip_machine_utils.rl"; + + action tag{ + tag_start = p; + } + + action parse_seq{ + TSK_PARSER_SET_UINT(hdr_rseq->seq); + } + + action eob{ + } + + RSeq = "RSeq"i HCOLON DIGIT+>tag %parse_seq ; + + # Entry point + main := RSeq :>CRLF @eob; + +}%% + + +tsip_header_RSeq_t* tsip_header_RSeq_create(uint32_t seq) +{ + return tsk_object_new(TSIP_HEADER_RSEQ_VA_ARGS(seq)); +} + +tsip_header_RSeq_t* tsip_header_RSeq_create_null() +{ + return tsip_header_RSeq_create(0); +} + +int tsip_header_RSeq_serialize(const tsip_header_t* header, tsk_buffer_t* output) +{ + if(header){ + const tsip_header_RSeq_t *RSeq = (const tsip_header_RSeq_t *)header; + return tsk_buffer_append_2(output, "%u", RSeq->seq); + } + return -1; +} + +tsip_header_RSeq_t *tsip_header_RSeq_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsip_header_RSeq_t *hdr_rseq = tsip_header_RSeq_create_null(); + + const char *tag_start = tsk_null; + + %%write data; + (void)(eof); + (void)(tsip_machine_parser_header_RSeq_first_final); + (void)(tsip_machine_parser_header_RSeq_error); + (void)(tsip_machine_parser_header_RSeq_en_main); + %%write init; + %%write exec; + + if( cs < %%{ write first_final; }%% ){ + TSK_DEBUG_ERROR("Failed to parse 'RSeq' header."); + TSK_OBJECT_SAFE_FREE(hdr_rseq); + } + + return hdr_rseq; +} + + + + + + + +//======================================================== +// RSeq header object definition +// + +static tsk_object_t* tsip_header_RSeq_ctor(tsk_object_t *self, va_list * app) +{ + tsip_header_RSeq_t *RSeq = self; + if(RSeq){ + TSIP_HEADER(RSeq)->type = tsip_htype_RSeq; + TSIP_HEADER(RSeq)->serialize = tsip_header_RSeq_serialize; + RSeq->seq = va_arg(*app, uint32_t); + } + else{ + TSK_DEBUG_ERROR("Failed to create new RSeq header."); + } + return self; +} + +static tsk_object_t* tsip_header_RSeq_dtor(tsk_object_t *self) +{ + tsip_header_RSeq_t *RSeq = self; + if(RSeq){ + TSK_OBJECT_SAFE_FREE(TSIP_HEADER_PARAMS(RSeq)); + } + else{ + TSK_DEBUG_ERROR("Null RSeq header."); + } + + return self; +} + +static const tsk_object_def_t tsip_header_RSeq_def_s = +{ + sizeof(tsip_header_RSeq_t), + tsip_header_RSeq_ctor, + tsip_header_RSeq_dtor, + tsk_null +}; +const tsk_object_def_t *tsip_header_RSeq_def_t = &tsip_header_RSeq_def_s; + diff --git a/tinySIP/ragel/tsip_parser_header_Reason.rl b/tinySIP/ragel/tsip_parser_header_Reason.rl new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_Reason.rl @@ -0,0 +1 @@ + diff --git a/tinySIP/ragel/tsip_parser_header_Record_Route.rl b/tinySIP/ragel/tsip_parser_header_Record_Route.rl new file mode 100644 index 0000000..45ac809 --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_Record_Route.rl @@ -0,0 +1,211 @@ +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* DOUBANGO is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with DOUBANGO. +* +*/ + +/**@file tsip_header_Record_Route.c + * @brief SIP Record-Route header. + * + * @author Mamadou Diop + * + + */ +#include "tinysip/headers/tsip_header_Record_Route.h" + +#include "tinysip/parsers/tsip_parser_uri.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" +#include "tsk_time.h" + +#include + + + +/*********************************** +* Ragel state machine. +*/ +%%{ + machine tsip_machine_parser_header_Record_Route; + + # Includes + include tsip_machine_utils "./ragel/tsip_machine_utils.rl"; + + action tag{ + tag_start = p; + } + + action create_route{ + if(!curr_route){ + curr_route = tsip_header_Record_Route_create_null(); + } + } + + action parse_display_name{ + if(curr_route){ + TSK_PARSER_SET_STRING(curr_route->display_name); + tsk_strunquote(&curr_route->display_name); + } + } + + action parse_uri{ + if(curr_route && !curr_route->uri){ + int len = (int)(p - tag_start); + if(curr_route && !curr_route->uri){ + if((curr_route->uri = tsip_uri_parse(tag_start, (tsk_size_t)len)) && curr_route->display_name){ + curr_route->uri->display_name = tsk_strdup(curr_route->display_name); + } + } + } + } + + action parse_param{ + if(curr_route){ + TSK_PARSER_ADD_PARAM(TSIP_HEADER_PARAMS(curr_route)); + } + } + + action add_route{ + if(curr_route){ + tsk_list_push_back_data(hdr_record_routes, ((void**) &curr_route)); + } + } + + action eob{ + } + + URI = (scheme HCOLON any+)>tag %parse_uri; + display_name = (( token LWS )+ | quoted_string)>tag %parse_display_name; + my_name_addr = display_name? :>LAQUOT<: URI :>RAQUOT; + + rr_param = (generic_param)>tag %parse_param; + rec_route = ( my_name_addr (SEMI rr_param)* ) >create_route %add_route; + Record_Route = "Record-Route"i HCOLON rec_route (COMMA rec_route)*; + + # Entry point + main := Record_Route :>CRLF @eob; + +}%% + + +tsip_header_Record_Route_t* tsip_header_Record_Route_create(const tsip_uri_t* uri) +{ + return tsk_object_new(TSIP_HEADER_RECORD_ROUTE_VA_ARGS(uri)); +} + +tsip_header_Record_Route_t* tsip_header_Record_Route_create_null() +{ + return tsip_header_Record_Route_create(tsk_null); +} + +int tsip_header_Record_Route_serialize(const tsip_header_t* header, tsk_buffer_t* output) +{ + if(header){ + int ret; + const tsip_header_Record_Route_t *Record_Route = (const tsip_header_Record_Route_t *)header; + + /* Uri with hacked display-name*/ + if((ret = tsip_uri_serialize(Record_Route->uri, tsk_true, tsk_true, output))){ + return ret; + } + return ret; + } + return -1; +} + + tsip_header_Record_Routes_L_t* tsip_header_Record_Route_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsip_header_Record_Routes_L_t *hdr_record_routes = tsk_list_create(); + tsip_header_Record_Route_t *curr_route = tsk_null; + + const char *tag_start = tsk_null; + + %%write data; + (void)(eof); + (void)(tsip_machine_parser_header_Record_Route_first_final); + (void)(tsip_machine_parser_header_Record_Route_error); + (void)(tsip_machine_parser_header_Record_Route_en_main); + %%write init; + %%write exec; + + if( cs < %%{ write first_final; }%% ){ + TSK_DEBUG_ERROR("Failed to parse 'Record-Route' header."); + TSK_OBJECT_SAFE_FREE(curr_route); + TSK_OBJECT_SAFE_FREE(hdr_record_routes); + } + + return hdr_record_routes; +} + + + + + + + +//======================================================== +// Record_Route header object definition +// + +static tsk_object_t* tsip_header_Record_Route_ctor(tsk_object_t *self, va_list * app) +{ + tsip_header_Record_Route_t *Record_Route = self; + if(Record_Route){ + const tsip_uri_t* uri = va_arg(*app, const tsip_uri_t *); + + if(uri){ + Record_Route->uri = tsk_object_ref((void*)uri); + } + TSIP_HEADER(Record_Route)->type = tsip_htype_Record_Route; + TSIP_HEADER(Record_Route)->serialize = tsip_header_Record_Route_serialize; + } + else{ + TSK_DEBUG_ERROR("Failed to create new Record_Route header."); + } + return self; +} + +static tsk_object_t* tsip_header_Record_Route_dtor(tsk_object_t *self) +{ + tsip_header_Record_Route_t *Record_Route = self; + if(Record_Route){ + TSK_FREE(Record_Route->display_name); + TSK_OBJECT_SAFE_FREE(Record_Route->uri); + TSK_OBJECT_SAFE_FREE(TSIP_HEADER_PARAMS(Record_Route)); + } + else{ + TSK_DEBUG_ERROR("Null Record_Route header."); + } + + return self; +} + +static const tsk_object_def_t tsip_header_Record_Route_def_s = +{ + sizeof(tsip_header_Record_Route_t), + tsip_header_Record_Route_ctor, + tsip_header_Record_Route_dtor, + tsk_null +}; +const tsk_object_def_t *tsip_header_Record_Route_def_t = &tsip_header_Record_Route_def_s; diff --git a/tinySIP/ragel/tsip_parser_header_Refer_Sub.rl b/tinySIP/ragel/tsip_parser_header_Refer_Sub.rl new file mode 100644 index 0000000..dfe72d1 --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_Refer_Sub.rl @@ -0,0 +1,165 @@ + +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* DOUBANGO is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with DOUBANGO. +* +*/ + +/**@file tsip_header_Refer_Sub.c + * @brief SIP header 'Refer-Sub' as per 4488. + * + * @author Mamadou Diop + * + + */ +#include "tinysip/headers/tsip_header_Refer_Sub.h" + +#include "tinysip/parsers/tsip_parser_uri.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" + +#include + +/*********************************** +* Ragel state machine. +*/ +%%{ + machine tsip_machine_parser_header_Refer_Sub; + + # Includes + include tsip_machine_utils "./ragel/tsip_machine_utils.rl"; + + action tag{ + tag_start = p; + } + + action is_true{ + hdr_rsub->sub = tsk_true; + } + action is_false{ + hdr_rsub->sub = tsk_false; + } + action parse_param{ + TSK_PARSER_ADD_PARAM(TSIP_HEADER_PARAMS(hdr_rsub)); + } + + action eob{ + } + + refer_sub_value = "true"i>tag %is_true | "false"i>tag %is_false; + exten = generic_param>tag %parse_param; + Refer_Sub = "Refer-Sub"i HCOLON refer_sub_value ( SEMI exten )*; + + # Entry point + main := Refer_Sub :>CRLF @eob; + +}%% + +tsip_header_Refer_Sub_t* tsip_header_Refer_Sub_create(tsk_bool_t sub) +{ + return tsk_object_new(TSIP_HEADER_REFER_SUB_VA_ARGS(sub)); +} + +tsip_header_Refer_Sub_t* tsip_header_Refer_Sub_create_null() +{ + return tsip_header_Refer_Sub_create(tsk_true); +} + +int tsip_header_Refer_Sub_serialize(const tsip_header_t* header, tsk_buffer_t* output) +{ + if(header){ + const tsip_header_Refer_Sub_t *Refer_Sub = (const tsip_header_Refer_Sub_t *)header; + return tsk_buffer_append(output, Refer_Sub->sub ? "true" : "false", Refer_Sub->sub ? 4 : 5); + } + + return -1; +} + +tsip_header_Refer_Sub_t *tsip_header_Refer_Sub_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsip_header_Refer_Sub_t *hdr_rsub = tsip_header_Refer_Sub_create_null(); + + const char *tag_start = tsk_null; + + %%write data; + (void)(eof); + (void)(tsip_machine_parser_header_Refer_Sub_first_final); + (void)(tsip_machine_parser_header_Refer_Sub_error); + (void)(tsip_machine_parser_header_Refer_Sub_en_main); + %%write init; + %%write exec; + + if( cs < %%{ write first_final; }%% ){ + TSK_DEBUG_ERROR("Failed to parse 'Refer-Sub' header."); + TSK_OBJECT_SAFE_FREE(hdr_rsub); + } + + return hdr_rsub; +} + + + + + + + +//======================================================== +// Refer_Sub header object definition +// + +static tsk_object_t* tsip_header_Refer_Sub_ctor(tsk_object_t *self, va_list * app) +{ + tsip_header_Refer_Sub_t *Refer_Sub = self; + if(Refer_Sub){ + TSIP_HEADER(Refer_Sub)->type = tsip_htype_Refer_Sub; + TSIP_HEADER(Refer_Sub)->serialize = tsip_header_Refer_Sub_serialize; + Refer_Sub->sub = va_arg(*app, tsk_bool_t); + } + else{ + TSK_DEBUG_ERROR("Failed to create new Refer_Sub header."); + } + return self; +} + +static tsk_object_t* tsip_header_Refer_Sub_dtor(tsk_object_t *self) +{ + tsip_header_Refer_Sub_t *Refer_Sub = self; + if(Refer_Sub){ + TSK_OBJECT_SAFE_FREE(TSIP_HEADER_PARAMS(Refer_Sub)); + } + else{ + TSK_DEBUG_ERROR("Null Refer_Sub header."); + } + + return self; +} + +static const tsk_object_def_t tsip_header_Refer_Sub_def_s = +{ + sizeof(tsip_header_Refer_Sub_t), + tsip_header_Refer_Sub_ctor, + tsip_header_Refer_Sub_dtor, + tsk_null +}; +const tsk_object_def_t *tsip_header_Refer_Sub_def_t = &tsip_header_Refer_Sub_def_s; diff --git a/tinySIP/ragel/tsip_parser_header_Refer_To.rl b/tinySIP/ragel/tsip_parser_header_Refer_To.rl new file mode 100644 index 0000000..70ce44f --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_Refer_To.rl @@ -0,0 +1,195 @@ + +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* DOUBANGO is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with DOUBANGO. +* +*/ + +/**@file tsip_header_Refer_To.c + * @brief SIP Refer-To header as per RFC 3515. + * + * @author Mamadou Diop + * + + */ +#include "tinysip/headers/tsip_header_Refer_To.h" + +#include "tinysip/parsers/tsip_parser_uri.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" + + + +/*********************************** +* Ragel state machine. +*/ +%%{ + machine tsip_machine_parser_header_Refer_To; + + # Includes + include tsip_machine_utils "./ragel/tsip_machine_utils.rl"; + + action tag{ + tag_start = p; + } + + action parse_uri{ + if(!r_to->uri) /* Only one URI */{ + int len = (int)(p - tag_start); + if(r_to && !r_to->uri){ + if((r_to->uri = tsip_uri_parse(tag_start, (tsk_size_t)len)) && r_to->display_name){ + r_to->uri->display_name = tsk_strdup(r_to->display_name); + } + } + } + } + + action parse_display_name{ + if(!r_to->display_name){ + TSK_PARSER_SET_STRING(r_to->display_name); + tsk_strunquote(&r_to->display_name); + } + } + + action parse_param{ + TSK_PARSER_ADD_PARAM(TSIP_HEADER_PARAMS(r_to)); + } + + action eob{ + } + + URI = (scheme HCOLON any+)>tag %parse_uri; + display_name = (( token LWS )+ | quoted_string)>tag %parse_display_name; + my_name_addr = display_name? :>LAQUOT<: URI :>RAQUOT; + + feature_param = generic_param; # HACK + refer_param = generic_param>tag %parse_param | feature_param>tag %parse_param; + Refer_To = ( "Refer-To"i | "r"i ) HCOLON ( my_name_addr>0 | URI>1 ) ( SEMI refer_param )*; + + # Entry point + main := Refer_To :>CRLF @eob; + +}%% + + +tsip_header_Refer_To_t* tsip_header_Refer_To_create(const tsip_uri_t* uri) +{ + return tsk_object_new(TSIP_HEADER_REFER_TO_VA_ARGS(uri)); +} + +tsip_header_Refer_To_t* tsip_header_Refer_To_create_null() +{ + return tsip_header_Refer_To_create(tsk_null); +} + +int tsip_header_Refer_To_serialize(const tsip_header_t* header, tsk_buffer_t* output) +{ + if(header){ + int ret; + const tsip_header_Refer_To_t *Refer_To = (const tsip_header_Refer_To_t *)header; + + /* Uri with hacked display-name*/ + if((ret = tsip_uri_serialize(Refer_To->uri, tsk_true, tsk_true, output))){ + return ret; + } + return ret; + } + return -1; +} + +tsip_header_Refer_To_t *tsip_header_Refer_To_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsip_header_Refer_To_t *r_to = tsip_header_Refer_To_create_null(); + + const char *tag_start = tsk_null; + + %%write data; + (void)(eof); + (void)(tsip_machine_parser_header_Refer_To_first_final); + (void)(tsip_machine_parser_header_Refer_To_error); + (void)(tsip_machine_parser_header_Refer_To_en_main); + %%write init; + %%write exec; + + if( cs < %%{ write first_final; }%% ){ + TSK_DEBUG_ERROR("Failed to parse 'Refer-To' header."); + TSK_OBJECT_SAFE_FREE(r_to); + } + + return r_to; +} + + + + + + + +//======================================================== +// Refer_To header object definition +// + +static tsk_object_t* tsip_header_Refer_To_ctor(tsk_object_t *self, va_list * app) +{ + tsip_header_Refer_To_t *Refer_To = self; + if(Refer_To){ + const tsip_uri_t* uri = va_arg(*app, const tsip_uri_t*); + + TSIP_HEADER(Refer_To)->type = tsip_htype_Refer_To; + TSIP_HEADER(Refer_To)->serialize = tsip_header_Refer_To_serialize; + + if(uri){ + Refer_To->uri = tsk_object_ref((void*)uri); + } + } + else{ + TSK_DEBUG_ERROR("Failed to create new Refer_To header."); + } + return self; +} + +static tsk_object_t* tsip_header_Refer_To_dtor(tsk_object_t *self) +{ + tsip_header_Refer_To_t *Refer_To = self; + if(Refer_To){ + TSK_FREE(Refer_To->display_name); + TSK_OBJECT_SAFE_FREE(Refer_To->uri); + + TSK_OBJECT_SAFE_FREE(TSIP_HEADER_PARAMS(Refer_To)); + } + else{ + TSK_DEBUG_ERROR("Null Refer_To header."); + } + + return self; +} + +static const tsk_object_def_t tsip_header_Refer_To_def_s = +{ + sizeof(tsip_header_Refer_To_t), + tsip_header_Refer_To_ctor, + tsip_header_Refer_To_dtor, + tsk_null +}; +const tsk_object_def_t *tsip_header_Refer_To_def_t = &tsip_header_Refer_To_def_s; diff --git a/tinySIP/ragel/tsip_parser_header_Referred_By.rl b/tinySIP/ragel/tsip_parser_header_Referred_By.rl new file mode 100644 index 0000000..7e9334f --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_Referred_By.rl @@ -0,0 +1,207 @@ + +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* DOUBANGO is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with DOUBANGO. +* +*/ + +/**@file tsip_header_Referred_By.c + * @brief SIP Referred-By header as per RFC 3892. + * + * @author Mamadou Diop + * + + */ +#include "tinysip/headers/tsip_header_Referred_By.h" + +#include "tinysip/parsers/tsip_parser_uri.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" + + + +/*********************************** +* Ragel state machine. +*/ +%%{ + machine tsip_machine_parser_header_Referred_By; + + # Includes + include tsip_machine_utils "./ragel/tsip_machine_utils.rl"; + + action tag{ + tag_start = p; + } + + action parse_uri{ + if(!r_by->uri) /* Only one URI */{ + int len = (int)(p - tag_start); + if(r_by && !r_by->uri){ + if((r_by->uri = tsip_uri_parse(tag_start, (tsk_size_t)len)) && r_by->display_name){ + r_by->uri->display_name = tsk_strdup(r_by->display_name); + } + } + } + } + + action parse_display_name{ + if(!r_by->display_name){ + TSK_PARSER_SET_STRING(r_by->display_name); + tsk_strunquote(&r_by->display_name); + } + } + + action parse_cid{ + TSK_PARSER_SET_STRING(r_by->cid); + } + + action parse_param{ + TSK_PARSER_ADD_PARAM(TSIP_HEADER_PARAMS(r_by)); + } + + action eob{ + } + + URI = (scheme HCOLON any+)>tag %parse_uri; + display_name = (( token LWS )+ | quoted_string)>tag %parse_display_name; + my_name_addr = display_name? :>LAQUOT<: URI :>RAQUOT; + + referrer_uri = ( my_name_addr>0 | URI>1 ); + atom = ( alphanum | "-" | "!" | "%" | "*" | "_" | "+" | "'" | "`" | "~" )+; + dot_atom = atom ( "." atom )*; + sip_clean_msg_id = LDQUOT dot_atom "@" ( dot_atom | host ) RDQUOT; + referredby_id_param = "cid"i EQUAL sip_clean_msg_id>tag %parse_cid; + Referred_By = ( "Referred-By"i | "b"i ) HCOLON referrer_uri ( SEMI ( referredby_id_param | generic_param>tag %parse_param ) )*; + + # Entry point + main := Referred_By :>CRLF @eob; +}%% + + +tsip_header_Referred_By_t* tsip_header_Referred_By_create(const tsip_uri_t* uri, const char* cid) +{ + return tsk_object_new(TSIP_HEADER_REFERRED_BY_VA_ARGS(uri, cid)); +} + +tsip_header_Referred_By_t* tsip_header_Referred_By_create_null() +{ + return tsip_header_Referred_By_create(tsk_null, tsk_null); +} + +int tsip_header_Referred_By_serialize(const tsip_header_t* header, tsk_buffer_t* output) +{ + if(header){ + int ret; + const tsip_header_Referred_By_t *Referred_By = (const tsip_header_Referred_By_t *)header; + + /* Uri with hacked display-name*/ + if((ret = tsip_uri_serialize(Referred_By->uri, tsk_true, tsk_true, output))){ + return ret; + } + /* cid */ + if(Referred_By->cid && (ret = tsk_buffer_append_2(output, ";cid=%s", Referred_By->cid))){ + return ret; + } + return ret; + } + return -1; +} + +tsip_header_Referred_By_t *tsip_header_Referred_By_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsip_header_Referred_By_t *r_by = tsip_header_Referred_By_create_null(); + + const char *tag_start = tsk_null; + + %%write data; + (void)(eof); + (void)(tsip_machine_parser_header_Referred_By_first_final); + (void)(tsip_machine_parser_header_Referred_By_error); + (void)(tsip_machine_parser_header_Referred_By_en_main); + %%write init; + %%write exec; + + if( cs < %%{ write first_final; }%% ){ + TSK_DEBUG_ERROR("Failed to parse 'Referred-By' header."); + TSK_OBJECT_SAFE_FREE(r_by); + } + + return r_by; +} + + + + + + + +//======================================================== +// Referred_By header object definition +// + +static tsk_object_t* tsip_header_Referred_By_ctor(tsk_object_t *self, va_list * app) +{ + tsip_header_Referred_By_t *Referred_By = self; + if(Referred_By){ + const tsip_uri_t* uri = va_arg(*app, const tsip_uri_t*); + const char* cid = va_arg(*app, const char*); + + TSIP_HEADER(Referred_By)->type = tsip_htype_Referred_By; + TSIP_HEADER(Referred_By)->serialize = tsip_header_Referred_By_serialize; + + Referred_By->uri = tsk_object_ref((void*)uri); + Referred_By->cid = tsk_strdup(cid); + } + else{ + TSK_DEBUG_ERROR("Failed to create new Referred_By header."); + } + return self; +} + +static tsk_object_t* tsip_header_Referred_By_dtor(tsk_object_t *self) +{ + tsip_header_Referred_By_t *Referred_By = self; + if(Referred_By){ + TSK_FREE(Referred_By->display_name); + TSK_OBJECT_SAFE_FREE(Referred_By->uri); + TSK_FREE(Referred_By->cid); + + TSK_OBJECT_SAFE_FREE(TSIP_HEADER_PARAMS(Referred_By)); + } + else{ + TSK_DEBUG_ERROR("Null Referred_By header."); + } + + return self; +} + +static const tsk_object_def_t tsip_header_Referred_By_def_s = +{ + sizeof(tsip_header_Referred_By_t), + tsip_header_Referred_By_ctor, + tsip_header_Referred_By_dtor, + tsk_null +}; +const tsk_object_def_t *tsip_header_Referred_By_def_t = &tsip_header_Referred_By_def_s; + diff --git a/tinySIP/ragel/tsip_parser_header_Reject_Contact.rl b/tinySIP/ragel/tsip_parser_header_Reject_Contact.rl new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_Reject_Contact.rl @@ -0,0 +1 @@ + diff --git a/tinySIP/ragel/tsip_parser_header_Replaces.rl b/tinySIP/ragel/tsip_parser_header_Replaces.rl new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_Replaces.rl @@ -0,0 +1 @@ + diff --git a/tinySIP/ragel/tsip_parser_header_Reply_To.rl b/tinySIP/ragel/tsip_parser_header_Reply_To.rl new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_Reply_To.rl @@ -0,0 +1 @@ + diff --git a/tinySIP/ragel/tsip_parser_header_Request_Disposition.rl b/tinySIP/ragel/tsip_parser_header_Request_Disposition.rl new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_Request_Disposition.rl @@ -0,0 +1 @@ + diff --git a/tinySIP/ragel/tsip_parser_header_Require.rl b/tinySIP/ragel/tsip_parser_header_Require.rl new file mode 100644 index 0000000..a3ee3e2 --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_Require.rl @@ -0,0 +1,180 @@ +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* DOUBANGO is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with DOUBANGO. +* +*/ + +/**@file tsip_header_Require.c + * @brief SIP Require header. + * + * @author Mamadou Diop + * + + */ +#include "tinysip/headers/tsip_header_Require.h" + +#include "tinysip/parsers/tsip_parser_uri.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" + +#include + + + +/*********************************** +* Ragel state machine. +*/ +%%{ + machine tsip_machine_parser_header_Require; + + # Includes + include tsip_machine_utils "./ragel/tsip_machine_utils.rl"; + + action tag{ + tag_start = p; + } + + action parse_option{ + TSK_PARSER_ADD_STRING(hdr_require->options); + } + + action eob{ + } + + Require = "Require"i HCOLON option_tag>tag %parse_option ( COMMA option_tag>tag %parse_option )*; + + # Entry point + main := Require :>CRLF @eob; + +}%% + +tsip_header_Require_t* tsip_header_Require_create(const char* option) +{ + return tsk_object_new(TSIP_HEADER_REQUIRE_VA_ARGS(option)); +} + +tsip_header_Require_t* tsip_header_Require_create_null() +{ + return tsip_header_Require_create(tsk_null); +} + +int tsip_header_Require_serialize(const tsip_header_t* header, tsk_buffer_t* output) +{ + if(header){ + const tsip_header_Require_t *Require = (const tsip_header_Require_t *)header; + tsk_list_item_t *item; + tsk_string_t *str; + int ret = 0; + + tsk_list_foreach(item, Require->options){ + str = item->data; + if(item == Require->options->head){ + ret = tsk_buffer_append(output, str->value, tsk_strlen(str->value)); + } + else{ + ret = tsk_buffer_append_2(output, ",%s", str->value); + } + } + + return ret; + } + + return -1; +} + +tsip_header_Require_t *tsip_header_Require_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsip_header_Require_t *hdr_require = tsip_header_Require_create_null(); + + const char *tag_start = tsk_null; + + %%write data; + (void)(eof); + (void)(tsip_machine_parser_header_Require_first_final); + (void)(tsip_machine_parser_header_Require_error); + (void)(tsip_machine_parser_header_Require_en_main); + %%write init; + %%write exec; + + if( cs < %%{ write first_final; }%% ){ + TSK_DEBUG_ERROR("Failed to parse 'Require' header."); + TSK_OBJECT_SAFE_FREE(hdr_require); + } + + return hdr_require; +} + + + + + + + +//======================================================== +// Require header object definition +// + +static tsk_object_t* tsip_header_Require_ctor(tsk_object_t *self, va_list * app) +{ + tsip_header_Require_t *Require = self; + if(Require){ + const char* option; + + TSIP_HEADER(Require)->type = tsip_htype_Require; + TSIP_HEADER(Require)->serialize = tsip_header_Require_serialize; + + if((option = va_arg(*app, const char*))){ + tsk_string_t* string = tsk_string_create(option); + Require->options = tsk_list_create(); + + tsk_list_push_back_data(Require->options, ((void**) &string)); + } + } + else{ + TSK_DEBUG_ERROR("Failed to create new Require header."); + } + return self; +} + +static tsk_object_t* tsip_header_Require_dtor(tsk_object_t *self) +{ + tsip_header_Require_t *Require = self; + if(Require){ + TSK_OBJECT_SAFE_FREE(Require->options); + } + else{ + TSK_DEBUG_ERROR("Null Require header."); + } + + return self; +} + +static const tsk_object_def_t tsip_header_Require_def_s = +{ + sizeof(tsip_header_Require_t), + tsip_header_Require_ctor, + tsip_header_Require_dtor, + tsk_null +}; +const tsk_object_def_t *tsip_header_Require_def_t = &tsip_header_Require_def_s; diff --git a/tinySIP/ragel/tsip_parser_header_Resource_Priority.rl b/tinySIP/ragel/tsip_parser_header_Resource_Priority.rl new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_Resource_Priority.rl @@ -0,0 +1 @@ + diff --git a/tinySIP/ragel/tsip_parser_header_Retry_After.rl b/tinySIP/ragel/tsip_parser_header_Retry_After.rl new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_Retry_After.rl @@ -0,0 +1 @@ + diff --git a/tinySIP/ragel/tsip_parser_header_Route.rl b/tinySIP/ragel/tsip_parser_header_Route.rl new file mode 100644 index 0000000..b777303 --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_Route.rl @@ -0,0 +1,218 @@ +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* DOUBANGO is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with DOUBANGO. +* +*/ + +/**@file tsip_header_Route.c + * @brief SIP Route header. + * + * @author Mamadou Diop + * + + */ +#include "tinysip/headers/tsip_header_Route.h" + +#include "tinysip/parsers/tsip_parser_uri.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" +#include "tsk_time.h" + +#include + + + +/*********************************** +* Ragel state machine. +*/ +%%{ + machine tsip_machine_parser_header_Route; + + # Includes + include tsip_machine_utils "./ragel/tsip_machine_utils.rl"; + + action tag{ + tag_start = p; + } + + action create_route{ + if(!curr_route){ + curr_route = tsip_header_Route_create_null(); + } + } + + action parse_display_name{ + if(curr_route){ + TSK_PARSER_SET_STRING(curr_route->display_name); + tsk_strunquote(&curr_route->display_name); + } + } + + action parse_uri{ + if(curr_route && !curr_route->uri){ + int len = (int)(p - tag_start); + if(curr_route && !curr_route->uri){ + if((curr_route->uri = tsip_uri_parse(tag_start, (tsk_size_t)len)) && curr_route->display_name){ + curr_route->uri->display_name = tsk_strdup(curr_route->display_name); + } + } + } + } + + action parse_param{ + if(curr_route){ + TSK_PARSER_ADD_PARAM(TSIP_HEADER_PARAMS(curr_route)); + } + } + + action add_route{ + if(curr_route){ + tsk_list_push_back_data(hdr_routes, ((void**) &curr_route)); + } + } + + action eob{ + } + + + URI = (scheme HCOLON any+)>tag %parse_uri; + display_name = (( token LWS )+ | quoted_string)>tag %parse_display_name; + my_name_addr = display_name? :>LAQUOT<: URI :>RAQUOT; + + rr_param = (generic_param)>tag %parse_param; + + #route_param = (my_name_addr ( SEMI rr_param )*)>create_route %add_route; + #Route = "Route"i HCOLON route_param (COMMA route_param)*; + + route_value = (my_name_addr ( SEMI rr_param )*) >create_route %add_route; + Route = "Route"i HCOLON route_value (COMMA route_value)*; + + # Entry point + main := Route :>CRLF @eob; + +}%% + +tsip_header_Route_t* tsip_header_Route_create(const tsip_uri_t* uri) +{ + return tsk_object_new(TSIP_HEADER_ROUTE_VA_ARGS(uri)); +} + +tsip_header_Route_t* tsip_header_Route_create_null() +{ + return tsip_header_Route_create(tsk_null); +} + + +int tsip_header_Route_serialize(const tsip_header_t* header, tsk_buffer_t* output) +{ + if(header){ + const tsip_header_Route_t *Route = (const tsip_header_Route_t *)header; + int ret = 0; + + /* Uri with hacked display-name*/ + if((ret = tsip_uri_serialize(Route->uri, tsk_true, tsk_true, output))){ + return ret; + } + + return ret; + } + + return -1; +} + +tsip_header_Routes_L_t *tsip_header_Route_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsip_header_Routes_L_t *hdr_routes = tsk_list_create(); + + const char *tag_start = tsk_null; + tsip_header_Route_t *curr_route = tsk_null; + + %%write data; + (void)(eof); + (void)(tsip_machine_parser_header_Route_first_final); + (void)(tsip_machine_parser_header_Route_error); + (void)(tsip_machine_parser_header_Route_en_main); + %%write init; + %%write exec; + + if( cs < %%{ write first_final; }%% ){ + TSK_DEBUG_ERROR("Failed to parse 'Route' header."); + TSK_OBJECT_SAFE_FREE(curr_route); + TSK_OBJECT_SAFE_FREE(hdr_routes); + } + + return hdr_routes; +} + + + + + +//======================================================== +// Route header object definition +// + +static tsk_object_t* tsip_header_Route_ctor(tsk_object_t *self, va_list * app) +{ + tsip_header_Route_t *Route = self; + if(Route){ + const tsip_uri_t* uri = va_arg(*app, const tsip_uri_t*); + + TSIP_HEADER(Route)->type = tsip_htype_Route; + TSIP_HEADER(Route)->serialize = tsip_header_Route_serialize; + + if(uri){ + Route->uri = tsk_object_ref((void*)uri); + } + } + else{ + TSK_DEBUG_ERROR("Failed to create new Route header."); + } + return self; +} + +static tsk_object_t* tsip_header_Route_dtor(tsk_object_t *self) +{ + tsip_header_Route_t *Route = self; + if(Route){ + TSK_FREE(Route->display_name); + TSK_OBJECT_SAFE_FREE(Route->uri); + + TSK_OBJECT_SAFE_FREE(TSIP_HEADER_PARAMS(Route)); + } + else{ + TSK_DEBUG_ERROR("Null Route header."); + } + + return self; +} + +static const tsk_object_def_t tsip_header_Route_def_s = +{ + sizeof(tsip_header_Route_t), + tsip_header_Route_ctor, + tsip_header_Route_dtor, + tsk_null +}; +const tsk_object_def_t *tsip_header_Route_def_t = &tsip_header_Route_def_s; diff --git a/tinySIP/ragel/tsip_parser_header_SIP_ETag.rl b/tinySIP/ragel/tsip_parser_header_SIP_ETag.rl new file mode 100644 index 0000000..84e68ed --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_SIP_ETag.rl @@ -0,0 +1,163 @@ + +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* DOUBANGO is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with DOUBANGO. +* +*/ + +/**@file tsip_header_SIP_ETag.c + * @brief SIP SIP-ETag header. + * + * @author Mamadou Diop + * + + */ +#include "tinysip/headers/tsip_header_SIP_ETag.h" + +#include "tinysip/parsers/tsip_parser_uri.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" + +#include + + + +/*********************************** +* Ragel state machine. +*/ +%%{ + machine tsip_machine_parser_header_SIP_ETag; + + # Includes + include tsip_machine_utils "./ragel/tsip_machine_utils.rl"; + + action tag{ + tag_start = p; + } + + action parse_etag{ + TSK_PARSER_SET_STRING(hdr_etag->value); + } + + action eob{ + } + + SIP_ETag = "SIP-ETag"i HCOLON token>tag %parse_etag; + + # Entry point + main := SIP_ETag :>CRLF @eob; + +}%% + +tsip_header_SIP_ETag_t* tsip_header_SIP_ETag_create(const char* etag) +{ + return tsk_object_new(TSIP_HEADER_SIP_ETAG_VA_ARGS(etag)); +} + +tsip_header_SIP_ETag_t* tsip_header_SIP_ETag_create_null() +{ + return tsip_header_SIP_ETag_create(tsk_null); +} + +int tsip_header_SIP_ETag_serialize(const tsip_header_t* header, tsk_buffer_t* output) +{ + if(header){ + const tsip_header_SIP_ETag_t *SIP_ETag = (const tsip_header_SIP_ETag_t *)header; + if(SIP_ETag->value){ + return tsk_buffer_append(output, SIP_ETag->value, tsk_strlen(SIP_ETag->value)); + } + return 0; + } + + return -1; +} + +tsip_header_SIP_ETag_t *tsip_header_SIP_ETag_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsip_header_SIP_ETag_t *hdr_etag = tsip_header_SIP_ETag_create_null(); + + const char *tag_start = tsk_null; + + %%write data; + (void)(eof); + (void)(tsip_machine_parser_header_SIP_ETag_first_final); + (void)(tsip_machine_parser_header_SIP_ETag_error); + (void)(tsip_machine_parser_header_SIP_ETag_en_main); + %%write init; + %%write exec; + + if( cs < %%{ write first_final; }%% ){ + TSK_DEBUG_ERROR("Failed to parse 'SIP-ETag' header."); + TSK_OBJECT_SAFE_FREE(hdr_etag); + } + + return hdr_etag; +} + + + + + + + +//======================================================== +// SIP_ETag header object definition +// + +static tsk_object_t* tsip_header_SIP_ETag_ctor(tsk_object_t *self, va_list * app) +{ + tsip_header_SIP_ETag_t *SIP_ETag = self; + if(SIP_ETag){ + TSIP_HEADER(SIP_ETag)->type = tsip_htype_SIP_ETag; + TSIP_HEADER(SIP_ETag)->serialize = tsip_header_SIP_ETag_serialize; + SIP_ETag->value = tsk_strdup(va_arg(*app, const char*)); + } + else{ + TSK_DEBUG_ERROR("Failed to create new SIP_ETag header."); + } + return self; +} + +static tsk_object_t* tsip_header_SIP_ETag_dtor(tsk_object_t *self) +{ + tsip_header_SIP_ETag_t *SIP_ETag = self; + if(SIP_ETag){ + TSK_FREE(SIP_ETag->value); + TSK_OBJECT_SAFE_FREE(TSIP_HEADER_PARAMS(SIP_ETag)); + } + else{ + TSK_DEBUG_ERROR("Null SIP_ETag header."); + } + + return self; +} + +static const tsk_object_def_t tsip_header_SIP_ETag_def_s = +{ + sizeof(tsip_header_SIP_ETag_t), + tsip_header_SIP_ETag_ctor, + tsip_header_SIP_ETag_dtor, + tsk_null +}; +const tsk_object_def_t *tsip_header_SIP_ETag_def_t = &tsip_header_SIP_ETag_def_s; diff --git a/tinySIP/ragel/tsip_parser_header_SIP_If_Match.rl b/tinySIP/ragel/tsip_parser_header_SIP_If_Match.rl new file mode 100644 index 0000000..4fbea6a --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_SIP_If_Match.rl @@ -0,0 +1,165 @@ + +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* DOUBANGO is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with DOUBANGO. +* +*/ + +/**@file tsip_header_SIP_If_Match.c + * @brief SIP SIP-If-Match header. + * + * @author Mamadou Diop + * + + */ +#include "tinysip/headers/tsip_header_SIP_If_Match.h" + +#include "tinysip/parsers/tsip_parser_uri.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" + +#include + + + +/*********************************** +* Ragel state machine. +*/ +%%{ + machine tsip_machine_parser_header_SIP_If_Match; + + # Includes + include tsip_machine_utils "./ragel/tsip_machine_utils.rl"; + + action tag{ + tag_start = p; + } + + action parse_ifmatch{ + TSK_PARSER_SET_STRING(hdr_ifmatch->value); + } + + action eob{ + } + + SIP_If_Match = "SIP-If-Match"i HCOLON token>tag %parse_ifmatch; + + # Entry point + main := SIP_If_Match :>CRLF @eob; + +}%% + + +tsip_header_SIP_If_Match_t* tsip_header_SIP_If_Match_create(const char* etag) +{ + return tsk_object_new(TSIP_HEADER_SIP_IF_MATCH_VA_ARGS(etag)); +} + +tsip_header_SIP_If_Match_t* tsip_header_SIP_If_Match_create_null() +{ + return tsip_header_SIP_If_Match_create(tsk_null); +} + +int tsip_header_SIP_If_Match_serialize(const tsip_header_t* header, tsk_buffer_t* output) +{ + if(header){ + const tsip_header_SIP_If_Match_t *SIP_If_Match = (const tsip_header_SIP_If_Match_t *)header; + if(SIP_If_Match->value){ + return tsk_buffer_append(output, SIP_If_Match->value, tsk_strlen(SIP_If_Match->value)); + } + return 0; + } + + return -1; +} + +tsip_header_SIP_If_Match_t *tsip_header_SIP_If_Match_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsip_header_SIP_If_Match_t *hdr_ifmatch = tsip_header_SIP_If_Match_create_null(); + + const char *tag_start = tsk_null; + + %%write data; + (void)(eof); + (void)(tsip_machine_parser_header_SIP_If_Match_first_final); + (void)(tsip_machine_parser_header_SIP_If_Match_error); + (void)(tsip_machine_parser_header_SIP_If_Match_en_main); + %%write init; + %%write exec; + + if( cs < %%{ write first_final; }%% ){ + TSK_DEBUG_ERROR("Failed to parse 'SIP-If-Match' header."); + TSK_OBJECT_SAFE_FREE(hdr_ifmatch); + } + + return hdr_ifmatch; +} + + + + + + + +//======================================================== +// SIP_If_Match header object definition +// + +static tsk_object_t* tsip_header_SIP_If_Match_ctor(tsk_object_t *self, va_list * app) +{ + tsip_header_SIP_If_Match_t *SIP_If_Match = self; + if(SIP_If_Match){ + TSIP_HEADER(SIP_If_Match)->type = tsip_htype_SIP_If_Match; + TSIP_HEADER(SIP_If_Match)->serialize = tsip_header_SIP_If_Match_serialize; + SIP_If_Match->value = tsk_strdup(va_arg(*app, const char*)); + } + else{ + TSK_DEBUG_ERROR("Failed to create new SIP_If_Match header."); + } + return self; +} + +static tsk_object_t* tsip_header_SIP_If_Match_dtor(tsk_object_t *self) +{ + tsip_header_SIP_If_Match_t *SIP_If_Match = self; + if(SIP_If_Match){ + TSK_FREE(SIP_If_Match->value); + TSK_OBJECT_SAFE_FREE(TSIP_HEADER_PARAMS(SIP_If_Match)); + } + else{ + TSK_DEBUG_ERROR("Null SIP_If_Match header."); + } + + return self; +} + +static const tsk_object_def_t tsip_header_SIP_If_Match_def_s = +{ + sizeof(tsip_header_SIP_If_Match_t), + tsip_header_SIP_If_Match_ctor, + tsip_header_SIP_If_Match_dtor, + tsk_null +}; +const tsk_object_def_t *tsip_header_SIP_If_Match_def_t = &tsip_header_SIP_If_Match_def_s; + diff --git a/tinySIP/ragel/tsip_parser_header_Security_Client.rl b/tinySIP/ragel/tsip_parser_header_Security_Client.rl new file mode 100644 index 0000000..a49b761 --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_Security_Client.rl @@ -0,0 +1,297 @@ +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* DOUBANGO is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with DOUBANGO. +* +*/ + +/**@file tsip_header_Security_Client.c + * @brief SIP Security-Client header as per RFC 3329. + * + * @author Mamadou Diop + * + + */ +#include "tinysip/headers/tsip_header_Security_Client.h" + +#include "tinysip/parsers/tsip_parser_uri.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" +#include "tsk_time.h" + +#include + + + +/*********************************** +* Ragel state machine. +*/ +%%{ + machine tsip_machine_parser_header_Security_Client; + + # Includes + include tsip_machine_utils "./ragel/tsip_machine_utils.rl"; + + action tag{ + tag_start = p; + } + + action create_securityclient{ + if(!curr_securityclient){ + curr_securityclient = tsip_header_Security_Client_create_null(); + } + } + + action add_securityclient{ + if(curr_securityclient){ + tsk_list_push_back_data(hdr_securityclients, ((void**) &curr_securityclient)); + } + } + + action parse_mech{ + if(curr_securityclient){ + TSK_PARSER_SET_STRING(curr_securityclient->mech); + } + } + + action parse_port_s{ + if(curr_securityclient){ + TSK_PARSER_SET_INT(curr_securityclient->port_s); + } + } + + action parse_port_c{ + if(curr_securityclient){ + TSK_PARSER_SET_INT(curr_securityclient->port_c); + } + } + + action parse_spi_s{ + if(curr_securityclient){ + TSK_PARSER_SET_UINT(curr_securityclient->spi_s); + } + } + + action parse_spi_c{ + if(curr_securityclient){ + TSK_PARSER_SET_UINT(curr_securityclient->spi_c); + } + } + + action parse_ealg{ + if(curr_securityclient){ + TSK_PARSER_SET_STRING(curr_securityclient->ealg); + } + } + + action parse_alg{ + if(curr_securityclient){ + TSK_PARSER_SET_STRING(curr_securityclient->alg); + } + } + + action parse_prot{ + if(curr_securityclient){ + TSK_PARSER_SET_STRING(curr_securityclient->prot); + } + } + + action parse_preference{ + if(curr_securityclient){ + TSK_PARSER_SET_DOUBLE(curr_securityclient->q); + } + } + + action parse_param{ + if(curr_securityclient){ + TSK_PARSER_ADD_PARAM(TSIP_HEADER_PARAMS(curr_securityclient)); + } + } + + action eob{ + } + + mech_extension = generic_param>tag %parse_param; + port_s = "port-s"i EQUAL DIGIT+>tag %parse_port_s; + port_c = "port-c"i EQUAL DIGIT+>tag %parse_port_c; + spi_s = "spi-s"i EQUAL DIGIT+>tag %parse_spi_s; + spi_c = "spi-c"i EQUAL DIGIT+>tag %parse_spi_c; + ealg = "ealg"i EQUAL token>tag %parse_ealg; + alg = "alg"i EQUAL token>tag %parse_alg; + prot = "prot"i EQUAL token>tag %parse_prot; + preference = "q"i EQUAL qvalue>tag %parse_preference; + mech_parameters = (preference |prot | alg | ealg | spi_c | spi_s | port_c | port_s) @1 | mech_extension @0; + mechanism_name = token>tag %parse_mech; + sec_mechanism = (mechanism_name ( SEMI mech_parameters )*) >create_securityclient %add_securityclient; + Security_Client = "Security-Client"i HCOLON sec_mechanism ( COMMA sec_mechanism )*; + + # Entry point + main := Security_Client :>CRLF @eob; + +}%% + +tsip_header_Security_Client_t* tsip_header_Security_Client_create(const char* mech, const char* alg, const char* prot, const char* mod, const char* ealg, tnet_port_t port_c, tnet_port_t port_s, uint32_t spi_c, uint32_t spi_s) +{ + return tsk_object_new(TSIP_HEADER_SECURITY_CLIENT_VA_ARGS(mech, alg, prot, mod, ealg, port_c, port_s, spi_c, spi_s)); +} + +tsip_header_Security_Client_t* tsip_header_Security_Client_create_null() +{ + return tsip_header_Security_Client_create(tsk_null, tsk_null, tsk_null, tsk_null, tsk_null, 0, 0, 0, 0); +} + + +int tsip_header_Security_Client_serialize(const tsip_header_t* header, tsk_buffer_t* output) +{ + if(header){ + const tsip_header_Security_Client_t *Security_Client = (const tsip_header_Security_Client_t *)header; + int ret = 0; + + // ipsec-3gpp; alg=hmac-md5-96; ealg=des-ede3-cbc; spi-c=1111; spi-s=2222; port-c=5062; port-s=5064 + if(tsk_striequals(Security_Client->mech, "ipsec-3gpp")){ + ret = tsk_buffer_append_2(output, "%s%s%s%s%s%s%s;spi-c=%u;spi-s=%u;port-c=%u;port-s=%u", + Security_Client->mech, + + Security_Client->alg ? ";alg=" : "", + Security_Client->alg ? Security_Client->alg : "", + + Security_Client->ealg ? ";ealg=" : "", + Security_Client->ealg ? Security_Client->ealg : "", + + Security_Client->prot ? ";prot=" : "", + Security_Client->prot ? Security_Client->prot : "", + + Security_Client->spi_c, + Security_Client->spi_s, + Security_Client->port_c, + Security_Client->port_s + ); + } + else if(Security_Client->mech){ + ret = tsk_buffer_append(output, Security_Client->mech, tsk_strlen(Security_Client->mech)); + } + + if(Security_Client->q >= 0){ + /* qvalue = ("0" [ "." 0*3DIGIT ] ) / ( "1" [ "." 0*3("0") ] ) */ + ret = tsk_buffer_append_2(output, ";q=%1.3f", Security_Client->q); + } + + return ret; + } + + return -1; +} + +tsip_header_Security_Clients_L_t *tsip_header_Security_Client_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsip_header_Security_Clients_L_t *hdr_securityclients = tsk_list_create(); + + const char *tag_start = tsk_null; + tsip_header_Security_Client_t *curr_securityclient = tsk_null; + + %%write data; + (void)(eof); + (void)(tsip_machine_parser_header_Security_Client_first_final); + (void)(tsip_machine_parser_header_Security_Client_error); + (void)(tsip_machine_parser_header_Security_Client_en_main); + %%write init; + %%write exec; + + if( cs < %%{ write first_final; }%% ){ + TSK_DEBUG_ERROR("Failed to parse 'Security-Client' header."); + TSK_OBJECT_SAFE_FREE(curr_securityclient); + TSK_OBJECT_SAFE_FREE(hdr_securityclients); + } + + return hdr_securityclients; +} + + + + + +//======================================================== +// Security_Client header object definition +// + +static tsk_object_t* tsip_header_Security_Client_ctor(tsk_object_t *self, va_list * app) +{ + tsip_header_Security_Client_t *Security_Client = self; + if(Security_Client){ + const char* mech = va_arg(*app, const char*); + + TSIP_HEADER(Security_Client)->type = tsip_htype_Security_Client; + TSIP_HEADER(Security_Client)->serialize = tsip_header_Security_Client_serialize; + + Security_Client->q = -1; + + if(mech){ + Security_Client->mech = tsk_strdup(mech); + Security_Client->alg = tsk_strdup(va_arg(*app, const char*)); + Security_Client->prot = tsk_strdup(va_arg(*app, const char*)); + Security_Client->mod = tsk_strdup(va_arg(*app, const char*)); + Security_Client->ealg = tsk_strdup(va_arg(*app, const char*)); +#if defined(__GNUC__) + Security_Client->port_c = (tnet_port_t)va_arg(*app, unsigned); + Security_Client->port_s = (tnet_port_t)va_arg(*app, unsigned); +#else + Security_Client->port_c = va_arg(*app, tnet_port_t); + Security_Client->port_s = va_arg(*app, tnet_port_t); +#endif + Security_Client->spi_c = va_arg(*app, uint32_t); + Security_Client->spi_s = va_arg(*app, uint32_t); + } + } + else{ + TSK_DEBUG_ERROR("Failed to create new Security_Client header."); + } + return self; +} + +static tsk_object_t* tsip_header_Security_Client_dtor(tsk_object_t *self) +{ + tsip_header_Security_Client_t *Security_Client = self; + if(Security_Client){ + TSK_FREE(Security_Client->mech); + TSK_FREE(Security_Client->alg); + TSK_FREE(Security_Client->prot); + TSK_FREE(Security_Client->mod); + TSK_FREE(Security_Client->ealg); + + TSK_OBJECT_SAFE_FREE(TSIP_HEADER_PARAMS(Security_Client)); + } + else{ + TSK_DEBUG_ERROR("Null Security_Client header."); + } + + return self; +} + +static const tsk_object_def_t tsip_header_Security_Client_def_s = +{ + sizeof(tsip_header_Security_Client_t), + tsip_header_Security_Client_ctor, + tsip_header_Security_Client_dtor, + tsk_null +}; +const tsk_object_def_t *tsip_header_Security_Client_def_t = &tsip_header_Security_Client_def_s; diff --git a/tinySIP/ragel/tsip_parser_header_Security_Server.rl b/tinySIP/ragel/tsip_parser_header_Security_Server.rl new file mode 100644 index 0000000..0693362 --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_Security_Server.rl @@ -0,0 +1,280 @@ + +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* DOUBANGO is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with DOUBANGO. +* +*/ + +/**@file tsip_header_Security_Server.c + * @brief SIP Security-Server header as per RFC 3329. + * + * @author Mamadou Diop + * + + */ +#include "tinysip/headers/tsip_header_Security_Server.h" + +#include "tinysip/parsers/tsip_parser_uri.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" +#include "tsk_time.h" + +#include + + + +/*********************************** +* Ragel state machine. +*/ +%%{ + machine tsip_machine_parser_header_Security_Server; + + # Includes + include tsip_machine_utils "./ragel/tsip_machine_utils.rl"; + + action tag{ + tag_start = p; + } + + action create_securityserver{ + if(!curr_securityserver){ + curr_securityserver = tsip_header_Security_Server_create_null(); + } + } + + action add_securityserver{ + if(curr_securityserver){ + tsk_list_push_back_data(hdr_securityservers, ((void**) &curr_securityserver)); + } + } + + action parse_mech{ + if(curr_securityserver){ + TSK_PARSER_SET_STRING(curr_securityserver->mech); + } + } + + action parse_port_s{ + if(curr_securityserver){ + TSK_PARSER_SET_INT(curr_securityserver->port_s); + } + } + + action parse_port_c{ + if(curr_securityserver){ + TSK_PARSER_SET_INT(curr_securityserver->port_c); + } + } + + action parse_spi_s{ + if(curr_securityserver){ + TSK_PARSER_SET_UINT(curr_securityserver->spi_s); + } + } + + action parse_spi_c{ + if(curr_securityserver){ + TSK_PARSER_SET_UINT(curr_securityserver->spi_c); + } + } + + action parse_ealg{ + if(curr_securityserver){ + TSK_PARSER_SET_STRING(curr_securityserver->ealg); + } + } + + action parse_alg{ + if(curr_securityserver){ + TSK_PARSER_SET_STRING(curr_securityserver->alg); + } + } + + action parse_prot{ + if(curr_securityserver){ + TSK_PARSER_SET_STRING(curr_securityserver->prot); + } + } + + action parse_preference{ + if(curr_securityserver){ + TSK_PARSER_SET_DOUBLE(curr_securityserver->q); + } + } + + action parse_param{ + if(curr_securityserver){ + TSK_PARSER_ADD_PARAM(TSIP_HEADER_PARAMS(curr_securityserver)); + } + } + + action eob{ + } + + mech_extension = generic_param>tag %parse_param; + port_s = "port-s"i EQUAL DIGIT+>tag %parse_port_s; + port_c = "port-c"i EQUAL DIGIT+>tag %parse_port_c; + spi_s = "spi-s"i EQUAL DIGIT+>tag %parse_spi_s; + spi_c = "spi-c"i EQUAL DIGIT+>tag %parse_spi_c; + ealg = "ealg"i EQUAL token>tag %parse_ealg; + alg = "alg"i EQUAL token>tag %parse_alg; + prot = "prot"i EQUAL token>tag %parse_prot; + preference = "q"i EQUAL qvalue>tag %parse_preference; + mech_parameters = (preference | prot | alg | ealg | spi_c | spi_s | port_c | port_s) @1 | mech_extension @0; + mechanism_name = token>tag %parse_mech; + sec_mechanism = (mechanism_name ( SEMI mech_parameters )*) >create_securityserver %add_securityserver; + Security_Server = "Security-Server"i HCOLON sec_mechanism ( COMMA sec_mechanism )*; + + # Entry point + main := Security_Server :>CRLF @eob; + +}%% + +tsip_header_Security_Server_t* tsip_header_Security_Server_create() +{ + return tsk_object_new(TSIP_HEADER_SECURITY_SERVER_VA_ARGS()); +} + +tsip_header_Security_Server_t* tsip_header_Security_Server_create_null() +{ + return tsip_header_Security_Server_create(); +} + +int tsip_header_Security_Server_serialize(const tsip_header_t* header, tsk_buffer_t* output) +{ + if(header){ + const tsip_header_Security_Server_t *Security_Server = (const tsip_header_Security_Server_t *)header; + int ret = 0; + + // ipsec-3gpp; alg=hmac-md5-96; ealg=des-ede3-cbc; spi-c=1111; spi-s=2222; port-c=5062; port-s=5064 + if(tsk_striequals(Security_Server->mech, "ipsec-3gpp")){ + ret = tsk_buffer_append_2(output, "%s%s%s%s%s%s%s;spi-c=%u;spi-s=%u;port-c=%u;port-s=%u", + Security_Server->mech, + + Security_Server->alg ? ";alg=" : "", + Security_Server->alg ? Security_Server->alg : "", + + Security_Server->ealg ? ";ealg=" : "", + Security_Server->ealg ? Security_Server->ealg : "", + + Security_Server->prot ? ";prot=" : "", + Security_Server->prot ? Security_Server->prot : "", + + Security_Server->spi_c, + Security_Server->spi_s, + Security_Server->port_c, + Security_Server->port_s + ); + } + else if(Security_Server->mech){ + ret = tsk_buffer_append(output, Security_Server->mech, tsk_strlen(Security_Server->mech)); + } + + if(Security_Server->q >= 0){ + /* qvalue = ("0" [ "." 0*3DIGIT ] ) / ( "1" [ "." 0*3("0") ] ) */ + ret = tsk_buffer_append_2(output, ";q=%1.3f", Security_Server->q); + } + + return ret; + } + + return -1; +} + + +tsip_header_Security_Servers_L_t *tsip_header_Security_Server_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsip_header_Security_Servers_L_t *hdr_securityservers = tsk_list_create(); + + const char *tag_start = tsk_null; + tsip_header_Security_Server_t *curr_securityserver = tsk_null; + + %%write data; + (void)(eof); + (void)(tsip_machine_parser_header_Security_Server_first_final); + (void)(tsip_machine_parser_header_Security_Server_error); + (void)(tsip_machine_parser_header_Security_Server_en_main); + %%write init; + %%write exec; + + if( cs < %%{ write first_final; }%% ){ + TSK_DEBUG_ERROR("Failed to parse 'Security-Server' header."); + TSK_OBJECT_SAFE_FREE(curr_securityserver); + TSK_OBJECT_SAFE_FREE(hdr_securityservers); + } + + return hdr_securityservers; +} + + + + + +//======================================================== +// Security_Server header object definition +// + +static tsk_object_t* tsip_header_Security_Server_ctor(tsk_object_t *self, va_list * app) +{ + tsip_header_Security_Server_t *Security_Server = self; + if(Security_Server){ + + TSIP_HEADER(Security_Server)->type = tsip_htype_Security_Server; + TSIP_HEADER(Security_Server)->serialize = tsip_header_Security_Server_serialize; + + Security_Server->q = -1; + } + else{ + TSK_DEBUG_ERROR("Failed to create new Security_Server header."); + } + return self; +} + +static tsk_object_t* tsip_header_Security_Server_dtor(tsk_object_t *self) +{ + tsip_header_Security_Server_t *Security_Server = self; + if(Security_Server){ + TSK_FREE(Security_Server->mech); + TSK_FREE(Security_Server->alg); + TSK_FREE(Security_Server->prot); + TSK_FREE(Security_Server->mod); + TSK_FREE(Security_Server->ealg); + + TSK_OBJECT_SAFE_FREE(TSIP_HEADER_PARAMS(Security_Server)); + } + else{ + TSK_DEBUG_ERROR("Null Security_Server header."); + } + + return self; +} + +static const tsk_object_def_t tsip_header_Security_Server_def_s = +{ + sizeof(tsip_header_Security_Server_t), + tsip_header_Security_Server_ctor, + tsip_header_Security_Server_dtor, + tsk_null +}; +const tsk_object_def_t *tsip_header_Security_Server_def_t = &tsip_header_Security_Server_def_s; diff --git a/tinySIP/ragel/tsip_parser_header_Security_Verify.rl b/tinySIP/ragel/tsip_parser_header_Security_Verify.rl new file mode 100644 index 0000000..ea24ee1 --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_Security_Verify.rl @@ -0,0 +1,279 @@ +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* DOUBANGO is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with DOUBANGO. +* +*/ + +/**@file tsip_header_Security_Verify.c + * @brief SIP Security-Verify header as per RFC 3329. + * + * @author Mamadou Diop + * + + */ +#include "tinysip/headers/tsip_header_Security_Verify.h" + +#include "tinysip/parsers/tsip_parser_uri.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" +#include "tsk_time.h" + +#include + + + +/*********************************** +* Ragel state machine. +*/ +%%{ + machine tsip_machine_parser_header_Security_Verify; + + # Includes + include tsip_machine_utils "./ragel/tsip_machine_utils.rl"; + + action tag{ + tag_start = p; + } + + action create_securityverify{ + if(!curr_securityverify){ + curr_securityverify = tsip_header_Security_Verify_create_null(); + } + } + + action add_securityverify{ + if(curr_securityverify){ + tsk_list_push_back_data(hdr_securityverifies, ((void**) &curr_securityverify)); + } + } + + action parse_mech{ + if(curr_securityverify){ + TSK_PARSER_SET_STRING(curr_securityverify->mech); + } + } + + action parse_port_s{ + if(curr_securityverify){ + TSK_PARSER_SET_INT(curr_securityverify->port_s); + } + } + + action parse_port_c{ + if(curr_securityverify){ + TSK_PARSER_SET_INT(curr_securityverify->port_c); + } + } + + action parse_spi_s{ + if(curr_securityverify){ + TSK_PARSER_SET_UINT(curr_securityverify->spi_s); + } + } + + action parse_spi_c{ + if(curr_securityverify){ + TSK_PARSER_SET_UINT(curr_securityverify->spi_c); + } + } + + action parse_ealg{ + if(curr_securityverify){ + TSK_PARSER_SET_STRING(curr_securityverify->ealg); + } + } + + action parse_alg{ + if(curr_securityverify){ + TSK_PARSER_SET_STRING(curr_securityverify->alg); + } + } + + action parse_prot{ + if(curr_securityverify){ + TSK_PARSER_SET_STRING(curr_securityverify->prot); + } + } + + action parse_preference{ + if(curr_securityverify){ + TSK_PARSER_SET_DOUBLE(curr_securityverify->q); + } + } + + action parse_param{ + if(curr_securityverify){ + TSK_PARSER_ADD_PARAM(TSIP_HEADER_PARAMS(curr_securityverify)); + } + } + + action eob{ + } + + mech_extension = generic_param>tag %parse_param; + port_s = "port-s"i EQUAL DIGIT+>tag %parse_port_s; + port_c = "port-c"i EQUAL DIGIT+>tag %parse_port_c; + spi_s = "spi-s"i EQUAL DIGIT+>tag %parse_spi_s; + spi_c = "spi-c"i EQUAL DIGIT+>tag %parse_spi_c; + ealg = "ealg"i EQUAL token>tag %parse_ealg; + alg = "alg"i EQUAL token>tag %parse_alg; + prot = "prot"i EQUAL token>tag %parse_prot; + preference = "q"i EQUAL qvalue>tag %parse_preference; + mech_parameters = (preference | prot | alg | ealg | spi_c | spi_s | port_c | port_s) @1 | mech_extension @0; + mechanism_name = token>tag %parse_mech; + sec_mechanism = (mechanism_name ( SEMI mech_parameters )*) >create_securityverify %add_securityverify; + Security_Verify = "Security-Verify"i HCOLON sec_mechanism ( COMMA sec_mechanism )*; + + # Entry point + main := Security_Verify :>CRLF @eob; + +}%% + +tsip_header_Security_Verify_t* tsip_header_Security_Verify_create() +{ + return tsk_object_new(TSIP_HEADER_SECURITY_VERIFY_VA_ARGS()); +} + +tsip_header_Security_Verify_t* tsip_header_Security_Verify_create_null() +{ + return tsip_header_Security_Verify_create(); +} + +int tsip_header_Security_Verify_serialize(const tsip_header_t* header, tsk_buffer_t* output) +{ + if(header){ + const tsip_header_Security_Verify_t *Security_Verify = (const tsip_header_Security_Verify_t *)header; + int ret = 0; + + // ipsec-3gpp; alg=hmac-md5-96; ealg=des-ede3-cbc; spi-c=1111; spi-s=2222; port-c=5062; port-s=5064 + if(tsk_striequals(Security_Verify->mech, "ipsec-3gpp")){ + ret = tsk_buffer_append_2(output, "%s%s%s%s%s%s%s;spi-c=%u;spi-s=%u;port-c=%u;port-s=%u", + Security_Verify->mech, + + Security_Verify->alg ? ";alg=" : "", + Security_Verify->alg ? Security_Verify->alg : "", + + Security_Verify->ealg ? ";ealg=" : "", + Security_Verify->ealg ? Security_Verify->ealg : "", + + Security_Verify->prot ? ";prot=" : "", + Security_Verify->prot ? Security_Verify->prot : "", + + Security_Verify->spi_c, + Security_Verify->spi_s, + Security_Verify->port_c, + Security_Verify->port_s + ); + } + else if(Security_Verify->mech){ + tsk_buffer_append(output, Security_Verify->mech, tsk_strlen(Security_Verify->mech)); + } + + if(Security_Verify->q >= 0){ + /* qvalue = ("0" [ "." 0*3DIGIT ] ) / ( "1" [ "." 0*3("0") ] ) */ + tsk_buffer_append_2(output, ";q=%1.3f", Security_Verify->q); + } + + return ret; + } + + return -1; +} + +tsip_header_Security_Verifies_L_t *tsip_header_Security_Verify_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsip_header_Security_Verifies_L_t *hdr_securityverifies = tsk_list_create(); + + const char *tag_start = tsk_null; + tsip_header_Security_Verify_t *curr_securityverify = tsk_null; + + %%write data; + (void)(eof); + (void)(tsip_machine_parser_header_Security_Verify_first_final); + (void)(tsip_machine_parser_header_Security_Verify_error); + (void)(tsip_machine_parser_header_Security_Verify_en_main); + %%write init; + %%write exec; + + if( cs < %%{ write first_final; }%% ){ + TSK_DEBUG_ERROR("Failed to parse 'Security-Verify' header."); + TSK_OBJECT_SAFE_FREE(curr_securityverify); + TSK_OBJECT_SAFE_FREE(hdr_securityverifies); + } + + return hdr_securityverifies; +} + + + + + +//======================================================== +// Security_Verify header object definition +// + +static tsk_object_t* tsip_header_Security_Verify_ctor(tsk_object_t *self, va_list * app) +{ + tsip_header_Security_Verify_t *Security_Verify = self; + if(Security_Verify){ + + TSIP_HEADER(Security_Verify)->type = tsip_htype_Security_Verify; + TSIP_HEADER(Security_Verify)->serialize = tsip_header_Security_Verify_serialize; + + Security_Verify->q = -1; + } + else{ + TSK_DEBUG_ERROR("Failed to create new Security_Verify header."); + } + return self; +} + +static tsk_object_t* tsip_header_Security_Verify_dtor(tsk_object_t *self) +{ + tsip_header_Security_Verify_t *Security_Verify = self; + if(Security_Verify){ + TSK_FREE(Security_Verify->mech); + TSK_FREE(Security_Verify->alg); + TSK_FREE(Security_Verify->prot); + TSK_FREE(Security_Verify->mod); + TSK_FREE(Security_Verify->ealg); + + TSK_OBJECT_SAFE_FREE(TSIP_HEADER_PARAMS(Security_Verify)); + } + else{ + TSK_DEBUG_ERROR("Null Security_Verify header."); + } + + return self; +} + +static const tsk_object_def_t tsip_header_Security_Verify_def_s = +{ + sizeof(tsip_header_Security_Verify_t), + tsip_header_Security_Verify_ctor, + tsip_header_Security_Verify_dtor, + tsk_null +}; +const tsk_object_def_t *tsip_header_Security_Verify_def_t = &tsip_header_Security_Verify_def_s; + diff --git a/tinySIP/ragel/tsip_parser_header_Server.rl b/tinySIP/ragel/tsip_parser_header_Server.rl new file mode 100644 index 0000000..fdee795 --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_Server.rl @@ -0,0 +1,167 @@ +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* DOUBANGO is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with DOUBANGO. +* +*/ + +/**@file tsip_header_Server.c + * @brief SIP Server header. + * + * @author Mamadou Diop + * + + */ +#include "tinysip/headers/tsip_header_Server.h" + +#include "tinysip/parsers/tsip_parser_uri.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" + +#include + + + +/*********************************** +* Ragel state machine. +*/ +%%{ + machine tsip_machine_parser_header_Server; + + # Includes + include tsip_machine_utils "./ragel/tsip_machine_utils.rl"; + + action tag{ + tag_start = p; + } + + action parse_server{ + TSK_PARSER_SET_STRING(hdr_server->value); + } + + action eob{ + } + + # product_version = token; + # product = token ( SLASH product_version )?; + # server_val = product | comment; + # Server = "Server"i HCOLON (server_val ( LWS server_val )*)>tag %parse_server; + + Server = "Server"i HCOLON (any*)>tag %parse_server; + + # Entry point + main := Server :>CRLF @eob; + +}%% + +tsip_header_Server_t* tsip_header_server_create(const char* server) +{ + return tsk_object_new(TSIP_HEADER_SERVER_VA_ARGS(server)); +} + +tsip_header_Server_t* tsip_header_server_create_null() +{ + return tsip_header_server_create(tsk_null); +} + +int tsip_header_Server_serialize(const tsip_header_t* header, tsk_buffer_t* output) +{ + if(header){ + const tsip_header_Server_t *Server = (const tsip_header_Server_t *)header; + if(Server->value){ + return tsk_buffer_append(output, Server->value, tsk_strlen(Server->value)); + } + return 0; + } + + return -1; +} + +tsip_header_Server_t *tsip_header_Server_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsip_header_Server_t *hdr_server = tsip_header_server_create_null(); + + const char *tag_start = tsk_null; + + %%write data; + (void)(eof); + (void)(tsip_machine_parser_header_Server_first_final); + (void)(tsip_machine_parser_header_Server_error); + (void)(tsip_machine_parser_header_Server_en_main); + %%write init; + %%write exec; + + if( cs < %%{ write first_final; }%% ){ + TSK_DEBUG_ERROR("Failed to parse 'Server' header."); + TSK_OBJECT_SAFE_FREE(hdr_server); + } + + return hdr_server; +} + + + + + + + +//======================================================== +// Server header object definition +// + +static tsk_object_t* tsip_header_Server_ctor(tsk_object_t *self, va_list * app) +{ + tsip_header_Server_t *Server = self; + if(Server){ + TSIP_HEADER(Server)->type = tsip_htype_Server; + TSIP_HEADER(Server)->serialize = tsip_header_Server_serialize; + Server->value = tsk_strdup(va_arg(*app, const char*)); + } + else{ + TSK_DEBUG_ERROR("Failed to create new Server header."); + } + return self; +} + +static tsk_object_t* tsip_header_Server_dtor(tsk_object_t *self) +{ + tsip_header_Server_t *Server = self; + if(Server){ + TSK_FREE(Server->value); + TSK_OBJECT_SAFE_FREE(TSIP_HEADER_PARAMS(Server)); + } + else{ + TSK_DEBUG_ERROR("Null Server header."); + } + + return self; +} + +static const tsk_object_def_t tsip_header_Server_def_s = +{ + sizeof(tsip_header_Server_t), + tsip_header_Server_ctor, + tsip_header_Server_dtor, + tsk_null +}; +const tsk_object_def_t *tsip_header_Server_def_t = &tsip_header_Server_def_s; diff --git a/tinySIP/ragel/tsip_parser_header_Service_Route.rl b/tinySIP/ragel/tsip_parser_header_Service_Route.rl new file mode 100644 index 0000000..eacc654 --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_Service_Route.rl @@ -0,0 +1,213 @@ +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* DOUBANGO is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with DOUBANGO. +* +*/ + +/**@file tsip_header_Service_Route.c + * @brief SIP Service-Route header as per RFC 3608. + * + * @author Mamadou Diop + * + + */ +#include "tinysip/headers/tsip_header_Service_Route.h" + +#include "tinysip/parsers/tsip_parser_uri.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" +#include "tsk_time.h" + +#include + + + +/*********************************** +* Ragel state machine. +*/ +%%{ + machine tsip_machine_parser_header_Service_Route; + + # Includes + include tsip_machine_utils "./ragel/tsip_machine_utils.rl"; + + action tag{ + tag_start = p; + } + + action create_service{ + if(!curr_service){ + curr_service = tsip_header_Service_Route_create_null(); + } + } + + action parse_display_name{ + if(curr_service){ + TSK_PARSER_SET_STRING(curr_service->display_name); + tsk_strunquote(&curr_service->display_name); + } + } + + action parse_uri{ + if(curr_service && !curr_service->uri){ + int len = (int)(p - tag_start); + if(curr_service && !curr_service->uri){ + if((curr_service->uri = tsip_uri_parse(tag_start, (tsk_size_t)len)) && curr_service->display_name){ + curr_service->uri->display_name = tsk_strdup(curr_service->display_name); + } + } + } + } + + action parse_param{ + if(curr_service){ + TSK_PARSER_ADD_PARAM(TSIP_HEADER_PARAMS(curr_service)); + } + } + + action add_service{ + if(curr_service){ + tsk_list_push_back_data(hdr_services, ((void**) &curr_service)); + } + } + + action eob{ + } + + + URI = (scheme HCOLON any+)>tag %parse_uri; + display_name = (( token LWS )+ | quoted_string)>tag %parse_display_name; + my_name_addr = display_name? :>LAQUOT<: URI :>RAQUOT; + + rr_param = (generic_param)>tag %parse_param; + + sr_value = (my_name_addr ( SEMI rr_param )*) >create_service %add_service; + Service_Route = "Service-Route" HCOLON sr_value (COMMA sr_value)*; + + # Entry point + main := Service_Route :>CRLF @eob; + +}%% + +tsip_header_Service_Route_t* tsip_header_Service_Route_create(const tsip_uri_t* uri) +{ + return tsk_object_new(TSIP_HEADER_SERVICE_ROUTE_VA_ARGS(uri)); +} + +tsip_header_Service_Route_t* tsip_header_Service_Route_create_null() +{ + return tsip_header_Service_Route_create(tsk_null); +} + +int tsip_header_Service_Route_serialize(const tsip_header_t* header, tsk_buffer_t* output) +{ + if(header){ + const tsip_header_Service_Route_t *Service_Route = (const tsip_header_Service_Route_t *)header; + int ret = 0; + + /* Uri with hacked display-name*/ + if((ret = tsip_uri_serialize(Service_Route->uri, tsk_true, tsk_true, output))){ + return ret; + } + + return ret; + } + + return -1; +} + +tsip_header_Service_Routes_L_t *tsip_header_Service_Route_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsip_header_Service_Routes_L_t *hdr_services = tsk_list_create(); + + const char *tag_start = tsk_null; + tsip_header_Service_Route_t *curr_service = tsk_null; + + %%write data; + (void)(eof); + (void)(tsip_machine_parser_header_Service_Route_first_final); + (void)(tsip_machine_parser_header_Service_Route_error); + (void)(tsip_machine_parser_header_Service_Route_en_main); + %%write init; + %%write exec; + + if( cs < %%{ write first_final; }%% ){ + TSK_DEBUG_ERROR("Failed to parse 'Service-Route' header."); + TSK_OBJECT_SAFE_FREE(curr_service); + TSK_OBJECT_SAFE_FREE(hdr_services); + } + + return hdr_services; +} + + + + + +//======================================================== +// Service_Route header object definition +// + +static tsk_object_t* tsip_header_Service_Route_ctor(tsk_object_t *self, va_list * app) +{ + tsip_header_Service_Route_t *Service_Route = self; + if(Service_Route){ + const tsip_uri_t* uri = va_arg(*app, const tsip_uri_t*); + + TSIP_HEADER(Service_Route)->type = tsip_htype_Service_Route; + TSIP_HEADER(Service_Route)->serialize = tsip_header_Service_Route_serialize; + if(uri){ + Service_Route->uri = tsk_object_ref((void*)uri); + } + } + else{ + TSK_DEBUG_ERROR("Failed to create new Service_Route header."); + } + return self; +} + +static tsk_object_t* tsip_header_Service_Route_dtor(tsk_object_t *self) +{ + tsip_header_Service_Route_t *Service_Route = self; + if(Service_Route){ + TSK_FREE(Service_Route->display_name); + TSK_OBJECT_SAFE_FREE(Service_Route->uri); + + TSK_OBJECT_SAFE_FREE(TSIP_HEADER_PARAMS(Service_Route)); + } + else{ + TSK_DEBUG_ERROR("Null Service_Route header."); + } + + return self; +} + +static const tsk_object_def_t tsip_header_Service_Route_def_s = +{ + sizeof(tsip_header_Service_Route_t), + tsip_header_Service_Route_ctor, + tsip_header_Service_Route_dtor, + tsk_null +}; +const tsk_object_def_t *tsip_header_Service_Route_def_t = &tsip_header_Service_Route_def_s; diff --git a/tinySIP/ragel/tsip_parser_header_Session_Expires.rl b/tinySIP/ragel/tsip_parser_header_Session_Expires.rl new file mode 100644 index 0000000..9b266a4 --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_Session_Expires.rl @@ -0,0 +1,172 @@ + + +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* DOUBANGO is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with DOUBANGO. +* +*/ + +/**@file tsip_header_Session_Expires.c + * @brief SIP Min-SE header. + * + * @author Mamadou Diop + * + + */ +#include "tinysip/headers/tsip_header_Session_Expires.h" + +#include "tinysip/parsers/tsip_parser_uri.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" + + + +/*********************************** +* Ragel state machine. +*/ +%%{ + machine tsip_machine_parser_header_Session_Expires; + + # Includes + include tsip_machine_utils "./ragel/tsip_machine_utils.rl"; + + action tag{ + tag_start = p; + } + + action parse_delta_seconds{ + TSK_PARSER_SET_INTEGER(hdr_session_expires->delta_seconds); + } + + action is_uas{ + hdr_session_expires->refresher_uas = tsk_true; + } + action is_uac{ + hdr_session_expires->refresher_uas = tsk_false; + } + + action parse_param{ + TSK_PARSER_ADD_PARAM(TSIP_HEADER_PARAMS(hdr_session_expires)); + } + + action eob{ + } + + refresher_param = "refresher"i EQUAL ( "uas"i>tag %is_uas | "uac"i>tag %is_uac ); + se_params = (refresher_param)@1 | (generic_param)@0>tag %parse_param; + Session_Expires = ( "Session-Expires"i | "x"i ) HCOLON delta_seconds>tag %parse_delta_seconds ( SEMI se_params )*; + + # Entry point + main := Session_Expires :>CRLF @eob; + +}%% + +tsip_header_Session_Expires_t* tsip_header_Session_Expires_create(int64_t delta_seconds, tsk_bool_t refresher_uas) +{ + return tsk_object_new(TSIP_HEADER_SESSION_EXPIRES_VA_ARGS(delta_seconds, refresher_uas)); +} + +int tsip_header_Session_Expires_serialize(const tsip_header_t* header, tsk_buffer_t* output) +{ + if(header){ + const tsip_header_Session_Expires_t *Session_Expires = (const tsip_header_Session_Expires_t *)header; + if(Session_Expires->delta_seconds >=0){ + return tsk_buffer_append_2(output, "%lld;refresher=%s", + Session_Expires->delta_seconds, Session_Expires->refresher_uas ? "uas" : "uac"); + } + return 0; + } + + return -1; +} + +tsip_header_Session_Expires_t *tsip_header_Session_Expires_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsip_header_Session_Expires_t *hdr_session_expires = tsip_header_Session_Expires_create(TSIP_SESSION_EXPIRES_DEFAULT_VALUE, tsk_false); + + const char *tag_start = tsk_null; + + %%write data; + (void)(eof); + (void)(tsip_machine_parser_header_Session_Expires_first_final); + (void)(tsip_machine_parser_header_Session_Expires_error); + (void)(tsip_machine_parser_header_Session_Expires_en_main); + %%write init; + %%write exec; + + if( cs < %%{ write first_final; }%% ){ + TSK_DEBUG_ERROR("Failed to parse 'Session-Expires' header."); + TSK_OBJECT_SAFE_FREE(hdr_session_expires); + } + + return hdr_session_expires; +} + + + + + + + +//======================================================== +// Session_Expires header object definition +// + +static tsk_object_t* tsip_header_Session_Expires_ctor(tsk_object_t *self, va_list * app) +{ + tsip_header_Session_Expires_t *Session_Expires = self; + if(Session_Expires){ + TSIP_HEADER(Session_Expires)->type = tsip_htype_Session_Expires; + TSIP_HEADER(Session_Expires)->serialize = tsip_header_Session_Expires_serialize; + Session_Expires->delta_seconds = va_arg(*app, int64_t); + Session_Expires->refresher_uas = va_arg(*app, tsk_bool_t); + } + else{ + TSK_DEBUG_ERROR("Failed to create new Session-Expires header."); + } + return self; +} + +static tsk_object_t* tsip_header_Session_Expires_dtor(tsk_object_t *self) +{ + tsip_header_Session_Expires_t *Session_Expires = self; + if(Session_Expires){ + TSK_OBJECT_SAFE_FREE(TSIP_HEADER_PARAMS(Session_Expires)); + } + else{ + TSK_DEBUG_ERROR("Null Session-Expires header."); + } + + return self; +} + +static const tsk_object_def_t tsip_header_Session_Expires_def_s = +{ + sizeof(tsip_header_Session_Expires_t), + tsip_header_Session_Expires_ctor, + tsip_header_Session_Expires_dtor, + tsk_null +}; +const tsk_object_def_t *tsip_header_Session_Expires_def_t = &tsip_header_Session_Expires_def_s; + diff --git a/tinySIP/ragel/tsip_parser_header_Subject.rl b/tinySIP/ragel/tsip_parser_header_Subject.rl new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_Subject.rl @@ -0,0 +1 @@ + diff --git a/tinySIP/ragel/tsip_parser_header_Subscription_State.rl b/tinySIP/ragel/tsip_parser_header_Subscription_State.rl new file mode 100644 index 0000000..d310f9b --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_Subscription_State.rl @@ -0,0 +1,189 @@ +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* DOUBANGO is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with DOUBANGO. +* +*/ + +/**@file tsip_header_Subscription_State.c + * @brief SIP Subscription_State header. + * + * @author Mamadou Diop + * + + */ +#include "tinysip/headers/tsip_header_Subscription_State.h" + +#include "tinysip/parsers/tsip_parser_uri.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" + + + +/*********************************** +* Ragel state machine. +*/ +%%{ + machine tsip_machine_parser_header_Subscription_State; + + # Includes + include tsip_machine_utils "./ragel/tsip_machine_utils.rl"; + + action tag{ + tag_start = p; + } + + action parse_state{ + TSK_PARSER_SET_STRING(hdr_Subscription_State->state); + } + + action parse_reason{ + TSK_PARSER_SET_STRING(hdr_Subscription_State->reason); + } + + action parse_expires{ + TSK_PARSER_SET_INTEGER(hdr_Subscription_State->expires); + } + + action parse_retry_after{ + TSK_PARSER_SET_INTEGER(hdr_Subscription_State->retry_after); + } + + action parse_param{ + TSK_PARSER_ADD_PARAM(TSIP_HEADER_PARAMS(hdr_Subscription_State)); + } + + action eob{ + } + + subexp_params = (( "reason"i EQUAL token>tag %parse_reason ) | ( "expires"i EQUAL delta_seconds>tag %parse_expires ) | ( "retry-after"i EQUAL delta_seconds>tag %parse_retry_after ))@1 | generic_param>tag %parse_param @0; + Subscription_State = ( "Subscription-State"i ) HCOLON token>tag %parse_state ( SEMI subexp_params )*; + + # Entry point + main := Subscription_State :>CRLF @eob; + +}%% + +tsip_header_Subscription_State_t* tsip_header_Subscription_State_create() +{ + return tsk_object_new(tsip_header_Subscription_State_def_t); +} + + +int tsip_header_Subscription_State_serialize(const tsip_header_t* header, tsk_buffer_t* output) +{ + if(header){ + const tsip_header_Subscription_State_t *Subscription_State = (const tsip_header_Subscription_State_t *)header; + int ret; + + ret = tsk_buffer_append_2(output, "%s%s%s", + Subscription_State->state, + + Subscription_State->reason ? ";reason=" : "", + Subscription_State->reason ? Subscription_State->reason : "" + ); + if(!ret && Subscription_State->expires>=0){ + ret = tsk_buffer_append_2(output, ";expires=%d", Subscription_State->expires); + } + if(!ret && Subscription_State->retry_after>=0){ + ret = tsk_buffer_append_2(output, ";retry-after=%d", Subscription_State->retry_after); + } + + return ret; + } + + return -1; +} + +tsip_header_Subscription_State_t *tsip_header_Subscription_State_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsip_header_Subscription_State_t *hdr_Subscription_State = tsip_header_Subscription_State_create(); + + const char *tag_start = tsk_null; + + %%write data; + (void)(eof); + (void)(tsip_machine_parser_header_Subscription_State_first_final); + (void)(tsip_machine_parser_header_Subscription_State_error); + (void)(tsip_machine_parser_header_Subscription_State_en_main); + %%write init; + %%write exec; + + if( cs < %%{ write first_final; }%% ){ + TSK_DEBUG_ERROR("Failed to parse 'Subscription-State' header."); + TSK_OBJECT_SAFE_FREE(hdr_Subscription_State); + } + + return hdr_Subscription_State; +} + + + + + + + +//======================================================== +// Subscription_State header object definition +// + +static tsk_object_t* tsip_header_Subscription_State_ctor(tsk_object_t *self, va_list * app) +{ + tsip_header_Subscription_State_t *Subscription_State = self; + if(Subscription_State){ + TSIP_HEADER(Subscription_State)->type = tsip_htype_Subscription_State; + TSIP_HEADER(Subscription_State)->serialize = tsip_header_Subscription_State_serialize; + + Subscription_State->expires = -1; + Subscription_State->retry_after = -1; + } + else{ + TSK_DEBUG_ERROR("Failed to create new Subscription_State header."); + } + return self; +} + +static tsk_object_t* tsip_header_Subscription_State_dtor(tsk_object_t *self) +{ + tsip_header_Subscription_State_t *Subscription_State = self; + if(Subscription_State){ + TSK_FREE(Subscription_State->state); + TSK_FREE(Subscription_State->reason); + + TSK_OBJECT_SAFE_FREE(TSIP_HEADER_PARAMS(Subscription_State)); + } + else{ + TSK_DEBUG_ERROR("Null Subscription_State header."); + } + + return self; +} + +static const tsk_object_def_t tsip_header_Subscription_State_def_s = +{ + sizeof(tsip_header_Subscription_State_t), + tsip_header_Subscription_State_ctor, + tsip_header_Subscription_State_dtor, + tsk_null +}; +const tsk_object_def_t *tsip_header_Subscription_State_def_t = &tsip_header_Subscription_State_def_s; diff --git a/tinySIP/ragel/tsip_parser_header_Supported.rl b/tinySIP/ragel/tsip_parser_header_Supported.rl new file mode 100644 index 0000000..6ee87d3 --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_Supported.rl @@ -0,0 +1,180 @@ +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* DOUBANGO is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with DOUBANGO. +* +*/ + +/**@file tsip_header_Supported.c + * @brief SIP Supported/k header. + * + * @author Mamadou Diop + * + + */ +#include "tinysip/headers/tsip_header_Supported.h" + +#include "tinysip/parsers/tsip_parser_uri.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" + +#include + + + +/*********************************** +* Ragel state machine. +*/ +%%{ + machine tsip_machine_parser_header_Supported; + + # Includes + include tsip_machine_utils "./ragel/tsip_machine_utils.rl"; + + action tag{ + tag_start = p; + } + + action parse_option{ + TSK_PARSER_ADD_STRING(hdr_supported->options); + } + + action eob{ + } + + Supported = ( "Supported"i | "k"i ) HCOLON ( option_tag>tag %parse_option ( COMMA option_tag>tag %parse_option )* )?; + + # Entry point + main := Supported :>CRLF @eob; + +}%% + +tsip_header_Supported_t* tsip_header_Supported_create(const char* option) +{ + return tsk_object_new(TSIP_HEADER_SUPPORTED_VA_ARGS(option)); +} + +tsip_header_Supported_t* tsip_header_Supported_create_null() +{ + return tsip_header_Supported_create(tsk_null); +} + +int tsip_header_Supported_serialize(const tsip_header_t* header, tsk_buffer_t* output) +{ + if(header){ + const tsip_header_Supported_t *Supported = (const tsip_header_Supported_t *)header; + tsk_list_item_t *item; + tsk_string_t *str; + int ret = 0; + + tsk_list_foreach(item, Supported->options){ + str = item->data; + if(item == Supported->options->head){ + ret = tsk_buffer_append(output, str->value, tsk_strlen(str->value)); + } + else{ + ret = tsk_buffer_append_2(output, ",%s", str->value); + } + } + + return ret; + } + + return -1; +} + +tsip_header_Supported_t *tsip_header_Supported_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsip_header_Supported_t *hdr_supported = tsip_header_Supported_create_null(); + + const char *tag_start = tsk_null; + + %%write data; + (void)(eof); + (void)(tsip_machine_parser_header_Supported_first_final); + (void)(tsip_machine_parser_header_Supported_error); + (void)(tsip_machine_parser_header_Supported_en_main); + %%write init; + %%write exec; + + if( cs < %%{ write first_final; }%% ){ + TSK_DEBUG_ERROR("Failed to parse 'Supported' header."); + TSK_OBJECT_SAFE_FREE(hdr_supported); + } + + return hdr_supported; +} + + + + + + + +//======================================================== +// Supported header object definition +// + +static tsk_object_t* tsip_header_Supported_ctor(tsk_object_t *self, va_list * app) +{ + tsip_header_Supported_t *Supported = self; + if(Supported){ + const char* option; + + TSIP_HEADER(Supported)->type = tsip_htype_Supported; + TSIP_HEADER(Supported)->serialize = tsip_header_Supported_serialize; + + if((option = va_arg(*app, const char*))){ + tsk_string_t* string = tsk_string_create(option); + Supported->options = tsk_list_create(); + + tsk_list_push_back_data(Supported->options, ((void**) &string)); + } + } + else{ + TSK_DEBUG_ERROR("Failed to create new Supported header."); + } + return self; +} + +static tsk_object_t* tsip_header_Supported_dtor(tsk_object_t *self) +{ + tsip_header_Supported_t *Supported = self; + if(Supported){ + TSK_OBJECT_SAFE_FREE(Supported->options); + } + else{ + TSK_DEBUG_ERROR("Null Supported header."); + } + + return self; +} + +static const tsk_object_def_t tsip_header_Supported_def_s = +{ + sizeof(tsip_header_Supported_t), + tsip_header_Supported_ctor, + tsip_header_Supported_dtor, + tsk_null +}; +const tsk_object_def_t *tsip_header_Supported_def_t = &tsip_header_Supported_def_s; diff --git a/tinySIP/ragel/tsip_parser_header_Target_Dialog.rl b/tinySIP/ragel/tsip_parser_header_Target_Dialog.rl new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_Target_Dialog.rl @@ -0,0 +1 @@ + diff --git a/tinySIP/ragel/tsip_parser_header_Timestamp.rl b/tinySIP/ragel/tsip_parser_header_Timestamp.rl new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_Timestamp.rl @@ -0,0 +1 @@ + diff --git a/tinySIP/ragel/tsip_parser_header_To.rl b/tinySIP/ragel/tsip_parser_header_To.rl new file mode 100644 index 0000000..9099469 --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_To.rl @@ -0,0 +1,200 @@ +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* DOUBANGO is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with DOUBANGO. +* +*/ + +/**@file tsip_header_To.c + * @brief SIP To/t header. + * + * @author Mamadou Diop + * + + */ +#include "tinysip/headers/tsip_header_To.h" + +#include "tinysip/parsers/tsip_parser_uri.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" + + + +/*********************************** +* Ragel state machine. +*/ +%%{ + machine tsip_machine_parser_header_To; + + # Includes + include tsip_machine_utils "./ragel/tsip_machine_utils.rl"; + + action tag{ + tag_start = p; + } + + action parse_uri{ + int len = (int)(p - tag_start); + if(hdr_to && !hdr_to->uri){ + if((hdr_to->uri = tsip_uri_parse(tag_start, (tsk_size_t)len)) && hdr_to->display_name){ + hdr_to->uri->display_name = tsk_strdup(hdr_to->display_name); + } + } + } + + action parse_display_name{ + TSK_PARSER_SET_STRING(hdr_to->display_name); + tsk_strunquote(&hdr_to->display_name); + } + + action parse_tag{ + TSK_PARSER_SET_STRING(hdr_to->tag); + } + + action parse_param{ + TSK_PARSER_ADD_PARAM(TSIP_HEADER_PARAMS(hdr_to)); + } + + action eob{ + } + + my_tag_param = "tag"i EQUAL token>tag %parse_tag; + to_param = my_tag_param@1 | (generic_param)@0 >tag %parse_param; + + URI = (scheme HCOLON any+)>tag %parse_uri; + display_name = (( token LWS )+ | quoted_string)>tag %parse_display_name; + my_name_addr = display_name? :>LAQUOT<: URI :>RAQUOT; + + To = ( "To"i | "t"i ) HCOLON ( my_name_addr | URI ) ( SEMI to_param )*; + + # Entry point + main := To :>CRLF @eob; + +}%% + +tsip_header_To_t* tsip_header_To_create(const char* display_name, const tsip_uri_t* uri, const char* tag) +{ + return tsk_object_new(TSIP_HEADER_TO_VA_ARGS(display_name, uri, tag)); +} + +tsip_header_To_t* tsip_header_To_create_null() +{ + return tsip_header_To_create(tsk_null, tsk_null, tsk_null); +} + +int tsip_header_To_serialize(const tsip_header_t* header, tsk_buffer_t* output) +{ + if(header){ + int ret = 0; + const tsip_header_To_t *To = (const tsip_header_To_t *)header; + + /* Uri with hacked display-name*/ + if((ret = tsip_uri_serialize(To->uri, tsk_true, tsk_true, output))){ + return ret; + } + if(To->tag && (ret = tsk_buffer_append_2(output, ";tag=%s", To->tag))){ + return ret; + } + return ret; + } + return -1; +} + +tsip_header_To_t *tsip_header_To_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsip_header_To_t *hdr_to = tsip_header_To_create_null(); + + const char *tag_start = tsk_null; + + %%write data; + (void)(eof); + (void)(tsip_machine_parser_header_To_first_final); + (void)(tsip_machine_parser_header_To_error); + (void)(tsip_machine_parser_header_To_en_main); + %%write init; + %%write exec; + + if( cs < %%{ write first_final; }%% ){ + TSK_DEBUG_ERROR("Failed to parse 'To' header."); + TSK_OBJECT_SAFE_FREE(hdr_to); + } + + return hdr_to; +} + + + + + + + +//======================================================== +// To header object definition +// + +static tsk_object_t* tsip_header_To_ctor(tsk_object_t *self, va_list * app) +{ + tsip_header_To_t *To = self; + if(To){ + const char* display_name = va_arg(*app, const char *); + const tsip_uri_t* uri = va_arg(*app, const tsip_uri_t *); + const char* tag = va_arg(*app, const char *); + + To->display_name = tsk_strdup(display_name); + if(uri) To->uri = tsk_object_ref((void *)uri); + To->tag = tsk_strdup(tag); + + TSIP_HEADER(To)->type = tsip_htype_To; + TSIP_HEADER(To)->serialize = tsip_header_To_serialize; + } + else{ + TSK_DEBUG_ERROR("Failed to create new To header."); + } + return self; +} + +static tsk_object_t* tsip_header_To_dtor(tsk_object_t *self) +{ + tsip_header_To_t *To = self; + if(To){ + TSK_FREE(To->display_name); + TSK_FREE(To->tag); + + TSK_OBJECT_SAFE_FREE(To->uri); + TSK_OBJECT_SAFE_FREE(TSIP_HEADER_PARAMS(To)); + } + else{ + TSK_DEBUG_ERROR("Null To header."); + } + + return self; +} + +static const tsk_object_def_t tsip_header_To_def_s = +{ + sizeof(tsip_header_To_t), + tsip_header_To_ctor, + tsip_header_To_dtor, + tsk_null +}; +const tsk_object_def_t *tsip_header_To_def_t = &tsip_header_To_def_s; diff --git a/tinySIP/ragel/tsip_parser_header_Unsupported.rl b/tinySIP/ragel/tsip_parser_header_Unsupported.rl new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_Unsupported.rl @@ -0,0 +1 @@ + diff --git a/tinySIP/ragel/tsip_parser_header_User_Agent.rl b/tinySIP/ragel/tsip_parser_header_User_Agent.rl new file mode 100644 index 0000000..028ecff --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_User_Agent.rl @@ -0,0 +1,160 @@ +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* DOUBANGO is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with DOUBANGO. +* +*/ + +/**@file tsip_header_User_Agent.c + * @brief SIP User-Agent/t header. + * + * @author Mamadou Diop + * + + */ +#include "tinysip/headers/tsip_header_User_Agent.h" + +#include "tinysip/parsers/tsip_parser_uri.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" + +#include + +/*********************************** +* Ragel state machine. +*/ +%%{ + machine tsip_machine_parser_header_User_Agent; + + # Includes + include tsip_machine_utils "./ragel/tsip_machine_utils.rl"; + + action tag{ + tag_start = p; + } + + action parse_user_agent{ + TSK_PARSER_SET_STRING(hdr_user_agent->value); + } + + action eob{ + } + + User_Agent = "User-Agent"i HCOLON (any*)>tag %parse_user_agent; + + # Entry point + main := User_Agent :>CRLF @eob; + +}%% + +tsip_header_User_Agent_t* tsip_header_User_Agent_create(const char* ua) +{ + return tsk_object_new(TSIP_HEADER_USER_AGENT_VA_ARGS(ua)); +} + +tsip_header_User_Agent_t* tsip_header_User_Agent_create_null() +{ + return tsip_header_User_Agent_create(tsk_null); +} + +int tsip_header_User_Agent_serialize(const tsip_header_t* header, tsk_buffer_t* output) +{ + if(header){ + const tsip_header_User_Agent_t *User_Agent = (const tsip_header_User_Agent_t *)header; + if(User_Agent->value){ + return tsk_buffer_append(output, User_Agent->value, tsk_strlen(User_Agent->value)); + } + return 0; + } + + return -1; +} + +tsip_header_User_Agent_t *tsip_header_User_Agent_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsip_header_User_Agent_t *hdr_user_agent = tsip_header_User_Agent_create_null(); + + const char *tag_start = tsk_null; + + %%write data; + (void)(eof); + (void)(tsip_machine_parser_header_User_Agent_first_final); + (void)(tsip_machine_parser_header_User_Agent_error); + (void)(tsip_machine_parser_header_User_Agent_en_main); + %%write init; + %%write exec; + + if( cs < %%{ write first_final; }%% ){ + TSK_DEBUG_ERROR("Failed to parse 'User-Agent' header."); + TSK_OBJECT_SAFE_FREE(hdr_user_agent); + } + + return hdr_user_agent; +} + + + + + + + +//======================================================== +// User_Agent header object definition +// + +static tsk_object_t* tsip_header_User_Agent_ctor(tsk_object_t *self, va_list * app) +{ + tsip_header_User_Agent_t *User_Agent = self; + if(User_Agent){ + TSIP_HEADER(User_Agent)->type = tsip_htype_User_Agent; + TSIP_HEADER(User_Agent)->serialize = tsip_header_User_Agent_serialize; + User_Agent->value = tsk_strdup(va_arg(*app, const char*)); + } + else{ + TSK_DEBUG_ERROR("Failed to create new User_Agent header."); + } + return self; +} + +static tsk_object_t* tsip_header_User_Agent_dtor(tsk_object_t *self) +{ + tsip_header_User_Agent_t *User_Agent = self; + if(User_Agent){ + TSK_FREE(User_Agent->value); + TSK_OBJECT_SAFE_FREE(TSIP_HEADER_PARAMS(User_Agent)); + } + else{ + TSK_DEBUG_ERROR("Null User_Agent header."); + } + + return self; +} + +static const tsk_object_def_t tsip_header_User_Agent_def_s = +{ + sizeof(tsip_header_User_Agent_t), + tsip_header_User_Agent_ctor, + tsip_header_User_Agent_dtor, + tsk_null +}; +const tsk_object_def_t *tsip_header_User_Agent_def_t = &tsip_header_User_Agent_def_s; diff --git a/tinySIP/ragel/tsip_parser_header_Via.rl b/tinySIP/ragel/tsip_parser_header_Via.rl new file mode 100644 index 0000000..d7a0b56 --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_Via.rl @@ -0,0 +1,345 @@ +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* DOUBANGO is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with DOUBANGO. +* +*/ + +/**@file tsip_header_Via.c + * @brief SIP Via/v header as per RFC 3261 subclause 20.42. + * + * @author Mamadou Diop + * + + */ +#include "tinysip/headers/tsip_header_Via.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" + + + +/*********************************** +* Ragel state machine. +*/ +%%{ + machine tsip_machine_parser_header_Via; + + # Includes + include tsip_machine_utils "./ragel/tsip_machine_utils.rl"; + + + action tag{ + tag_start = p; + } + + action create_via{ + if(!curr_via){ + curr_via = tsip_header_Via_create_null(); + } + } + + action parse_protocol_name{ + TSK_PARSER_SET_STRING(curr_via->proto_name); + } + + action parse_protocol_version{ + TSK_PARSER_SET_STRING(curr_via->proto_version); + } + + action parse_host{ + TSK_PARSER_SET_STRING(curr_via->host); + if(curr_via->host && *curr_via->host == '['){ + tsk_strunquote_2(&curr_via->host, '[', ']'); + } + } + + action parse_port{ + TSK_PARSER_SET_INTEGER(curr_via->port); + } + + action parse_transport{ + TSK_PARSER_SET_STRING(curr_via->transport); + } + + action parse_ttl{ + TSK_PARSER_SET_INTEGER(curr_via->ttl); + } + + action parse_maddr{ + TSK_PARSER_SET_STRING(curr_via->maddr); + } + + action parse_received{ + TSK_PARSER_SET_STRING(curr_via->received); + } + + action parse_branch{ + TSK_PARSER_SET_STRING(curr_via->branch); + } + + action parse_comp{ + TSK_PARSER_SET_STRING(curr_via->comp); + } + + action parse_rport{ + TSK_PARSER_SET_INTEGER(curr_via->rport); + } + + action has_rport{ + if(curr_via->rport <0){ + curr_via->rport = 0; + } + } + + action parse_param{ + TSK_PARSER_ADD_PARAM(TSIP_HEADER_PARAMS(curr_via)); + } + + action add_via{ + if(curr_via){ + tsk_list_push_back_data(hdr_vias, ((void**) &curr_via)); + } + } + + action eob{ + + } + + protocol_name = "SIP"i | token >tag %parse_protocol_name; + protocol_version = token >tag %parse_protocol_version; + transport = ("UDP"i | "TCP"i | "TLS"i | "SCTP"i | "TLS-SCTP"i | other_transport) >tag %parse_transport; + sent_protocol = protocol_name SLASH protocol_version SLASH transport; + sent_by = host>tag %parse_host ( COLON port >tag %parse_port )?; + via_ttl = "ttl"i EQUAL ttl >tag %parse_ttl; + via_maddr = "maddr"i EQUAL host >tag %parse_maddr; + via_received = "received"i EQUAL ( IPv4address | IPv6address )>tag %parse_received; + via_branch = "branch"i EQUAL token >tag %parse_branch; + via_compression = "comp"i EQUAL ( "sigcomp"i | other_compression )>tag %parse_comp; + response_port = "rport"i ( EQUAL DIGIT+ >tag %parse_rport )? %has_rport; + via_extension = (generic_param) >tag %parse_param; + via_params = (via_ttl | via_maddr | via_received | via_branch | via_compression | response_port)@1 | (via_extension)@0; + via_parm = (sent_protocol LWS sent_by ( SEMI via_params )*) >create_via %add_via; + Via = ( "Via"i | "v"i ) HCOLON via_parm ( COMMA via_parm )*; + + # Entry point + main := Via :>CRLF @eob; +}%% + + +tsip_header_Via_t* tsip_header_Via_create(const char* proto_name, const char* proto_version, const char* transport, const char* host, uint16_t port) +{ + return tsk_object_new(TSIP_HEADER_VIA_VA_ARGS(proto_name, proto_version, transport, host, port)); +} +tsip_header_Via_t* tsip_header_Via_create_null() +{ + return tsip_header_Via_create(tsk_null, tsk_null, tsk_null, tsk_null, 0); +} + +int tsip_header_Via_serialize(const tsip_header_t* header, tsk_buffer_t* output) +{ + if(header){ + const tsip_header_Via_t *Via = (const tsip_header_Via_t *)header; + tsk_istr_t port, rport, ttl; + int ipv6 = (Via->host && tsk_strcontains(Via->host, tsk_strlen(Via->host), ":")); + + if(Via->port){ + tsk_itoa(Via->port, &port); + } + if(Via->rport){ + tsk_itoa(Via->rport, &rport); + } + if(Via->ttl){ + tsk_itoa(Via->ttl, &ttl); + } + + /* SIP/2.0/UDP [::]:1988;test=1234;comp=sigcomp;rport=254;ttl=457;received=192.0.2.101;branch=z9hG4bK1245420841406\r\n" */ + return tsk_buffer_append_2(output, "%s/%s/%s %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", + + Via->proto_name ? Via->proto_name : "SIP", + + Via->proto_version ? Via->proto_version : "2.0", + + Via->transport ? Via->transport : "UDP", + + ipv6 ? "[" : "", + Via->host ? Via->host : "127.0.0.1", + ipv6 ? "]" : "", + + Via->port ? ":" : "", + Via->port ? port : "", + + Via->maddr ? ";maddr=" : "", + Via->maddr ? Via->maddr : "", + + Via->sigcomp_id ? ";sigcomp-id=" : "", + Via->sigcomp_id ? Via->sigcomp_id : "", + + Via->comp ? ";comp=" : "", + Via->comp ? Via->comp : "", + + Via->rport>=0 ? (Via->rport>0?";rport=":";rport") : "", + Via->rport>0 ? rport : "", + + Via->ttl>=0 ? (Via->ttl>0?";ttl=":";ttl") : "", + Via->ttl>0 ? ttl : "", + + Via->received ? ";received=" : "", + Via->received ? Via->received : "", + + Via->branch ? ";branch=" : "", + Via->branch ? Via->branch : "" + ); + } + return -1; +} + +char* tsip_header_Via_get_special_param_value(const tsip_header_t* header, const char* pname) +{ + if(header){ + const tsip_header_Via_t *Via = (const tsip_header_Via_t *)header; + if(tsk_striequals(pname, "maddr")){ + return tsk_strdup(Via->maddr); + } + else if(tsk_striequals(pname, "sigcomp-id")){ + return tsk_strdup(Via->sigcomp_id); + } + else if(tsk_striequals(pname, "comp")){ + return tsk_strdup(Via->comp); + } + else if(tsk_striequals(pname, "rport")){ + tsk_istr_t rport; + tsk_itoa(Via->rport, &rport); + + return tsk_strdup(rport); + } + else if(tsk_striequals(pname, "received")){ + return tsk_strdup(Via->received); + } + else if(tsk_striequals(pname, "branch")){ + return tsk_strdup(Via->branch); + } + } + return tsk_null; +} + +tsip_header_Vias_L_t *tsip_header_Via_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsip_header_Vias_L_t *hdr_vias = tsk_list_create(); + tsip_header_Via_t *curr_via = tsk_null; + + const char *tag_start = tsk_null; + + %%write data; + (void)(eof); + (void)(tsip_machine_parser_header_Via_first_final); + (void)(tsip_machine_parser_header_Via_error); + (void)(tsip_machine_parser_header_Via_en_main); + %%write init; + %%write exec; + + if( cs < %%{ write first_final; }%% ){ + TSK_DEBUG_ERROR("Failed to parse 'Via' header."); + TSK_OBJECT_SAFE_FREE(curr_via); + TSK_OBJECT_SAFE_FREE(hdr_vias); + } + + return hdr_vias; +} + + + + + + + + + + + +//======================================================== +// Via header object definition +// + +static tsk_object_t* tsip_header_Via_ctor(tsk_object_t *self, va_list * app) +{ + tsip_header_Via_t *via = self; + if(via){ + const char* proto_name = va_arg(*app, const char *); + const char* proto_version = va_arg(*app, const char *); + const char* transport = va_arg(*app, const char *); + const char* host = va_arg(*app, const char *); +#if defined(__GNUC__) + uint16_t port = (uint16_t)va_arg(*app, unsigned); +#else + uint16_t port = va_arg(*app, uint16_t); +#endif + + if(proto_name) via->proto_name = tsk_strdup(proto_name); + if(proto_version) via->proto_version = tsk_strdup(proto_version); + if(transport) via->transport = tsk_strdup(transport); + if(host) via->host = tsk_strdup(host); + via->port = port; + + via->rport = -1; + via->ttl = -1; + + TSIP_HEADER(via)->type = tsip_htype_Via; + TSIP_HEADER(via)->serialize = tsip_header_Via_serialize; + TSIP_HEADER(via)->get_special_param_value = tsip_header_Via_get_special_param_value; + } + else{ + TSK_DEBUG_ERROR("Failed to create new Via header."); + } + return self; +} + +static tsk_object_t* tsip_header_Via_dtor(tsk_object_t *self) +{ + tsip_header_Via_t *via = self; + if(via){ + TSK_FREE(via->branch); + TSK_FREE(via->comp); + TSK_FREE(via->host); + TSK_FREE(via->maddr); + TSK_FREE(via->proto_name); + TSK_FREE(via->proto_version); + TSK_FREE(via->received); + TSK_FREE(via->sigcomp_id); + TSK_FREE(via->transport); + TSK_OBJECT_SAFE_FREE(TSIP_HEADER_PARAMS(via)); + } + else{ + TSK_DEBUG_ERROR("Null Via header."); + } + + return self; +} + +static const tsk_object_def_t tsip_header_Via_def_s = +{ + sizeof(tsip_header_Via_t), + tsip_header_Via_ctor, + tsip_header_Via_dtor, + tsk_null +}; +const tsk_object_def_t *tsip_header_Via_def_t = &tsip_header_Via_def_s; diff --git a/tinySIP/ragel/tsip_parser_header_WWW_Authenticate.rl b/tinySIP/ragel/tsip_parser_header_WWW_Authenticate.rl new file mode 100644 index 0000000..5c8200d --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_WWW_Authenticate.rl @@ -0,0 +1,244 @@ +///* +//* Copyright (C) 2010-2011 Mamadou Diop. +//* +//* Contact: Mamadou Diop +//* +//* This file is part of Open Source Doubango Framework. +//* +//* DOUBANGO is free software: you can redistribute it and/or modify +//* it under the terms of the GNU General Public License as published by +//* the Free Software Foundation, either version 3 of the License, or +//* (at your option) any later version. +//* +//* DOUBANGO is distributed in the hope that it will be useful, +//* but WITHOUT ANY WARRANTY; without even the implied warranty of +//* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +//* GNU General Public License for more details. +//* +//* You should have received a copy of the GNU General Public License +//* along with DOUBANGO. +//* +//*/ +// +///**@file tsip_header_WWW_Authenticate.c +// * @brief SIP WWW-Authenticate header. +// * +// * @author Mamadou Diop +// * +// +// */ +//#include "tinysip/headers/tsip_header_WWW_Authenticate.h" +// +//#include "tinysip/parsers/tsip_parser_uri.h" +// +//#include "tsk_debug.h" +//#include "tsk_memory.h" +//#include "tsk_time.h" +// +//#include +// +// +///*********************************** +//* Ragel state machine. +//*/ +//%%{ +// machine tsip_machine_parser_header_WWW_Authenticate; +// +// # Includes +// include tsip_machine_utils "./ragel/tsip_machine_utils.rl"; +// +// action tag +// { +// tag_start = p; +// } +// +// action is_digest +// { +// #//FIXME: Only Digest is supported +// hdr_WWW_Authenticate->scheme = tsk_strdup("Digest"); +// } +// +// action parse_realm +// { +// TSK_PARSER_SET_STRING(hdr_WWW_Authenticate->realm); +// tsk_strunquote(&hdr_WWW_Authenticate->realm); +// } +// +// action parse_domain +// { +// TSK_PARSER_SET_STRING(hdr_WWW_Authenticate->domain); +// //tsk_strunquote(&hdr_WWW_Authenticate->domain); +// } +// +// action parse_nonce +// { +// TSK_PARSER_SET_STRING(hdr_WWW_Authenticate->nonce); +// tsk_strunquote(&hdr_WWW_Authenticate->nonce); +// } +// +// action parse_opaque +// { +// TSK_PARSER_SET_STRING(hdr_WWW_Authenticate->opaque); +// tsk_strunquote(&hdr_WWW_Authenticate->opaque); +// } +// +// action parse_stale +// { +// hdr_WWW_Authenticate->stale = tsk_strniequals(tag_start, "true", 4); +// } +// +// action parse_algorithm +// { +// TSK_PARSER_SET_STRING(hdr_WWW_Authenticate->algorithm); +// } +// +// action parse_qop +// { +// TSK_PARSER_SET_STRING(hdr_WWW_Authenticate->qop); +// //tsk_strunquote(&hdr_WWW_Authenticate->qop); +// } +// +// action parse_param +// { +// TSK_PARSER_ADD_PARAM(TSIP_HEADER_PARAMS(hdr_WWW_Authenticate)); +// } +// +// action eob +// { +// } +// +// #FIXME: Only Digest (MD5, AKAv1-MD5 and AKAv2-MD5) is supported +// other_challenge = (any+); +// auth_param = generic_param>tag %parse_param; +// +// realm = "realm"i EQUAL quoted_string>tag %parse_realm; +// domain = "domain"i EQUAL LDQUOT <: (any*)>tag %parse_domain :> RDQUOT; +// nonce = "nonce"i EQUAL quoted_string>tag %parse_nonce; +// opaque = "opaque"i EQUAL quoted_string>tag %parse_opaque; +// stale = "stale"i EQUAL ( "true"i | "false"i )>tag %parse_stale; +// algorithm = "algorithm"i EQUAL <:token>tag %parse_algorithm; +// qop_options = "qop"i EQUAL LDQUOT <: (any*)>tag %parse_qop :> RDQUOT; +// +// digest_cln = (realm | domain | nonce | opaque | stale | algorithm | qop_options)@1 | auth_param@0; +// challenge = ( "Digest"i LWS digest_cln ( COMMA <:digest_cln )* )>is_digest | other_challenge; +// WWW_Authenticate = "WWW-Authenticate"i HCOLON challenge; +// +// # Entry point +// main := WWW_Authenticate :>CRLF @eob; +// +//}%% +// +//int tsip_header_WWW_Authenticate_serialize(const tsip_header_t* header, tsk_buffer_t* output) +//{ +// if(header) +// { +// const tsip_header_WWW_Authenticate_t *WWW_Authenticate = header; +// if(WWW_Authenticate && WWW_Authenticate->scheme) +// { +// return tsk_buffer_append_2(output, "%s realm=\"%s\"%s%s%s%s%s%s%s%s%s%s%s%s,stale=%s%s%s", +// WWW_Authenticate->scheme, +// WWW_Authenticate->realm ? WWW_Authenticate->realm : "", +// +// WWW_Authenticate->domain ? ",domain=\"" : "", +// WWW_Authenticate->domain ? WWW_Authenticate->domain : "", +// WWW_Authenticate->domain ? "\"" : "", +// +// +// WWW_Authenticate->qop ? ",qop=\"" : "", +// WWW_Authenticate->qop ? WWW_Authenticate->qop : "", +// WWW_Authenticate->qop ? "\"" : "", +// +// +// WWW_Authenticate->nonce ? ",nonce=\"" : "", +// WWW_Authenticate->nonce ? WWW_Authenticate->nonce : "", +// WWW_Authenticate->nonce ? "\"" : "", +// +// WWW_Authenticate->opaque ? ",opaque=\"" : "", +// WWW_Authenticate->opaque ? WWW_Authenticate->opaque : "", +// WWW_Authenticate->opaque ? "\"" : "", +// +// WWW_Authenticate->stale ? "TRUE" : "FALSE", +// +// WWW_Authenticate->algorithm ? ",algorithm=" : "", +// WWW_Authenticate->algorithm ? WWW_Authenticate->algorithm : "" +// ); +// } +// } +// return -1; +//} +// +//tsip_header_WWW_Authenticate_t *tsip_header_WWW_Authenticate_parse(const char *data, tsk_size_t size) +//{ +// int cs = 0; +// const char *p = data; +// const char *pe = p + size; +// const char *eof = pe; +// tsip_header_WWW_Authenticate_t *hdr_WWW_Authenticate = TSIP_HEADER_WWW_AUTHENTICATE_CREATE(); +// +// const char *tag_start = tsk_null; +// +// %%write data; +// %%write init; +// %%write exec; +// +// if( cs < %%{ write first_final; }%% ) +// { +// TSK_OBJECT_SAFE_FREE(hdr_WWW_Authenticate); +// } +// +// return hdr_WWW_Authenticate; +//} +// +// +// +// +// +// +// +////======================================================== +//// WWW_Authenticate header object definition +//// +// +//static tsk_object_t* tsip_header_WWW_Authenticate_ctor(tsk_object_t *self, va_list * app) +//{ +// tsip_header_WWW_Authenticate_t *WWW_Authenticate = self; +// if(WWW_Authenticate) +// { +// TSIP_HEADER(WWW_Authenticate)->type = tsip_htype_WWW_Authenticate; +// TSIP_HEADER(WWW_Authenticate)->serialize = tsip_header_WWW_Authenticate_serialize; +// } +// else +// { +// TSK_DEBUG_ERROR("Failed to create new WWW_Authenticate header."); +// } +// return self; +//} +// +//static tsk_object_t* tsip_header_WWW_Authenticate_dtor(tsk_object_t *self) +//{ +// tsip_header_WWW_Authenticate_t *WWW_Authenticate = self; +// if(WWW_Authenticate) +// { +// TSK_FREE(WWW_Authenticate->scheme); +// TSK_FREE(WWW_Authenticate->realm); +// TSK_FREE(WWW_Authenticate->domain); +// TSK_FREE(WWW_Authenticate->nonce); +// TSK_FREE(WWW_Authenticate->opaque); +// TSK_FREE(WWW_Authenticate->algorithm); +// TSK_FREE(WWW_Authenticate->qop); +// +// TSK_OBJECT_SAFE_FREE(TSIP_HEADER_PARAMS(WWW_Authenticate)); +// } +// else TSK_DEBUG_ERROR("Null WWW_Authenticate header."); +// +// return self; +//} +// +//static const tsk_object_def_t tsip_header_WWW_Authenticate_def_s = +//{ +// sizeof(tsip_header_WWW_Authenticate_t), +// tsip_header_WWW_Authenticate_ctor, +// tsip_header_WWW_Authenticate_dtor, +// 0 +//}; +//const void *tsip_header_WWW_Authenticate_def_t = &tsip_header_WWW_Authenticate_def_s; diff --git a/tinySIP/ragel/tsip_parser_header_Warning.rl b/tinySIP/ragel/tsip_parser_header_Warning.rl new file mode 100644 index 0000000..8158a7d --- /dev/null +++ b/tinySIP/ragel/tsip_parser_header_Warning.rl @@ -0,0 +1,190 @@ +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* DOUBANGO is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with DOUBANGO. +* +*/ + +/**@file tsip_header_Warning.c + * @brief SIP Warning header. + * + * @author Mamadou Diop + * + + */ +#include "tinysip/headers/tsip_header_Warning.h" + +#include "tinysip/parsers/tsip_parser_uri.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" +#include "tsk_time.h" + +#include + + + +/*********************************** +* Ragel state machine. +*/ +%%{ + machine tsip_machine_parser_header_Warning; + + # Includes + include tsip_machine_utils "./ragel/tsip_machine_utils.rl"; + + action tag{ + tag_start = p; + } + + action create_warning{ + if(!curr_warning){ + curr_warning = tsip_header_Warning_create(); + } + } + + action parse_agent{ + if(curr_warning){ + TSK_PARSER_SET_STRING(curr_warning->agent); + } + } + + action parse_text{ + if(curr_warning){ + TSK_PARSER_SET_STRING(curr_warning->text); + } + } + + action parse_code{ + if(curr_warning){ + TSK_PARSER_SET_INTEGER(curr_warning->code); + } + } + + action add_warning{ + if(curr_warning){ + tsk_list_push_back_data(hdr_warnings, ((void**) &curr_warning)); + } + } + + action eob{ + } + + warn_code = DIGIT{3}; + pseudonym = token; + warn_agent = hostport | pseudonym; + warn_text = quoted_string; + warning_value = (warn_code>tag %parse_code :>SP warn_agent>tag %parse_agent :>SP warn_text>tag %parse_text) >create_warning %add_warning; + Warning = "Warning"i HCOLON warning_value ( COMMA warning_value )*; + + # Entry point + main := Warning :>CRLF @eob; + +}%% + +tsip_header_Warning_t* tsip_header_Warning_create() +{ + return tsk_object_new(tsip_header_Warning_def_t); +} + +int tsip_header_Warning_serialize(const tsip_header_t* header, tsk_buffer_t* output) +{ + if(header){ + const tsip_header_Warning_t *Warning = (const tsip_header_Warning_t *)header; + return tsk_buffer_append_2(output, "%d %s %s", + Warning->code, Warning->agent, Warning->text); /* warn-code SP warn-agent SP warn-text */ + } + + return -1; +} + +tsip_header_Warnings_L_t *tsip_header_Warning_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + tsip_header_Warnings_L_t *hdr_warnings = tsk_list_create(); + + const char *tag_start = tsk_null; + tsip_header_Warning_t *curr_warning = 0; + + %%write data; + (void)(eof); + (void)(tsip_machine_parser_header_Warning_first_final); + (void)(tsip_machine_parser_header_Warning_error); + (void)(tsip_machine_parser_header_Warning_en_main); + %%write init; + %%write exec; + + if( cs < %%{ write first_final; }%% ){ + TSK_DEBUG_ERROR("Failed to parse 'Warning' header."); + TSK_OBJECT_SAFE_FREE(curr_warning); + TSK_OBJECT_SAFE_FREE(hdr_warnings); + } + + return hdr_warnings; +} + + + + + +//======================================================== +// Warning header object definition +// + +static tsk_object_t* tsip_header_Warning_ctor(tsk_object_t *self, va_list * app) +{ + tsip_header_Warning_t *Warning = self; + if(Warning){ + TSIP_HEADER(Warning)->type = tsip_htype_Warning; + TSIP_HEADER(Warning)->serialize = tsip_header_Warning_serialize; + + Warning->code = -1; + } + else{ + TSK_DEBUG_ERROR("Failed to create new Warning header."); + } + return self; +} + +static tsk_object_t* tsip_header_Warning_dtor(tsk_object_t *self) +{ + tsip_header_Warning_t *Warning = self; + if(Warning){ + TSK_FREE(Warning->agent); + TSK_FREE(Warning->text); + + TSK_OBJECT_SAFE_FREE(TSIP_HEADER_PARAMS(Warning)); + } + else{ + TSK_DEBUG_ERROR("Null Warning header."); + } + + return self; +} + +static const tsk_object_def_t tsip_header_Warning_def_s = +{ + sizeof(tsip_header_Warning_t), + tsip_header_Warning_ctor, + tsip_header_Warning_dtor, + tsk_null +}; +const tsk_object_def_t *tsip_header_Warning_def_t = &tsip_header_Warning_def_s; diff --git a/tinySIP/ragel/tsip_parser_message.rl b/tinySIP/ragel/tsip_parser_message.rl new file mode 100644 index 0000000..65be9d4 --- /dev/null +++ b/tinySIP/ragel/tsip_parser_message.rl @@ -0,0 +1,275 @@ +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* DOUBANGO is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with DOUBANGO. +* +*/ + +/**@file tsip_parser_message.c + * @brief SIP parser. + * + * @author Mamadou Diop + * + + */ +#include "tinysip/parsers/tsip_parser_message.h" +#include "tinysip/parsers/tsip_parser_header.h" + +#include "tinysip/parsers/tsip_parser_uri.h" + +#include "tsk_debug.h" +#include "tsk_memory.h" + +static void tsip_message_parser_execute(tsk_ragel_state_t *state, tsip_message_t *message, tsk_bool_t extract_content); +static void tsip_message_parser_init(tsk_ragel_state_t *state); +static void tsip_message_parser_eoh(tsk_ragel_state_t *state, tsip_message_t *message, tsk_bool_t extract_content); + +// Check if we have ",CRLF" ==> See WWW-Authenticate header +// As :>CRLF is preceded by any+ ==> p will be at least (start + 1) +// p point to CR +#define prev_not_comma(p) !(p && p[-1] == ',') + +/*********************************** +* Ragel state machine. +*/ +%%{ + machine tsip_machine_parser_message; + + #/* Tag the buffer (start point). */ + action tag + { + state->tag_start = p; + } + + #/* SIP method */ + action parse_method + { + int len; + state->tag_end = p; + len = (int)(state->tag_end - state->tag_start); + + if(message->type == tsip_unknown) + { + message->type = tsip_request; + if(!message->line.request.method) + { + message->line.request.method = tsk_calloc(1, len+1); + memcpy(message->line.request.method, state->tag_start, len); + message->line.request.request_type = tsip_request_get_type(message->line.request.method); + } + } + else + { + state->cs = tsip_machine_parser_message_error; + } + } + + #/* Request URI parsing */ + action parse_requesturi + { + int len; + state->tag_end = p; + len = (int)(state->tag_end - state->tag_start); + + if(!message->line.request.uri) + { + message->line.request.uri = tsip_uri_parse(state->tag_start, (tsk_size_t)len); + } + } + + #/* Sip Version */ + action parse_sipversion + { + int len; + state->tag_end = p; + len = (int)(state->tag_end - state->tag_start); + + if(!message->sip_version) + { + message->sip_version = tsk_calloc(1, len+1); + memcpy(message->sip_version, state->tag_start, len); + } + } + + #/* Status Code */ + action parse_status_code + { + int len; + state->tag_end = p; + len = (int)(state->tag_end - state->tag_start); + + if(message->type == tsip_unknown) + { + message->type = tsip_response; + message->line.response.status_code = atoi(state->tag_start); + } + else + { + state->cs = tsip_machine_parser_message_error; + } + } + + #/* Reason Phrase */ + action parse_reason_phrase + { + int len; + state->tag_end = p; + len = (int)(state->tag_end - state->tag_start); + + if(!message->line.response.reason_phrase) + { + message->line.response.reason_phrase = tsk_calloc(1, len+1); + memcpy(message->line.response.reason_phrase, state->tag_start, len); + } + } + + #/* Parse sip header */ + action parse_header + { + int len; + state->tag_end = p; + len = (int)(state->tag_end - state->tag_start); + + if(tsip_header_parse(state, message)){ + //TSK_DEBUG_INFO("TSIP_MESSAGE_PARSER::PARSE_HEADER len=%d state=%d", len, state->cs); + } + else{ + TSK_DEBUG_ERROR("Failed to parse header - %s", state->tag_start); + } + } + + #/* Parse sip content/body. */ + #action parse_body + #{ + # int len; + # state->tag_end = p; + # len = (int)(state->tag_end - state->tag_start); + # TSK_DEBUG_ERROR("==TSIP_MESSAGE_PARSER::PARSE_BODY=="); + #} + + #/* End-Of-Headers */ + action eoh + { + state->cs = cs; + state->p = p; + state->pe = pe; + state->eof = eof; + + tsip_message_parser_eoh(state, message, extract_content); + + cs = state->cs; + p = state->p; + pe = state->pe; + eof = state->eof; + } + + # Includes + include tsip_machine_utils "./ragel/tsip_machine_utils.rl"; + include tsip_machine_message "./ragel/tsip_machine_message.rl"; + + # Entry point + main := SIP_message; +}%% + + +/* Regel data */ +%%write data; + + +tsk_bool_t tsip_message_parse(tsk_ragel_state_t *state, tsip_message_t **result, tsk_bool_t extract_content) +{ + if(!state || state->pe <= state->p){ + return tsk_false; + } + + if(!*result){ + *result = tsip_message_create(); + } + + /* Ragel init */ + tsip_message_parser_init(state); + + /* + * State mechine execution. + */ + tsip_message_parser_execute(state, *result, extract_content); + + /* Check result */ + + if( state->cs < %%{ write first_final; }%% ) + { + TSK_DEBUG_ERROR("Failed to parse SIP message: %s", state->p); + TSK_OBJECT_SAFE_FREE(*result); + return tsk_false; + } + return tsk_true; +} + + +static void tsip_message_parser_init(tsk_ragel_state_t *state) +{ + int cs = 0; + + /* Regel machine initialization. */ + %% write init; + + state->cs = cs; +} + +static void tsip_message_parser_execute(tsk_ragel_state_t *state, tsip_message_t *message, tsk_bool_t extract_content) +{ + int cs = state->cs; + const char *p = state->p; + const char *pe = state->pe; + const char *eof = state->eof; + + %% write exec; + + state->cs = cs; + state->p = p; + state->pe = pe; + state->eof = eof; +} + +static void tsip_message_parser_eoh(tsk_ragel_state_t *state, tsip_message_t *message, tsk_bool_t extract_content) +{ + int cs = state->cs; + const char *p = state->p; + const char *pe = state->pe; + const char *eof = state->eof; + const char *eoh = (state->p + 1); + + if(extract_content && message) + { + uint32_t clen = TSIP_MESSAGE_CONTENT_LENGTH(message); + if((p+clen) Content){ + message->Content = tsk_buffer_create((p+1), clen); + p = (p+clen); + } + else{ + p = (pe-1); + } + } + //%%write eof; + + state->cs = cs; + state->p = p; + state->pe = pe; + state->eof = eof; + state->eoh = eoh; +} diff --git a/tinySIP/ragel/tsip_parser_uri.rl b/tinySIP/ragel/tsip_parser_uri.rl new file mode 100644 index 0000000..418f8ed --- /dev/null +++ b/tinySIP/ragel/tsip_parser_uri.rl @@ -0,0 +1,180 @@ +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* DOUBANGO is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with DOUBANGO. +* +*/ + +/**@file tsip_parser_uri.c + * @brief SIP/SIPS/TEL URI parser. + * + * @author Mamadou Diop + * + + */ +#include "tinysip/parsers/tsip_parser_uri.h" + +#include "tsk_string.h" +#include "tsk_memory.h" +#include "tsk_debug.h" + +/*********************************** +* Ragel state machine. +*/ +%%{ + machine tsip_machine_parser_uri; + + # Includes + include tsip_machine_utils "./ragel/tsip_machine_utils.rl"; + #include tsip_machine_userinfo; + + action tag{ + tag_start = p; + } + + #/* Sets URI type */ + action is_sip { uri->scheme = tsk_strdup("sip"), uri->type = uri_sip; } + action is_sips { uri->scheme = tsk_strdup("sips"), uri->type = uri_sips; } + action is_tel { uri->scheme = tsk_strdup("tel"), uri->type = uri_tel; } + + #/* Sets HOST type */ + action is_ipv4 { uri->host_type = host_ipv4; } + action is_ipv6 { uri->host_type = host_ipv6; } + action is_hostname { uri->host_type = host_hostname; } + + action parse_scheme{ + TSK_PARSER_SET_STRING(uri->scheme); + } + + action parse_user_name{ + TSK_PARSER_SET_STRING(uri->user_name); + } + + action parse_password{ + TSK_PARSER_SET_STRING(uri->password); + } + + action parse_host{ + TSK_PARSER_SET_STRING(uri->host); + } + + action parse_port{ + TSK_PARSER_SET_INTEGER(uri->port); + } + + action parse_param{ + TSK_PARSER_ADD_PARAM(uri->params); + } + + action eob{ + } + + my_uri_parameter = (pname ( "=" pvalue )?) >tag %parse_param; + uri_parameters = ( ";" my_uri_parameter )*; + + sip_usrinfo := ( ( user>tag %parse_user_name ) :> ( ':' password>tag %parse_password )? :>> '@' ) @{ fgoto main; }; + + main := |* + ("sip:"i>tag %is_sip | "sips:"i>tag %is_sips) @100 + { + if(tsk_strcontains(te, (pe - te), "@")){ + fgoto sip_usrinfo; + } + }; + + ("tel:"i %is_tel (any+)>tag %parse_user_name :> uri_parameters) @100 { }; + + ( (IPv6reference >is_ipv6)@89 | (IPv4address >is_ipv4)@88 | (hostname >is_hostname)@87 ) @90 + { + TSK_SCANNER_SET_STRING(uri->host); + if(uri->host_type == host_ipv6){ + tsk_strunquote_2(&uri->host, '[', ']'); + } + }; + + (":" port)@80 + { + ts++; + TSK_SCANNER_SET_INTEGER(uri->port); + }; + + ( uri_parameters ) @70 { }; + (any)+ @0 { }; + + + + *|; + + #main := ({ fcall SIP_URI; }); + +}%% + +//////////////////////////////////////////////////////////////////////////////////////////////////// +/// @ingroup tsip_uri_group +/// +/// Creates SIP/SIPS/TEL URI from string buffer. +/// +/// +/// @param data Pointer to a string buffer from which to create the URI object. +/// @param size The size of the string buffer. +/// +/// @retval @ref tsip_uri_t* object if succeed and Null otherwise. +/// +/// @code +/// tsip_uri_t* uri; +/// if((uri = tsip_uri_parse("sip:bob@open-ims.test", strlen("sip:bob@open-ims.test")))){ +/// printf("success"); +/// } +/// else{ +/// printf("error"); +/// } +/// TSK_OBJECT_SAFE_FREE(uri); +/// @endcode +/// +/// @sa @ref tsip_uri_create() +//////////////////////////////////////////////////////////////////////////////////////////////////// +tsip_uri_t *tsip_uri_parse(const char *data, tsk_size_t size) +{ + int cs = 0; + const char *p = data; + const char *pe = p + size; + const char *eof = pe; + + const char *ts = tsk_null, *te = tsk_null; + int act = 0; + + tsip_uri_t *uri = tsip_uri_create(uri_unknown); + + const char *tag_start = tsk_null; + + %%write data; + (void)(eof); + (void)(void)(tsip_machine_parser_uri_first_final); + (void)(void)(tsip_machine_parser_uri_error); + (void)(void)(tsip_machine_parser_uri_en_sip_usrinfo); + (void)(void)(tsip_machine_parser_uri_en_main); + %%write init; + %%write exec; + + if( cs < %%{ write first_final; }%% ){ + TSK_DEBUG_ERROR("Failed to parse SIP/SIPS/TEL URI."); + TSK_OBJECT_SAFE_FREE(uri); + } + + return uri; +} -- cgit v1.1