summaryrefslogtreecommitdiffstats
path: root/tinySIP/ragel
diff options
context:
space:
mode:
Diffstat (limited to 'tinySIP/ragel')
-rw-r--r--tinySIP/ragel/tsip_machine_header.rl133
-rw-r--r--tinySIP/ragel/tsip_machine_message.rl57
-rw-r--r--tinySIP/ragel/tsip_machine_utils.rl197
-rw-r--r--tinySIP/ragel/tsip_parser_header.rl863
-rw-r--r--tinySIP/ragel/tsip_parser_header_Accept_Contact.rl1
-rw-r--r--tinySIP/ragel/tsip_parser_header_Accept_Encoding.rl1
-rw-r--r--tinySIP/ragel/tsip_parser_header_Accept_Language.rl1
-rw-r--r--tinySIP/ragel/tsip_parser_header_Accept_Resource_Priority.rl1
-rw-r--r--tinySIP/ragel/tsip_parser_header_Alert_Info.rl1
-rw-r--r--tinySIP/ragel/tsip_parser_header_Allow.rl190
-rw-r--r--tinySIP/ragel/tsip_parser_header_Allow_Events.rl170
-rw-r--r--tinySIP/ragel/tsip_parser_header_Authentication_Info.rl1
-rw-r--r--tinySIP/ragel/tsip_parser_header_Authorization.rl285
-rw-r--r--tinySIP/ragel/tsip_parser_header_CSeq.rl168
-rw-r--r--tinySIP/ragel/tsip_parser_header_Call_ID.rl163
-rw-r--r--tinySIP/ragel/tsip_parser_header_Call_Info.rl1
-rw-r--r--tinySIP/ragel/tsip_parser_header_Contact.rl256
-rw-r--r--tinySIP/ragel/tsip_parser_header_Content_Disposition.rl1
-rw-r--r--tinySIP/ragel/tsip_parser_header_Content_Encoding.rl1
-rw-r--r--tinySIP/ragel/tsip_parser_header_Content_Language.rl1
-rw-r--r--tinySIP/ragel/tsip_parser_header_Content_Length.rl157
-rw-r--r--tinySIP/ragel/tsip_parser_header_Content_Type.rl181
-rw-r--r--tinySIP/ragel/tsip_parser_header_Date.rl221
-rw-r--r--tinySIP/ragel/tsip_parser_header_Dummy.rl170
-rw-r--r--tinySIP/ragel/tsip_parser_header_Error_Info.rl1
-rw-r--r--tinySIP/ragel/tsip_parser_header_Event.rl168
-rw-r--r--tinySIP/ragel/tsip_parser_header_Expires.rl155
-rw-r--r--tinySIP/ragel/tsip_parser_header_From.rl196
-rw-r--r--tinySIP/ragel/tsip_parser_header_History_Info.rl1
-rw-r--r--tinySIP/ragel/tsip_parser_header_Identity.rl1
-rw-r--r--tinySIP/ragel/tsip_parser_header_Identity_Info.rl1
-rw-r--r--tinySIP/ragel/tsip_parser_header_In_Reply_To.rl1
-rw-r--r--tinySIP/ragel/tsip_parser_header_Join.rl1
-rw-r--r--tinySIP/ragel/tsip_parser_header_MIME_Version.rl1
-rw-r--r--tinySIP/ragel/tsip_parser_header_Max_Forwards.rl155
-rw-r--r--tinySIP/ragel/tsip_parser_header_Min_Expires.rl160
-rw-r--r--tinySIP/ragel/tsip_parser_header_Min_SE.rl160
-rw-r--r--tinySIP/ragel/tsip_parser_header_Organization.rl1
-rw-r--r--tinySIP/ragel/tsip_parser_header_P_Access_Network_Info.rl170
-rw-r--r--tinySIP/ragel/tsip_parser_header_P_Answer_State.rl1
-rw-r--r--tinySIP/ragel/tsip_parser_header_P_Asserted_Identity.rl200
-rw-r--r--tinySIP/ragel/tsip_parser_header_P_Associated_URI.rl212
-rw-r--r--tinySIP/ragel/tsip_parser_header_P_Called_Party_ID.rl1
-rw-r--r--tinySIP/ragel/tsip_parser_header_P_Charging_Function_Addresses.rl195
-rw-r--r--tinySIP/ragel/tsip_parser_header_P_Charging_Vector.rl1
-rw-r--r--tinySIP/ragel/tsip_parser_header_P_DCS_Billing_Info.rl1
-rw-r--r--tinySIP/ragel/tsip_parser_header_P_DCS_LAES.rl1
-rw-r--r--tinySIP/ragel/tsip_parser_header_P_DCS_OSPS.rl1
-rw-r--r--tinySIP/ragel/tsip_parser_header_P_DCS_Redirect.rl1
-rw-r--r--tinySIP/ragel/tsip_parser_header_P_DCS_Trace_Party_ID.rl1
-rw-r--r--tinySIP/ragel/tsip_parser_header_P_Early_Media.rl1
-rw-r--r--tinySIP/ragel/tsip_parser_header_P_Media_Authorization.rl1
-rw-r--r--tinySIP/ragel/tsip_parser_header_P_Preferred_Identity.rl198
-rw-r--r--tinySIP/ragel/tsip_parser_header_P_Profile_Key.rl1
-rw-r--r--tinySIP/ragel/tsip_parser_header_P_User_Database.rl1
-rw-r--r--tinySIP/ragel/tsip_parser_header_P_Visited_Network_ID.rl1
-rw-r--r--tinySIP/ragel/tsip_parser_header_Path.rl214
-rw-r--r--tinySIP/ragel/tsip_parser_header_Priority.rl1
-rw-r--r--tinySIP/ragel/tsip_parser_header_Privacy.rl176
-rw-r--r--tinySIP/ragel/tsip_parser_header_Proxy_Authenticate.rl245
-rw-r--r--tinySIP/ragel/tsip_parser_header_Proxy_Authorization.rl286
-rw-r--r--tinySIP/ragel/tsip_parser_header_Proxy_Require.rl181
-rw-r--r--tinySIP/ragel/tsip_parser_header_RAck.rl170
-rw-r--r--tinySIP/ragel/tsip_parser_header_RSeq.rl158
-rw-r--r--tinySIP/ragel/tsip_parser_header_Reason.rl1
-rw-r--r--tinySIP/ragel/tsip_parser_header_Record_Route.rl211
-rw-r--r--tinySIP/ragel/tsip_parser_header_Refer_Sub.rl165
-rw-r--r--tinySIP/ragel/tsip_parser_header_Refer_To.rl195
-rw-r--r--tinySIP/ragel/tsip_parser_header_Referred_By.rl207
-rw-r--r--tinySIP/ragel/tsip_parser_header_Reject_Contact.rl1
-rw-r--r--tinySIP/ragel/tsip_parser_header_Replaces.rl1
-rw-r--r--tinySIP/ragel/tsip_parser_header_Reply_To.rl1
-rw-r--r--tinySIP/ragel/tsip_parser_header_Request_Disposition.rl1
-rw-r--r--tinySIP/ragel/tsip_parser_header_Require.rl180
-rw-r--r--tinySIP/ragel/tsip_parser_header_Resource_Priority.rl1
-rw-r--r--tinySIP/ragel/tsip_parser_header_Retry_After.rl1
-rw-r--r--tinySIP/ragel/tsip_parser_header_Route.rl218
-rw-r--r--tinySIP/ragel/tsip_parser_header_SIP_ETag.rl163
-rw-r--r--tinySIP/ragel/tsip_parser_header_SIP_If_Match.rl165
-rw-r--r--tinySIP/ragel/tsip_parser_header_Security_Client.rl297
-rw-r--r--tinySIP/ragel/tsip_parser_header_Security_Server.rl280
-rw-r--r--tinySIP/ragel/tsip_parser_header_Security_Verify.rl279
-rw-r--r--tinySIP/ragel/tsip_parser_header_Server.rl167
-rw-r--r--tinySIP/ragel/tsip_parser_header_Service_Route.rl213
-rw-r--r--tinySIP/ragel/tsip_parser_header_Session_Expires.rl172
-rw-r--r--tinySIP/ragel/tsip_parser_header_Subject.rl1
-rw-r--r--tinySIP/ragel/tsip_parser_header_Subscription_State.rl189
-rw-r--r--tinySIP/ragel/tsip_parser_header_Supported.rl180
-rw-r--r--tinySIP/ragel/tsip_parser_header_Target_Dialog.rl1
-rw-r--r--tinySIP/ragel/tsip_parser_header_Timestamp.rl1
-rw-r--r--tinySIP/ragel/tsip_parser_header_To.rl200
-rw-r--r--tinySIP/ragel/tsip_parser_header_Unsupported.rl1
-rw-r--r--tinySIP/ragel/tsip_parser_header_User_Agent.rl160
-rw-r--r--tinySIP/ragel/tsip_parser_header_Via.rl345
-rw-r--r--tinySIP/ragel/tsip_parser_header_WWW_Authenticate.rl244
-rw-r--r--tinySIP/ragel/tsip_parser_header_Warning.rl190
-rw-r--r--tinySIP/ragel/tsip_parser_message.rl275
-rw-r--r--tinySIP/ragel/tsip_parser_uri.rl180
98 files changed, 11528 insertions, 0 deletions
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 <diopmamadou(at)doubango[dot]org>
+*
+* 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 <diopmamadou(at)doubango[dot]org>
+ *
+
+ */
+
+/*== 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 <diopmamadou(at)doubango[dot]org>
+*
+* 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 <diopmamadou(at)doubango[dot]org>
+ *
+
+ */
+%%{
+ 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 <diopmamadou(at)doubango[dot]org>
+*
+* 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 <diopmamadou(at)doubango[dot]org>
+ *
+
+ */
+%%{
+
+ 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 <diopmamadou(at)doubango[dot]org>
+*
+* 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 <diopmamadou(at)doubango[dot]org>
+ *
+
+ */
+#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 <diopmamadou(at)doubango[dot]org>
+*
+* 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 <diopmamadou(at)doubango[dot]org>
+ *
+
+ */
+#include "tinysip/headers/tsip_header_Allow.h"
+
+#include "tinysip/parsers/tsip_parser_uri.h"
+
+#include "tsk_debug.h"
+#include "tsk_memory.h"
+#include <string.h>
+
+/***********************************
+* 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 <diopmamadou(at)doubango[dot]org>
+*
+* 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 <diopmamadou(at)doubango[dot]org>
+ *
+
+ */
+#include "tinysip/headers/tsip_header_Allow_Events.h"
+
+#include "tinysip/parsers/tsip_parser_uri.h"
+
+#include "tsk_debug.h"
+#include "tsk_memory.h"
+
+#include <string.h>
+
+
+/***********************************
+* 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 <diopmamadou(at)doubango[dot]org>
+//*
+//* 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 <diopmamadou(at)doubango[dot]org>
+// *
+//
+// */
+//#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 <string.h>
+//
+
+//
+///***********************************
+//* 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 <diopmamadou(at)doubango[dot]org>
+*
+* 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 <diopmamadou(at)doubango[dot]org>
+ *
+
+ */
+#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 <diopmamadou(at)doubango[dot]org>
+*
+* 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 <diopmamadou(at)doubango[dot]org>
+ *
+
+ */
+#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 <string.h>
+
+
+
+/***********************************
+* 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 <diopmamadou(at)doubango[dot]org>
+*
+* 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 <diopmamadou(at)doubango[dot]org>
+ *
+
+ */
+#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 <diopmamadou(at)doubango[dot]org>
+*
+* 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 <diopmamadou(at)doubango[dot]org>
+ *
+
+ */
+#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 <diopmamadou(at)doubango[dot]org>
+*
+* 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 <diopmamadou(at)doubango[dot]org>
+ *
+
+ */
+#include "tinysip/headers/tsip_header_Content_Type.h"
+
+#include "tsk_debug.h"
+#include "tsk_memory.h"
+
+#include <string.h>
+
+
+
+/***********************************
+* 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 <diopmamadou(at)doubango[dot]org>
+*
+* 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 <diopmamadou(at)doubango[dot]org>
+ *
+
+ */
+#include "tinysip/headers/tsip_header_Date.h"
+
+#include "tinysip/parsers/tsip_parser_uri.h"
+
+#include "tsk_debug.h"
+#include "tsk_memory.h"
+
+#include <string.h>
+
+
+
+/***********************************
+* 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 <diopmamadou(at)doubango[dot]org>
+*
+* 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 <diopmamadou(at)doubango[dot]org>
+ *
+
+ */
+#include "tinysip/headers/tsip_header_Dummy.h"
+
+#include "tinysip/parsers/tsip_parser_uri.h"
+
+#include "tsk_debug.h"
+#include "tsk_memory.h"
+
+#include <string.h>
+
+
+
+/***********************************
+* 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 <diopmamadou(at)doubango[dot]org>
+*
+* 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 <diopmamadou(at)doubango[dot]org>
+ *
+
+ */
+#include "tinysip/headers/tsip_header_Event.h"
+
+#include "tinysip/parsers/tsip_parser_uri.h"
+
+#include "tsk_debug.h"
+#include "tsk_memory.h"
+
+#include <string.h>
+
+
+
+/***********************************
+* 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 <diopmamadou(at)doubango[dot]org>
+*
+* 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 <diopmamadou(at)doubango[dot]org>
+ *
+
+ */
+#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 <diopmamadou(at)doubango[dot]org>
+*
+* 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 <diopmamadou(at)doubango[dot]org>
+ *
+
+ */
+#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 <diopmamadou(at)doubango[dot]org>
+*
+* 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 <diopmamadou(at)doubango[dot]org>
+ *
+
+ */
+#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 <diopmamadou(at)doubango[dot]org>
+*
+* 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 <diopmamadou(at)doubango[dot]org>
+ *
+
+ */
+#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 <diopmamadou(at)doubango[dot]org>
+*
+* 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 <diopmamadou(at)doubango[dot]org>
+ *
+
+ */
+#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 <diopmamadou(at)doubango[dot]org>
+*
+* 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 <diopmamadou(at)doubango[dot]org>
+ *
+
+ */
+#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 <string.h>
+
+
+
+/***********************************
+* 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 <diopmamadou(at)doubango[dot]org>
+*
+* 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 <diopmamadou(at)doubango[dot]org>
+ *
+
+ */
+#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 <string.h>
+
+
+
+/***********************************
+* 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 <diopmamadou(at)doubango[dot]org>
+*
+* 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 <diopmamadou(at)doubango[dot]org>
+ *
+
+ */
+#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 <string.h>
+
+
+
+/***********************************
+* 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 <diopmamadou(at)doubango[dot]org>
+*
+* 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 <diopmamadou(at)doubango[dot]org>
+ *
+
+ */
+#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 <string.h>
+
+
+
+/***********************************
+* 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 <diopmamadou(at)doubango[dot]org>
+*
+* 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 <diopmamadou(at)doubango[dot]org>
+ *
+
+ */
+#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 <diopmamadou(at)doubango[dot]org>
+*
+* 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 <diopmamadou(at)doubango[dot]org>
+ *
+
+ */
+#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 <string.h>
+
+
+
+/***********************************
+* 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 <diopmamadou(at)doubango[dot]org>
+*
+* 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 <diopmamadou(at)doubango[dot]org>
+ *
+
+ */
+#include "tinysip/headers/tsip_header_Privacy.h"
+
+#include "tinysip/parsers/tsip_parser_uri.h"
+
+#include "tsk_debug.h"
+#include "tsk_memory.h"
+
+#include <string.h>
+
+
+
+/***********************************
+* 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 <diopmamadou(at)doubango[dot]org>
+//*
+//* 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 <diopmamadou(at)doubango[dot]org>
+// *
+//
+// */
+//#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 <string.h>
+//
+
+//
+///***********************************
+//* 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 <diopmamadou(at)doubango[dot]org>
+//*
+//* 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 <diopmamadou(at)doubango[dot]org>
+// *
+//
+// */
+//#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 <string.h>
+//
+
+//
+///***********************************
+//* 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 <diopmamadou(at)doubango[dot]org>
+*
+* 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 <diopmamadou(at)doubango[dot]org>
+ *
+
+ */
+#include "tinysip/headers/tsip_header_Proxy_Require.h"
+
+#include "tinysip/parsers/tsip_parser_uri.h"
+
+#include "tsk_debug.h"
+#include "tsk_memory.h"
+
+#include <string.h>
+
+
+/***********************************
+* 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 <diopmamadou(at)doubango[dot]org>
+*
+* 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 <diopmamadou(at)doubango[dot]org>
+ *
+
+ */
+#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 <diopmamadou(at)doubango[dot]org>
+*
+* 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 <diopmamadou(at)doubango[dot]org>
+ *
+
+ */
+#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 <diopmamadou(at)doubango[dot]org>
+*
+* 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 <diopmamadou(at)doubango[dot]org>
+ *
+
+ */
+#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 <string.h>
+
+
+
+/***********************************
+* 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 <diopmamadou(at)doubango[dot]org>
+*
+* 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 <diopmamadou(at)doubango[dot]org>
+ *
+
+ */
+#include "tinysip/headers/tsip_header_Refer_Sub.h"
+
+#include "tinysip/parsers/tsip_parser_uri.h"
+
+#include "tsk_debug.h"
+#include "tsk_memory.h"
+
+#include <string.h>
+
+/***********************************
+* 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 <diopmamadou(at)doubango[dot]org>
+*
+* 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 <diopmamadou(at)doubango[dot]org>
+ *
+
+ */
+#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 <diopmamadou(at)doubango[dot]org>
+*
+* 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 <diopmamadou(at)doubango[dot]org>
+ *
+
+ */
+#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 <diopmamadou(at)doubango[dot]org>
+*
+* 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 <diopmamadou(at)doubango[dot]org>
+ *
+
+ */
+#include "tinysip/headers/tsip_header_Require.h"
+
+#include "tinysip/parsers/tsip_parser_uri.h"
+
+#include "tsk_debug.h"
+#include "tsk_memory.h"
+
+#include <string.h>
+
+
+
+/***********************************
+* 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 <diopmamadou(at)doubango[dot]org>
+*
+* 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 <diopmamadou(at)doubango[dot]org>
+ *
+
+ */
+#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 <string.h>
+
+
+
+/***********************************
+* 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 <diopmamadou(at)doubango[dot]org>
+*
+* 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 <diopmamadou(at)doubango[dot]org>
+ *
+
+ */
+#include "tinysip/headers/tsip_header_SIP_ETag.h"
+
+#include "tinysip/parsers/tsip_parser_uri.h"
+
+#include "tsk_debug.h"
+#include "tsk_memory.h"
+
+#include <string.h>
+
+
+
+/***********************************
+* 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 <diopmamadou(at)doubango[dot]org>
+*
+* 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 <diopmamadou(at)doubango[dot]org>
+ *
+
+ */
+#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 <string.h>
+
+
+
+/***********************************
+* 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 <diopmamadou(at)doubango[dot]org>
+*
+* 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 <diopmamadou(at)doubango[dot]org>
+ *
+
+ */
+#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 <string.h>
+
+
+
+/***********************************
+* 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 <diopmamadou(at)doubango[dot]org>
+*
+* 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 <diopmamadou(at)doubango[dot]org>
+ *
+
+ */
+#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 <string.h>
+
+
+
+/***********************************
+* 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 <diopmamadou(at)doubango[dot]org>
+*
+* 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 <diopmamadou(at)doubango[dot]org>
+ *
+
+ */
+#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 <string.h>
+
+
+
+/***********************************
+* 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 <diopmamadou(at)doubango[dot]org>
+*
+* 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 <diopmamadou(at)doubango[dot]org>
+ *
+
+ */
+#include "tinysip/headers/tsip_header_Server.h"
+
+#include "tinysip/parsers/tsip_parser_uri.h"
+
+#include "tsk_debug.h"
+#include "tsk_memory.h"
+
+#include <string.h>
+
+
+
+/***********************************
+* 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 <diopmamadou(at)doubango[dot]org>
+*
+* 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 <diopmamadou(at)doubango[dot]org>
+ *
+
+ */
+#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 <string.h>
+
+
+
+/***********************************
+* 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 <diopmamadou(at)doubango[dot]org>
+*
+* 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 <diopmamadou(at)doubango[dot]org>
+ *
+
+ */
+#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 <diopmamadou(at)doubango[dot]org>
+*
+* 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 <diopmamadou(at)doubango[dot]org>
+ *
+
+ */
+#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 <diopmamadou(at)doubango[dot]org>
+*
+* 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 <diopmamadou(at)doubango[dot]org>
+ *
+
+ */
+#include "tinysip/headers/tsip_header_Supported.h"
+
+#include "tinysip/parsers/tsip_parser_uri.h"
+
+#include "tsk_debug.h"
+#include "tsk_memory.h"
+
+#include <string.h>
+
+
+
+/***********************************
+* 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 <diopmamadou(at)doubango[dot]org>
+*
+* 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 <diopmamadou(at)doubango[dot]org>
+ *
+
+ */
+#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 <diopmamadou(at)doubango[dot]org>
+*
+* 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 <diopmamadou(at)doubango[dot]org>
+ *
+
+ */
+#include "tinysip/headers/tsip_header_User_Agent.h"
+
+#include "tinysip/parsers/tsip_parser_uri.h"
+
+#include "tsk_debug.h"
+#include "tsk_memory.h"
+
+#include <string.h>
+
+/***********************************
+* 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 <diopmamadou(at)doubango[dot]org>
+*
+* 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 <diopmamadou(at)doubango[dot]org>
+ *
+
+ */
+#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 <diopmamadou(at)doubango[dot]org>
+//*
+//* 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 <diopmamadou(at)doubango[dot]org>
+// *
+//
+// */
+//#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 <string.h>
+//
+//
+///***********************************
+//* 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 <diopmamadou(at)doubango[dot]org>
+*
+* 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 <diopmamadou(at)doubango[dot]org>
+ *
+
+ */
+#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 <string.h>
+
+
+
+/***********************************
+* 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 <diopmamadou(at)doubango[dot]org>
+*
+* 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 <diopmamadou(at)doubango[dot]org>
+ *
+
+ */
+#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) <pe && !message->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 <diopmamadou(at)doubango[dot]org>
+*
+* 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 <diopmamadou(at)doubango[dot]org>
+ *
+
+ */
+#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;
+}
OpenPOWER on IntegriCloud