pkg/kamailio/fedora/16: Updated rel in .spec to dev2
[sip-router] / error.c
1 /*
2  * $Id$
3  *
4  *
5  * Copyright (C) 2001-2003 FhG Fokus
6  *
7  * This file is part of ser, a free SIP server.
8  *
9  * ser is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version
13  *
14  * For a license to use the ser software under conditions
15  * other than those described here, or to purchase support for this
16  * software, please contact iptel.org by e-mail at the following addresses:
17  *    info@iptel.org
18  *
19  * ser is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License 
25  * along with this program; if not, write to the Free Software 
26  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
27  *
28  * History:
29  * --------
30  * 2003-04-04 phrase length corrected not to include trailer 0 (jiri)
31  */
32
33 /*!
34  * \file
35  * \brief SIP-router core :: 
36  * \ingroup core
37  * Module: \ref core
38  */
39
40
41 #include <stdio.h>
42 #include "error.h"
43 #include "str.h"
44 #include "parser/msg_parser.h"
45 #include "mem/mem.h"
46
47 /* current function's error; */
48 int ser_error=-1;
49 /* previous error */
50 int prev_ser_error=-1;
51
52 int err2reason_phrase( 
53         int ser_error,  /* current internal ser error */
54         int *sip_error,  /* the sip error code to which ser     
55                                             ser error will be turned */
56         char *phrase,    /* resulting error text */
57         int etl,                /* error text buffer length */
58         char *signature ) /* extra text to be appended */
59 {
60
61         char *error_txt;
62
63         switch( ser_error ) {
64                 case E_SEND:
65                         error_txt="Unfortunately error on sending to next hop occurred";
66                         *sip_error=-ser_error;
67                         break;
68                 case E_BAD_ADDRESS:
69                         error_txt="Unresolvable destination";
70                         *sip_error=-ser_error;
71                         break;
72                 case E_BAD_REQ:
73                         error_txt="Bad Request";
74                         *sip_error=-ser_error;
75                         break;
76                 case E_BAD_URI:
77                         error_txt="Regretfully, we were not able to process the URI";
78                         *sip_error=-ser_error;
79                         break;
80                 case E_BAD_TUPEL:
81                         error_txt="Transaction tuple incomplete";
82                         *sip_error=-E_BAD_REQ;
83                         break;
84                 case E_BAD_TO:
85                         error_txt="Bad To";
86                         *sip_error=-E_BAD_REQ;
87                         break;
88                 case E_EXEC:
89                         error_txt="Error in external logic";
90                         *sip_error=-E_BAD_SERVER;
91                         break;
92                 case E_TOO_MANY_BRANCHES:
93                         error_txt="Forking capacity exceeded";
94                         *sip_error=-E_BAD_SERVER;
95                         break;
96
97                 case E_Q_INV_CHAR:
98                         error_txt="Invalid character in q parameter";
99                         *sip_error=-E_BAD_REQ;
100                         break;
101
102                 case E_Q_EMPTY:
103                         error_txt="Empty q parameter";
104                         *sip_error=-E_BAD_REQ;
105                         break;;
106
107                 case E_Q_TOO_BIG:
108                         error_txt="q parameter too big";
109                         *sip_error=-E_BAD_REQ;
110                         break;
111
112                 case E_Q_DEC_MISSING:
113                         error_txt="Decimal part missing in q";
114                         *sip_error=-E_BAD_REQ;
115                         break;
116
117                 case E_CANCELED:
118                         error_txt="transaction canceled";
119                         *sip_error=-ser_error;
120                         break;
121
122                 case E_OUT_OF_MEM:
123                 /* dont disclose lack of mem in release mode */
124 #ifdef EXTRA_DEBUG
125                         error_txt="Excuse me I ran out of memory";
126                         *sip_error=500;
127                         break;
128 #endif
129                 case E_OK:
130                         error_txt="No error";
131                         *sip_error=500;
132                         break;
133                 default:
134                         error_txt="I'm terribly sorry, server error occurred";
135                         *sip_error=500;
136                         break;
137         }
138         return snprintf( phrase, etl, "%s (%d/%s)", error_txt, 
139                 -ser_error, signature );
140 }
141
142 char *error_text( int code )
143 {
144         switch(code) {
145
146                 case 100: return "Trying";
147                 case 180: return "Ringing";
148                 case 181: return "Call is Being Forwarded";
149                 case 182: return "Queued";
150                 case 183: return "Session Progress";
151
152                 case 200: return "OK";
153
154                 case 300: return "Multiple Choices";
155                 case 301: return "Moved Permanently";
156                 case 302: return "Moved Temporarily";
157                 case 305: return "Use Proxy";
158                 case 380: return "Alternative Service";
159
160                 case 400: return "Bad Request";
161                 case 401: return "Unauthorized";
162                 case 402: return "Payment Required";
163                 case 403: return "Forbidden";
164                 case 404: return "Not Found";
165                 case 405: return "Method not Allowed";
166                 case 406: return "Not Acceptable";
167                 case 407: return "Proxy authentication Required";
168                 case 408: return "Request Timeout";
169                 case 410: return "Gone";
170                 case 413: return "Request Entity Too Large";
171                 case 414: return "Request-URI Too Long";
172                 case 415: return "Unsupported Media Type";
173                 case 416: return "Unsupported URI Scheme";
174                 case 417: return "Bad Extension";
175                 case 421: return "Extension Required";
176                 case 423: return "Interval Too Brief";
177                 case 480: return "Temporarily Unavailable";
178                 case 481: return "Call/Transaction Does not Exist";
179                 case 482: return "Loop Detected";
180                 case 483: return "Too Many Hops";
181                 case 484: return "Address Incomplete";
182                 case 485: return "Ambiguous";
183                 case 486: return "Busy Here";
184                 case 487: return "Request Terminated";
185                 case 488: return "Not Acceptable Here";
186                 case 491: return "Request Pending";
187         
188                 case 500: return "Server Internal Error";
189                 case 501: return "Not Implemented";
190                 case 502: return "Bad Gateway";
191                 case 503: return "Service Unavailable";
192                 case 504: return "Server Time-out";
193                 case 505: return "Version not Supported";
194                 case 513: return "Message Too Large";
195
196                 case 600: return "Busy Everywhere";
197                 case 603: return "Decline";
198                 case 604: return "Does not Exist Anywhere";
199                 case 606: return "Not Acceptable";
200
201         }
202
203         if (code>=600) return "Global Failure";
204         else if (code>=500) return "Server Failure";
205         else if (code>=400) return "Request Failure";
206         else if (code>=300) return "Redirection";
207         else if (code>=200) return "Successful";
208         else if (code>=100) return "Provisional";
209         else return "Unspecified";
210 }
211
212 void get_reply_status( str *status, struct sip_msg *reply, int code )
213 {
214         str phrase;
215
216         status->s=0;
217
218         if (reply==0) {
219                 LOG(L_CRIT, "BUG: get_reply_status called with 0 msg\n");
220                 return;
221         }
222
223         if (reply==FAKED_REPLY) {
224                 phrase.s=error_text(code);
225                 phrase.len=strlen(phrase.s);
226         } else {
227                 phrase=reply->first_line.u.reply.reason;
228         }
229         status->len=phrase.len+3/*code*/+1/*space*/; 
230         status->s=pkg_malloc(status->len+1/*ZT */);
231         if (!status->s) {
232                 LOG(L_ERR, "ERROR: get_reply_status: no mem\n");
233                 return;
234         }
235         status->s[3]=' ';
236         status->s[2]='0'+code % 10; code=code/10;
237         status->s[1]='0'+code% 10; code=code/10;
238         status->s[0]='0'+code % 10;
239         memcpy(&status->s[4], phrase.s, phrase.len);
240         status->s[status->len]=0;
241 }