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