1 /*
2   The oSIP library implements the Session Initiation Protocol (SIP -rfc3261-)
3   Copyright (C) 2001-2020 Aymeric MOIZARD amoizard@antisip.com
4 
5   This library is free software; you can redistribute it and/or
6   modify it under the terms of the GNU Lesser General Public
7   License as published by the Free Software Foundation; either
8   version 2.1 of the License, or (at your option) any later version.
9 
10   This library is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13   Lesser General Public License for more details.
14 
15   You should have received a copy of the GNU Lesser General Public
16   License along with this library; if not, write to the Free Software
17   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18 */
19 
20 #include <osip2/internal.h>
21 #include <osip2/osip.h>
22 
23 #include "fsm.h"
24 
25 /* Create a sipevent according to the SIP message buf. */
26 /* INPUT : char *buf | message as a string.            */
27 /* return NULL  if message cannot be parsed            */
osip_parse(const char * buf,size_t length)28 osip_event_t *osip_parse(const char *buf, size_t length) {
29   int i;
30   osip_event_t *se = __osip_event_new(UNKNOWN_EVT, 0);
31 
32   if (se == NULL)
33     return NULL;
34 
35   /* parse message and set up an event */
36   i = osip_message_init(&(se->sip));
37 
38   if (i != 0) {
39     osip_free(se);
40     return NULL;
41   }
42 
43   if (osip_message_parse(se->sip, buf, length) != 0) {
44     OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_ERROR, NULL, "could not parse message\n"));
45     osip_message_free(se->sip);
46     osip_free(se);
47     return NULL;
48 
49   } else {
50     if (se->sip->call_id != NULL && se->sip->call_id->number != NULL) {
51       OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_INFO3, NULL, "MESSAGE REC. CALLID:%s\n", se->sip->call_id->number));
52     }
53 
54     if (MSG_IS_REQUEST(se->sip)) {
55       if (se->sip->sip_method == NULL || se->sip->req_uri == NULL) {
56         osip_message_free(se->sip);
57         osip_free(se);
58         return NULL;
59       }
60     }
61 
62     se->type = evt_set_type_incoming_sipmessage(se->sip);
63     return se;
64   }
65 }
66 
67 /* allocates an event from retransmitter.             */
68 /* USED ONLY BY THE STACK.                            */
69 /* INPUT : int transactionid | id of the transaction. */
70 /* INPUT : type_t type | type of event.               */
71 /* returns null on error. */
__osip_event_new(type_t type,int transactionid)72 osip_event_t *__osip_event_new(type_t type, int transactionid) {
73   osip_event_t *sipevent;
74 
75   sipevent = (osip_event_t *) osip_malloc(sizeof(osip_event_t));
76 
77   if (sipevent == NULL)
78     return NULL;
79 
80   sipevent->type = type;
81   sipevent->sip = NULL;
82   sipevent->transactionid = transactionid;
83   return sipevent;
84 }
85 
86 /* allocates an event from user.                      */
87 /* USED ONLY BY THE USER.                             */
88 /* INPUT : osip_message_t *sip | sip message for transaction.  */
89 /* returns null on error. */
osip_new_outgoing_sipmessage(osip_message_t * sip)90 osip_event_t *osip_new_outgoing_sipmessage(osip_message_t *sip) {
91   osip_event_t *sipevent;
92 
93   if (sip == NULL)
94     return NULL;
95 
96   if (MSG_IS_REQUEST(sip)) {
97     if (sip->sip_method == NULL)
98       return NULL;
99 
100     if (sip->req_uri == NULL)
101       return NULL;
102   }
103 
104   sipevent = (osip_event_t *) osip_malloc(sizeof(osip_event_t));
105 
106   if (sipevent == NULL)
107     return NULL;
108 
109   sipevent->sip = sip;
110   sipevent->type = evt_set_type_outgoing_sipmessage(sip);
111   sipevent->transactionid = 0;
112   return sipevent;
113 }
114 
evt_set_type_incoming_sipmessage(osip_message_t * sip)115 type_t evt_set_type_incoming_sipmessage(osip_message_t *sip) {
116   if (MSG_IS_REQUEST(sip)) {
117     if (MSG_IS_INVITE(sip))
118       return RCV_REQINVITE;
119 
120     else if (MSG_IS_ACK(sip))
121       return RCV_REQACK;
122 
123     return RCV_REQUEST;
124 
125   } else {
126     if (MSG_IS_STATUS_1XX(sip))
127       return RCV_STATUS_1XX;
128 
129     else if (MSG_IS_STATUS_2XX(sip))
130       return RCV_STATUS_2XX;
131 
132     return RCV_STATUS_3456XX;
133   }
134 }
135 
evt_set_type_outgoing_sipmessage(osip_message_t * sip)136 type_t evt_set_type_outgoing_sipmessage(osip_message_t *sip) {
137   if (MSG_IS_REQUEST(sip)) {
138     if (MSG_IS_INVITE(sip))
139       return SND_REQINVITE;
140 
141     if (MSG_IS_ACK(sip))
142       return SND_REQACK;
143 
144     return SND_REQUEST;
145 
146   } else {
147     if (MSG_IS_STATUS_1XX(sip))
148       return SND_STATUS_1XX;
149 
150     else if (MSG_IS_STATUS_2XX(sip))
151       return SND_STATUS_2XX;
152 
153     return SND_STATUS_3456XX;
154   }
155 }
156 
osip_event_free(osip_event_t * event)157 void osip_event_free(osip_event_t *event) {
158   if (event != NULL) {
159     osip_message_free(event->sip);
160     osip_free(event);
161   }
162 }
163