[asterisk-commits] oej: branch oej/pinepacketrequest r217366 - /team/oej/pinepacketrequest/chann...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Wed Sep 9 05:25:11 CDT 2009


Author: oej
Date: Wed Sep  9 05:25:08 2009
New Revision: 217366

URL: http://svn.asterisk.org/svn-view/asterisk?view=rev&rev=217366
Log:
Make sure that all transmit_response include an integer value.

Later patches means that we can skip a parse_request just for this stuff when history is on. And propably implement some nice filters too.

Modified:
    team/oej/pinepacketrequest/channels/chan_sip.c

Modified: team/oej/pinepacketrequest/channels/chan_sip.c
URL: http://svn.asterisk.org/svn-view/asterisk/team/oej/pinepacketrequest/channels/chan_sip.c?view=diff&rev=217366&r1=217365&r2=217366
==============================================================================
--- team/oej/pinepacketrequest/channels/chan_sip.c (original)
+++ team/oej/pinepacketrequest/channels/chan_sip.c Wed Sep  9 05:25:08 2009
@@ -1345,11 +1345,11 @@
 
 struct sip_message {
 	/* For both incoming messages and outbound messages */
-	unsigned int outbound;		/*!< TRUE if this packet is outbound, FALSE if it's read from the wire */
-	int len;                	/*!< bytes used in data[], excluding trailing null terminator. Rarely used. */
-	int method;             /*!< Method of this request */
+	unsigned int outbound;			/*!< TRUE if this packet is outbound, FALSE if it's read from the wire */
+	int len;                		/*!< bytes used in data[], excluding trailing null terminator. Rarely used. */
+	int method;             		/*!< Method of this request */
 	unsigned int is_resp:1;			/*!< 1 if this is a response packet (e.g. 200 OK), 0 if it is a request */
-	unsigned int is_parsed:1;			/*!< 1 if this is a response packet (e.g. 200 OK), 0 if it is a request */
+	unsigned int is_parsed:1;		/*!< 1 if this is a response packet (e.g. 200 OK), 0 if it is a request */
 	unsigned int response_code;		/*!< If this is a response, the response code */
 	int seqno;				/*!< Our Sequence number */
 
@@ -1368,7 +1368,7 @@
 	/* XXX Do we need to unref socket.ser when the request goes away? */
 	struct sip_socket socket;		/*!< The socket used for this request */
 	AST_LIST_ENTRY(sip_message) next;
-	/* ------------------------    Fields copied from sip_pkt */
+	/* ------------------------    Fields Used only for inbound messages (read from a socket) */
 	/* Outbound messages only */
 	int retrans;				/*!< Retransmission number */
 	int retransid;				/*!< Retransmission ID (sched) */
@@ -2400,17 +2400,17 @@
 static int sipsock_read(int *id, int fd, short events, void *ignore);
 static int __sip_xmit(struct sip_pvt *p, struct ast_str *data, int len);
 static int __sip_reliable_xmit(struct sip_pvt *p, int seqno, int resp, struct ast_str *data, int len, int fatal, int sipmethod);
-static int __transmit_response(struct sip_pvt *p, const char *msg, const struct sip_message *req, enum xmittype reliable);
+static int __transmit_response(struct sip_pvt *p, const int code, const char *msg, const struct sip_message *req, enum xmittype reliable);
 static int retrans_pkt(const void *data);
-static int transmit_response_using_temp(ast_string_field callid, struct sockaddr_in *sin, int useglobal_nat, const int intended_method, const struct sip_message *req, const char *msg);
-static int transmit_response(struct sip_pvt *p, const char *msg, const struct sip_message *req);
-static int transmit_response_reliable(struct sip_pvt *p, const char *msg, const struct sip_message *req);
-static int transmit_response_with_date(struct sip_pvt *p, const char *msg, const struct sip_message *req);
-static int transmit_response_with_sdp(struct sip_pvt *p, const char *msg, const struct sip_message *req, enum xmittype reliable, int oldsdp, int rpid);
-static int transmit_response_with_unsupported(struct sip_pvt *p, const char *msg, const struct sip_message *req, const char *unsupported);
-static int transmit_response_with_auth(struct sip_pvt *p, const char *msg, const struct sip_message *req, const char *rand, enum xmittype reliable, const char *header, int stale);
-static int transmit_provisional_response(struct sip_pvt *p, const char *msg, const struct sip_message *req, int with_sdp);
-static int transmit_response_with_allow(struct sip_pvt *p, const char *msg, const struct sip_message *req, enum xmittype reliable);
+static int transmit_response_using_temp(ast_string_field callid, struct sockaddr_in *sin, int useglobal_nat, const int intended_method, const struct sip_message *req, const char *msg, const int code);
+static int transmit_response(struct sip_pvt *p, const int code, const char *msg, const struct sip_message *req);
+static int transmit_response_reliable(struct sip_pvt *p, const int code, const char *msg, const struct sip_message *req);
+static int transmit_response_with_date(struct sip_pvt *p, const int code, const char *msg, const struct sip_message *req);
+static int transmit_response_with_sdp(struct sip_pvt *p, const int code, const char *msg, const struct sip_message *req, enum xmittype reliable, int oldsdp, int rpid);
+static int transmit_response_with_unsupported(struct sip_pvt *p, const int code, const char *msg, const struct sip_message *req, const char *unsupported);
+static int transmit_response_with_auth(struct sip_pvt *p, const int code, const char *msg, const struct sip_message *req, const char *rand, enum xmittype reliable, const char *header, int stale);
+static int transmit_provisional_response(struct sip_pvt *p, const int code, const char *msg, const struct sip_message *req, int with_sdp);
+static int transmit_response_with_allow(struct sip_pvt *p, const int code, const char *msg, const struct sip_message *req, enum xmittype reliable);
 static void transmit_fake_auth_response(struct sip_pvt *p, int sipmethod, struct sip_message *req, enum xmittype reliable);
 static int transmit_request(struct sip_pvt *p, int sipmethod, int inc, enum xmittype reliable, int newbranch);
 static int transmit_request_with_auth(struct sip_pvt *p, int sipmethod, int seqno, enum xmittype reliable, int newbranch);
@@ -2714,7 +2714,7 @@
 static void handle_response(struct sip_pvt *p, int resp, const char *rest, struct sip_message *req, int seqno);
 
 /*------ T38 Support --------- */
-static int transmit_response_with_t38_sdp(struct sip_pvt *p, char *msg, struct sip_message *req, int retrans);
+static int transmit_response_with_t38_sdp(struct sip_pvt *p, const int code, char *msg, struct sip_message *req, int retrans);
 static struct ast_udptl *sip_get_udptl_peer(struct ast_channel *chan);
 static int sip_set_udptl_peer(struct ast_channel *chan, struct ast_udptl *udptl);
 static void change_t38_state(struct sip_pvt *p, int state);
@@ -4077,16 +4077,20 @@
 static int send_provisional_keepalive_full(struct sip_pvt *pvt, int with_sdp)
 {
 	const char *msg = NULL;
+	int code;
+
+	sscanf(pvt->last_provisional, " %30d", &code);
 
 	if (!pvt->last_provisional || !strncasecmp(pvt->last_provisional, "100", 3)) {
 		msg = "183 Session Progress";
+		code = 183;
 	}
 
 	if (pvt->invitestate < INV_COMPLETED) {
 		if (with_sdp) {
-			transmit_response_with_sdp(pvt, S_OR(msg, pvt->last_provisional), &pvt->initreq, XMIT_UNRELIABLE, FALSE, FALSE);
+			transmit_response_with_sdp(pvt, code, S_OR(msg, pvt->last_provisional), &pvt->initreq, XMIT_UNRELIABLE, FALSE, FALSE);
 		} else {
-			transmit_response(pvt, S_OR(msg, pvt->last_provisional), &pvt->initreq);
+			transmit_response(pvt, code, S_OR(msg, pvt->last_provisional), &pvt->initreq);
 		}
 		return PROVIS_KEEPALIVE_TIMEOUT;
 	}
@@ -4473,10 +4477,10 @@
 
 	switch (chan->_state) {
 	case AST_STATE_RING:
-		transmit_response(p, "100 Trying", &p->initreq);
+		transmit_response(p, 100, "100 Trying", &p->initreq);
 		break;
 	case AST_STATE_RINGING:
-		transmit_response(p, "180 Ringing", &p->initreq);
+		transmit_response(p, 180, "180 Ringing", &p->initreq);
 		break;
 	case AST_STATE_UP:
 		if (!p->pendinginvite) {		/* We are up, and have no outstanding invite */
@@ -6108,10 +6112,13 @@
 				}
 			} else {	/* Incoming call, not up */
 				const char *res;
-				if (p->hangupcause && (res = hangup_cause2sip(p->hangupcause)))
-					transmit_response_reliable(p, res, &p->initreq);
-				else
-					transmit_response_reliable(p, "603 Declined", &p->initreq);
+				if (p->hangupcause && (res = hangup_cause2sip(p->hangupcause))) {
+					int code;
+					sscanf(res, " %30d", &code);
+					transmit_response_reliable(p, code, res, &p->initreq);
+				} else {
+					transmit_response_reliable(p, 603, "603 Declined", &p->initreq);
+				}
 				p->invitestate = INV_TERMINATED;
 			}
 		} else {	/* Call is in UP state, send BYE */
@@ -6252,7 +6259,7 @@
 		ast_setstate(ast, AST_STATE_UP);
 		ast_debug(1, "SIP answering channel: %s\n", ast->name);
 		ast_rtp_instance_new_source(p->rtp);
-		res = transmit_response_with_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL, FALSE, TRUE);
+		res = transmit_response_with_sdp(p, 200, "200 OK", &p->initreq, XMIT_CRITICAL, FALSE, TRUE);
 		ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
 	}
 	sip_pvt_unlock(p);
@@ -6289,7 +6296,7 @@
 					ast_rtp_instance_new_source(p->rtp);
 					if (!global_prematuremediafilter) {
 						p->invitestate = INV_EARLY_MEDIA;
-						transmit_provisional_response(p, "183 Session Progress", &p->initreq, TRUE);
+						transmit_provisional_response(p, 183, "183 Session Progress", &p->initreq, TRUE);
 						ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT);
 					}
 				} else if (p->t38.state == T38_ENABLED) {
@@ -6312,7 +6319,7 @@
 				    !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) &&
 				    !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
 					p->invitestate = INV_EARLY_MEDIA;
-					transmit_provisional_response(p, "183 Session Progress", &p->initreq, TRUE);
+					transmit_provisional_response(p, 183, "183 Session Progress", &p->initreq, TRUE);
 					ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT);
 				}
 				p->lastrtptx = time(NULL);
@@ -6333,7 +6340,7 @@
 					    !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) &&
 					    !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
 						p->invitestate = INV_EARLY_MEDIA;
-						transmit_provisional_response(p, "183 Session Progress", &p->initreq, TRUE);
+						transmit_provisional_response(p, 183, "183 Session Progress", &p->initreq, TRUE);
 						ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT);
 					}
 					p->lastrtptx = time(NULL);
@@ -6510,7 +6517,7 @@
 			p->t38.our_parms.rate_management = p->t38.their_parms.rate_management;
 			ast_udptl_set_local_max_ifp(p->udptl, p->t38.our_parms.max_ifp);
 			change_t38_state(p, T38_ENABLED);
-			transmit_response_with_t38_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL);
+			transmit_response_with_t38_sdp(p, 200, "200 OK", &p->initreq, XMIT_CRITICAL);
 		} else if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT) && p->t38.state != T38_ENABLED) {
 			p->t38.our_parms = *parameters;
 			ast_udptl_set_local_max_ifp(p->udptl, p->t38.our_parms.max_ifp);
@@ -6528,7 +6535,7 @@
 		if (p->t38.state == T38_PEER_REINVITE) {
 			AST_SCHED_DEL_UNREF(sched, p->t38id, dialog_unref(p, "when you delete the t38id sched, you should dec the refcount for the stored dialog ptr"));
 			change_t38_state(p, T38_DISABLED);
-			transmit_response_reliable(p, "488 Not acceptable here", &p->initreq);
+			transmit_response_reliable(p, 488, "488 Not acceptable here", &p->initreq);
 		} else if (p->t38.state == T38_ENABLED)
 			transmit_reinvite_with_sdp(p, FALSE, FALSE);
 		break;
@@ -6555,7 +6562,7 @@
 			if (!ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) ||
 			    (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) == SIP_PROG_INBAND_NEVER)) {				
 				/* Send 180 ringing if out-of-band seems reasonable */
-				transmit_provisional_response(p, "180 Ringing", &p->initreq, 0);
+				transmit_provisional_response(p, 180, "180 Ringing", &p->initreq, 0);
 				ast_set_flag(&p->flags[0], SIP_RINGING);
 				if (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) != SIP_PROG_INBAND_YES)
 					break;
@@ -6567,7 +6574,7 @@
 		break;
 	case AST_CONTROL_BUSY:
 		if (ast->_state != AST_STATE_UP) {
-			transmit_response_reliable(p, "486 Busy Here", &p->initreq);
+			transmit_response_reliable(p, 486, "486 Busy Here", &p->initreq);
 			p->invitestate = INV_COMPLETED;
 			sip_alreadygone(p);
 			ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV);
@@ -6577,7 +6584,7 @@
 		break;
 	case AST_CONTROL_CONGESTION:
 		if (ast->_state != AST_STATE_UP) {
-			transmit_response_reliable(p, "503 Service Unavailable", &p->initreq);
+			transmit_response_reliable(p, 503, "503 Service Unavailable", &p->initreq);
 			p->invitestate = INV_COMPLETED;
 			sip_alreadygone(p);
 			ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV);
@@ -6589,7 +6596,7 @@
 		if ((ast->_state != AST_STATE_UP) &&
 		    !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) &&
 		    !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
-			transmit_response(p, "100 Trying", &p->initreq);
+			transmit_response(p, 100, "100 Trying", &p->initreq);
 			p->invitestate = INV_PROCEEDING;
 			break;
 		}
@@ -6600,7 +6607,7 @@
 		    !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) &&
 		    !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
 			p->invitestate = INV_EARLY_MEDIA;
-			transmit_provisional_response(p, "183 Session Progress", &p->initreq, TRUE);
+			transmit_provisional_response(p, 183, "183 Session Progress", &p->initreq, TRUE);
 			ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT);
 			break;
 		}
@@ -7406,11 +7413,11 @@
 	if (sip_methods[intended_method].can_create == CAN_CREATE_DIALOG) {
 		if (intended_method == SIP_REFER) {
 			/* We do support REFER, but not outside of a dialog yet */
-			transmit_response_using_temp(callid, sin, 1, intended_method, req, "603 Declined (no dialog)");
+			transmit_response_using_temp(callid, sin, 1, intended_method, req, "603 Declined (no dialog)", 603);
 		} else if (intended_method == SIP_NOTIFY) {
 			/* We do not support out-of-dialog NOTIFY either,
 		   	like voicemail notification, so cancel that early */
-			transmit_response_using_temp(callid, sin, 1, intended_method, req, "489 Bad event");
+			transmit_response_using_temp(callid, sin, 1, intended_method, req, "489 Bad event", 489);
 		} else {
 			/* Ok, time to create a new SIP dialog object, a pvt */
 			if ((p = sip_alloc(callid, sin, 1, intended_method, req)))  {
@@ -7425,18 +7432,18 @@
 	
 					Sorry, we apologize for the inconvienience
 				*/
-				transmit_response_using_temp(callid, sin, 1, intended_method, req, "500 Server internal error");
+				transmit_response_using_temp(callid, sin, 1, intended_method, req, "500 Server internal error", 500);
 				ast_debug(4, "Failed allocating SIP dialog, sending 500 Server internal error and giving up\n");
 			}
 		}
 		return p; /* can be NULL */
 	} else if( sip_methods[intended_method].can_create == CAN_CREATE_DIALOG_UNSUPPORTED_METHOD) {
 		/* A method we do not support, let's take it on the volley */
-		transmit_response_using_temp(callid, sin, 1, intended_method, req, "501 Method Not Implemented");
+		transmit_response_using_temp(callid, sin, 1, intended_method, req, "501 Method Not Implemented", 501);
 		ast_debug(2, "Got a request with unsupported SIP method.\n");
 	} else if (intended_method != SIP_RESPONSE && intended_method != SIP_ACK) {
 		/* This is a request outside of a dialog that we don't know about */
-		transmit_response_using_temp(callid, sin, 1, intended_method, req, "481 Call leg/transaction does not exist");
+		transmit_response_using_temp(callid, sin, 1, intended_method, req, "481 Call leg/transaction does not exist", 481);
 		ast_debug(2, "That's odd...  Got a request in unknown dialog. Callid %s\n", callid ? callid : "<unknown>");
 	}
 	/* We do not respond to responses for dialogs that we don't know about, we just drop
@@ -9255,6 +9262,7 @@
 	}
 	/* Initialize a response */
 	resp->method = SIP_RESPONSE;
+	resp->outbound = TRUE;
 	resp->is_resp = TRUE;
 	ast_str_set(&resp->data, 0, "SIP/2.0 %s\r\n", msg);
 	resp->len = resp->data->used;
@@ -9270,6 +9278,7 @@
 	}
 
 	/* Initialize a request */
+	message->outbound = TRUE;
 	message->method = sipmethod;
 	message->is_resp = FALSE;
 	ast_str_set(&message->data, 0, "%s %s SIP/2.0\r\n", sip_methods[sipmethod].text, ruri);
@@ -9535,7 +9544,7 @@
 }
 
 /*! \brief Base transmit response function */
-static int __transmit_response(struct sip_pvt *p, const char *msg, const struct sip_message *req, enum xmittype reliable)
+static int __transmit_response(struct sip_pvt *p, const int code, const char *msg, const struct sip_message *req, enum xmittype reliable)
 {
 	struct sip_message resp;
 	int seqno = 0;
@@ -9545,6 +9554,7 @@
 		return -1;
 	}
 	respprep(&resp, p, msg, req);
+	resp.response_code = code;
 
 	if (ast_test_flag(&p->flags[0], SIP_SENDRPID)
 			&& ast_test_flag(&p->flags[1], SIP_PAGE2_CONNECTLINEUPDATE_PEND)
@@ -9584,7 +9594,7 @@
 }
 
 /*! \brief Transmit response, no retransmits, using a temporary pvt structure */
-static int transmit_response_using_temp(ast_string_field callid, struct sockaddr_in *sin, int useglobal_nat, const int intended_method, const struct sip_message *req, const char *msg)
+static int transmit_response_using_temp(ast_string_field callid, struct sockaddr_in *sin, int useglobal_nat, const int intended_method, const struct sip_message *req, const char *msg, const int code)
 {
 	struct sip_pvt *p = NULL;
 
@@ -9627,7 +9637,7 @@
 	copy_socket_data(&p->socket, &req->socket);
 
 	/* Use this temporary pvt structure to send the message */
-	__transmit_response(p, msg, req, XMIT_UNRELIABLE);
+	__transmit_response(p, code, msg, req, XMIT_UNRELIABLE);
 
 	/* Free the string fields, but not the pool space */
 	ast_string_field_init(p, 0);
@@ -9636,30 +9646,32 @@
 }
 
 /*! \brief Transmit response, no retransmits */
-static int transmit_response(struct sip_pvt *p, const char *msg, const struct sip_message *req)
-{
-	return __transmit_response(p, msg, req, XMIT_UNRELIABLE);
+static int transmit_response(struct sip_pvt *p, const int code, const char *msg, const struct sip_message *req)
+{
+	return __transmit_response(p, code, msg, req, XMIT_UNRELIABLE);
 }
 
 /*! \brief Transmit response, no retransmits */
-static int transmit_response_with_unsupported(struct sip_pvt *p, const char *msg, const struct sip_message *req, const char *unsupported)
+static int transmit_response_with_unsupported(struct sip_pvt *p, const int code, const char *msg, const struct sip_message *req, const char *unsupported)
 {
 	struct sip_message resp;
 	respprep(&resp, p, msg, req);
 	append_date(&resp);
+	resp.response_code = code;
 	add_header(&resp, "Unsupported", unsupported);
 	add_header_contentLength(&resp, 0);
 	return send_response(p, &resp, XMIT_UNRELIABLE, 0);
 }
 
 /*! \brief Transmit 422 response with Min-SE header (Session-Timers)  */
-static int transmit_response_with_minse(struct sip_pvt *p, const char *msg, const struct sip_message *req, int minse_int)
+static int transmit_response_with_minse(struct sip_pvt *p, const int code, const char *msg, const struct sip_message *req, int minse_int)
 {
 	struct sip_message resp;
 	char minse_str[20];
 
 	respprep(&resp, p, msg, req);
 	append_date(&resp);
+	resp.response_code = code;
 
 	snprintf(minse_str, sizeof(minse_str), "%d", minse_int);
 	add_header(&resp, "Min-SE", minse_str);
@@ -9672,9 +9684,9 @@
 /*! \brief Transmit response, Make sure you get an ACK
 	This is only used for responses to INVITEs, where we need to make sure we get an ACK
 */
-static int transmit_response_reliable(struct sip_pvt *p, const char *msg, const struct sip_message *req)
-{
-	return __transmit_response(p, msg, req, req->ignore ? XMIT_UNRELIABLE : XMIT_CRITICAL);
+static int transmit_response_reliable(struct sip_pvt *p, const int code, const char *msg, const struct sip_message *req)
+{
+	return __transmit_response(p, code, msg, req, req->ignore ? XMIT_UNRELIABLE : XMIT_CRITICAL);
 }
 
 /*! \brief Append date to SIP message */
@@ -9690,27 +9702,29 @@
 }
 
 /*! \brief Append date and content length before transmitting response */
-static int transmit_response_with_date(struct sip_pvt *p, const char *msg, const struct sip_message *req)
+static int transmit_response_with_date(struct sip_pvt *p, const int code, const char *msg, const struct sip_message *req)
 {
 	struct sip_message resp;
 	respprep(&resp, p, msg, req);
 	append_date(&resp);
+	resp.response_code = code;
 	add_header_contentLength(&resp, 0);
 	return send_response(p, &resp, XMIT_UNRELIABLE, 0);
 }
 
 /*! \brief Append Accept header, content length before transmitting response */
-static int transmit_response_with_allow(struct sip_pvt *p, const char *msg, const struct sip_message *req, enum xmittype reliable)
+static int transmit_response_with_allow(struct sip_pvt *p, const int code, const char *msg, const struct sip_message *req, enum xmittype reliable)
 {
 	struct sip_message resp;
 	respprep(&resp, p, msg, req);
+	resp.response_code = code;
 	add_header(&resp, "Accept", "application/sdp");
 	add_header_contentLength(&resp, 0);
 	return send_response(p, &resp, reliable, 0);
 }
 
 /*! \brief Respond with authorization request */
-static int transmit_response_with_auth(struct sip_pvt *p, const char *msg, const struct sip_message *req, const char *randdata, enum xmittype reliable, const char *header, int stale)
+static int transmit_response_with_auth(struct sip_pvt *p, const int code, const char *msg, const struct sip_message *req, const char *randdata, enum xmittype reliable, const char *header, int stale)
 {
 	struct sip_message resp;
 	char tmp[512];
@@ -9727,6 +9741,7 @@
 	   based it on an old challenge (nonce) */
 	snprintf(tmp, sizeof(tmp), "Digest algorithm=MD5, realm=\"%s\", nonce=\"%s\"%s", p->realm, randdata, stale ? ", stale=true" : "");
 	respprep(&resp, p, msg, req);
+	resp.response_code = code;
 	add_header(&resp, header, tmp);
 	add_header_contentLength(&resp, 0);
 	append_history(p, "AuthChal", "Auth challenge sent for %s - nc %d", p->username, p->noncecount);
@@ -9807,12 +9822,13 @@
 	ast_string_field_set(p, realm, sip_cfg.realm);
 }
 
-/* Only use a static string for the msg, here! */
-static int transmit_provisional_response(struct sip_pvt *p, const char *msg, const struct sip_message *req, int with_sdp)
+/*! \brief Transmit provisional response (like 180 ringing)
+\note	 Only use a static string for the msg, here! */
+static int transmit_provisional_response(struct sip_pvt *p, const int code, const char *msg, const struct sip_message *req, int with_sdp)
 {
 	int res;
 
-	if (!(res = with_sdp ? transmit_response_with_sdp(p, msg, req, XMIT_UNRELIABLE, FALSE, FALSE) : transmit_response(p, msg, req))) {
+	if (!(res = with_sdp ? transmit_response_with_sdp(p, code, msg, req, XMIT_UNRELIABLE, FALSE, FALSE) : transmit_response(p, code, msg, req))) {
 		p->last_provisional = msg;
 		update_provisional_keepalive(p, with_sdp);
 	}
@@ -10513,7 +10529,7 @@
 }
 
 /*! \brief Used for 200 OK and 183 early media */
-static int transmit_response_with_t38_sdp(struct sip_pvt *p, char *msg, struct sip_message *req, int retrans)
+static int transmit_response_with_t38_sdp(struct sip_pvt *p, const int code, char *msg, struct sip_message *req, int retrans)
 {
 	struct sip_message resp;
 	int seqno;
@@ -10523,6 +10539,7 @@
 		return -1;
 	}
 	respprep(&resp, p, msg, req);
+	resp.response_code = code;
 	if (p->udptl) {
 		add_sdp(&resp, p, 0, 0, 1);
 	} else
@@ -10572,15 +10589,17 @@
 /*! \brief Used for 200 OK and 183 early media
 	\return Will return XMIT_ERROR for network errors.
 */
-static int transmit_response_with_sdp(struct sip_pvt *p, const char *msg, const struct sip_message *req, enum xmittype reliable, int oldsdp, int rpid)
+static int transmit_response_with_sdp(struct sip_pvt *p, const int code, const char *msg, const struct sip_message *req, enum xmittype reliable, int oldsdp, int rpid)
 {
 	struct sip_message resp;
 	int seqno;
+
 	if (sscanf(get_header(req, "CSeq"), "%30d ", &seqno) != 1) {
 		ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq"));
 		return -1;
 	}
 	respprep(&resp, p, msg, req);
+	resp.response_code = code;
 	if (rpid == TRUE) {
 		add_rpid(&resp, p);
 	}
@@ -12781,6 +12800,7 @@
 	const char *usednonce = p->randdata;
 	struct ast_str *buf;
 	int res;
+	int respcode;
 
 	/* table of recognised keywords, and their value in the digest */
 	enum keys { K_RESP, K_URI, K_USER, K_NONCE, K_LAST };
@@ -12802,6 +12822,7 @@
 	/* Always auth with WWW-auth since we're NOT a proxy */
 	/* Using proxy-auth in a B2BUA may block proxy authorization in the same transaction */
 	response = "401 Unauthorized";
+	respcode = 401;
 
 	/*
 	 * Note the apparent swap of arguments below, compared to other
@@ -12816,7 +12837,7 @@
 		if (!reliable) {
 			/* Resend message if this was NOT a reliable delivery.   Otherwise the
 			   retransmission should get it */
-			transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0);
+			transmit_response_with_auth(p, respcode, response, req, p->randdata, reliable, respheader, 0);
 			/* Schedule auto destroy in 32 seconds (according to RFC 3261) */
 			sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
 		}
@@ -12824,7 +12845,7 @@
 	} else if (ast_strlen_zero(p->randdata) || ast_strlen_zero(authtoken)) {
 		/* We have no auth, so issue challenge and request authentication */
 		set_nonce_randdata(p, 1); /* Create nonce for challenge */
-		transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0);
+		transmit_response_with_auth(p, respcode, response, req, p->randdata, reliable, respheader, 0);
 		/* Schedule auto destroy in 32 seconds */
 		sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
 		return AUTH_CHALLENGE_SENT;
@@ -12912,7 +12933,7 @@
 				ast_log(LOG_NOTICE, "Correct auth, but based on stale nonce received from '%s'\n", get_header(req, "To"));
 			/* We got working auth token, based on stale nonce . */
 			set_nonce_randdata(p, 0);
-			transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, TRUE);
+			transmit_response_with_auth(p, respcode, response, req, p->randdata, reliable, respheader, TRUE);
 		} else {
 			/* Everything was wrong, so give the device one more try with a new challenge */
 			if (!req->ignore) {
@@ -12923,7 +12944,7 @@
 				if (sipdebug)
 					ast_log(LOG_NOTICE, "Duplicate authentication received from '%s'\n", get_header(req, "To"));
 			}
-			transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, FALSE);
+			transmit_response_with_auth(p, respcode, response, req, p->randdata, reliable, respheader, FALSE);
 		}
 
 		/* Schedule auto destroy in 32 seconds */
@@ -13022,6 +13043,7 @@
 	const char *response = "407 Proxy Authentication Required";
 	const char *reqheader = "Proxy-Authorization";
 	const char *respheader = "Proxy-Authenticate";
+	int respcode = 407;
 	const char *authtoken;
 	struct ast_str *buf;
 	char *c;
@@ -13040,32 +13062,33 @@
 		response = "401 Unauthorized";
 		reqheader = "Authorization";
 		respheader = "WWW-Authenticate";
+		respcode = 401;
 	}
 	authtoken = get_header(req, reqheader);
 	if (req->ignore && !ast_strlen_zero(p->randdata) && ast_strlen_zero(authtoken)) {
 		/* This is a retransmitted invite/register/etc, don't reconstruct authentication
 		 * information */
-		transmit_response_with_auth(p, response, req, p->randdata, 0, respheader, 0);
+		transmit_response_with_auth(p, respcode, response, req, p->randdata, 0, respheader, 0);
 		/* Schedule auto destroy in 32 seconds (according to RFC 3261) */
 		sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
 		return;
 	} else if (ast_strlen_zero(p->randdata) || ast_strlen_zero(authtoken)) {
 		/* We have no auth, so issue challenge and request authentication */
 		set_nonce_randdata(p, 1);
-		transmit_response_with_auth(p, response, req, p->randdata, 0, respheader, 0);
+		transmit_response_with_auth(p, respcode, response, req, p->randdata, 0, respheader, 0);
 		/* Schedule auto destroy in 32 seconds */
 		sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
 		return;
 	}
 
 	if (!(buf = ast_str_thread_get(&check_auth_buf, CHECK_AUTH_BUF_INITLEN))) {
-		transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq);
+		transmit_response(p, 403, "403 Forbidden (Bad auth)", &p->initreq);
 		return;
 	}
 
 	/* Make a copy of the response and parse it */
 	if (ast_str_set(&buf, 0, "%s", authtoken) == AST_DYNSTR_BUILD_FAILED) {
-		transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq);
+		transmit_response(p, 403, "403 Forbidden (Bad auth)", &p->initreq);
 		return;
 	}
 
@@ -13098,12 +13121,12 @@
 		if (!req->ignore) {
 			set_nonce_randdata(p, 1);
 		}
-		transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, FALSE);
+		transmit_response_with_auth(p, respcode, response, req, p->randdata, reliable, respheader, FALSE);
 
 		/* Schedule auto destroy in 32 seconds */
 		sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
 	} else {
-		transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq);
+		transmit_response(p, 403, "403 Forbidden (Bad auth)", &p->initreq);
 	}
 }
 
@@ -13174,7 +13197,7 @@
 			*c = '\0';
 		if (!AST_LIST_EMPTY(&domain_list)) {
 			if (!check_sip_domain(domain, NULL, 0)) {
-				transmit_response(p, "404 Not found (unknown domain)", &p->initreq);
+				transmit_response(p, 404, "404 Not found (unknown domain)", &p->initreq);
 				return AUTH_UNKNOWN_DOMAIN;
 			}
 		}
@@ -13204,14 +13227,14 @@
 		} else {
 			ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_NAT_FORCE_RPORT);
 			if (ast_test_flag(&p->flags[1], SIP_PAGE2_REGISTERTRYING))
-				transmit_response(p, "100 Trying", req);
+				transmit_response(p, 100, "100 Trying", req);
 			if (!(res = check_auth(p, req, peer->name, peer->secret, peer->md5secret, SIP_REGISTER, uri2, XMIT_UNRELIABLE, req->ignore))) {
 				if (sip_cancel_destroy(p))
 					ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
 
 				if (check_request_transport(peer, req)) {
 					ast_set_flag(&p->flags[0], SIP_PENDINGBYE);
-					transmit_response_with_date(p, "403 Forbidden", req);
+					transmit_response_with_date(p, 403, "403 Forbidden", req);
 					res = AUTH_BAD_TRANSPORT;
 				} else {
 
@@ -13220,19 +13243,19 @@
 					switch (parse_register_contact(p, peer, req)) {
 					case PARSE_REGISTER_FAILED:
 						ast_log(LOG_WARNING, "Failed to parse contact info\n");
-						transmit_response_with_date(p, "400 Bad Request", req);
+						transmit_response_with_date(p, 400, "400 Bad Request", req);
 						peer->lastmsgssent = -1;
 						res = 0;
 						break;
 					case PARSE_REGISTER_QUERY:
-						transmit_response_with_date(p, "200 OK", req);
+						transmit_response_with_date(p, 200, "200 OK", req);
 						peer->lastmsgssent = -1;
 						res = 0;
 						break;
 					case PARSE_REGISTER_UPDATE:
 						update_peer(peer, p->expiry);
 						/* Say OK and ask subsystem to retransmit msg counter */
-						transmit_response_with_date(p, "200 OK", req);
+						transmit_response_with_date(p, 200, "200 OK", req);
 						if (!ast_test_flag((&peer->flags[1]), SIP_PAGE2_SUBSCRIBEMWIONLY))
 							peer->lastmsgssent = -1;
 						res = 0;
@@ -13258,18 +13281,18 @@
 			switch (parse_register_contact(p, peer, req)) {
 			case PARSE_REGISTER_FAILED:
 				ast_log(LOG_WARNING, "Failed to parse contact info\n");
-				transmit_response_with_date(p, "400 Bad Request", req);
+				transmit_response_with_date(p, 400, "400 Bad Request", req);
 				peer->lastmsgssent = -1;
 				res = 0;
 				break;
 			case PARSE_REGISTER_QUERY:
-				transmit_response_with_date(p, "200 OK", req);
+				transmit_response_with_date(p, 200, "200 OK", req);
 				peer->lastmsgssent = -1;
 				res = 0;
 				break;
 			case PARSE_REGISTER_UPDATE:
 				/* Say OK and ask subsystem to retransmit msg counter */
-				transmit_response_with_date(p, "200 OK", req);
+				transmit_response_with_date(p, 200, "200 OK", req);
 				manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: Registered\r\nAddress: %s\r\nPort: %d\r\n", peer->name, ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
 				peer->lastmsgssent = -1;
 				res = 0;
@@ -13282,7 +13305,7 @@
 		/* If we found a peer, we transmit a 100 Trying.  Therefore, if we're
 		 * trying to avoid leaking information, we MUST also transmit the same
 		 * response when we DON'T find a peer. */
-		transmit_response(p, "100 Trying", req);
+		transmit_response(p, 100, "100 Trying", req);
 		/* Insert a fake delay between the 100 and the subsequent failure. */
 		sched_yield();
 	}
@@ -13293,7 +13316,7 @@
 		switch (res) {
 		case AUTH_SECRET_FAILED:
 			/* Wrong password in authentication. Go away, don't try again until you fixed it */
-			transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq);
+			transmit_response(p, 403, "403 Forbidden (Bad auth)", &p->initreq);
 			if (global_authfailureevents)
 				manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: Rejected\r\nCause: AUTH_SECRET_FAILED\r\nAddress: %s\r\nPort: %d\r\n",
 					name, ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
@@ -13303,7 +13326,7 @@
 			   Asterisk uses the From: username for authentication. We need the
 			   devices to use the same authentication user name until we support
 			   proper authentication by digest auth name */
-			transmit_response(p, "403 Authentication user name does not match account name", &p->initreq);
+			transmit_response(p, 403, "403 Authentication user name does not match account name", &p->initreq);
 			if (global_authfailureevents)
 				manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: Rejected\r\nCause: AUTH_USERNAME_MISMATCH\r\nAddress: %s\r\nPort: %d\r\n",
 					name, ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
@@ -13321,13 +13344,13 @@
 			} else {
 				/* URI not found */
 				if (res == AUTH_PEER_NOT_DYNAMIC) {
-					transmit_response(p, "403 Forbidden", &p->initreq);
+					transmit_response(p, 403, "403 Forbidden", &p->initreq);
 					if (global_authfailureevents)
 						manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: Rejected\r\nCause: AUTH_PEER_NOT_DYNAMIC\r\nAddress: %s\r\nPort: %d\r\n",
 							name, ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
 					}
 				else
-					transmit_response(p, "404 Not found", &p->initreq);
+					transmit_response(p, 403, "404 Not found", &p->initreq);
 					if (global_authfailureevents)
 						manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: Rejected\r\nCause: URI_NOT_FOUND\r\nAddress: %s\r\nPort: %d\r\n",
 							name, ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
@@ -14548,7 +14571,7 @@
 	const char *content_type = get_header(req, "Content-Type");
 
 	if (strncmp(content_type, "text/plain", strlen("text/plain"))) { /* No text/plain attachment */
-		transmit_response(p, "415 Unsupported Media Type", req); /* Good enough, or? */
+		transmit_response(p, 415, "415 Unsupported Media Type", req); /* Good enough, or? */
 		if (!p->owner)
 			sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
 		return;
@@ -14556,7 +14579,7 @@
 
 	if (get_msg_text(buf, sizeof(buf), req, FALSE)) {
 		ast_log(LOG_WARNING, "Unable to retrieve text from %s\n", p->callid);
-		transmit_response(p, "202 Accepted", req);
+		transmit_response(p, 202, "202 Accepted", req);
 		if (!p->owner)
 			sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
 		return;
@@ -14572,13 +14595,13 @@
 		f.data.ptr = buf;
 		f.datalen = strlen(buf);
 		ast_queue_frame(p->owner, &f);
-		transmit_response(p, "202 Accepted", req); /* We respond 202 accepted, since we relay the message */
+		transmit_response(p, 202, "202 Accepted", req); /* We respond 202 accepted, since we relay the message */
 		return;
 	}
 
 	/* Message outside of a call, we do not support that */
 	ast_log(LOG_WARNING, "Received message to %s from %s, dropped it...\n  Content-Type:%s\n  Message: %s\n", get_header(req, "To"), get_header(req, "From"), content_type, buf);
-	transmit_response(p, "405 Method Not Allowed", req);
+	transmit_response(p, 405, "405 Method Not Allowed", req);
 	sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
 	return;
 }
@@ -16866,7 +16889,7 @@
 		unsigned int duration = 0;
 
 		if (!p->owner) {	/* not a PBX call */
-			transmit_response(p, "481 Call leg/transaction does not exist", req);
+			transmit_response(p, 481, "481 Call leg/transaction does not exist", req);
 			sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
 			return;
 		}
@@ -16874,7 +16897,7 @@
 		/* Try getting the "signal=" part */
 		if (ast_strlen_zero(c = get_body(req, "Signal", '=')) && ast_strlen_zero(c = get_body(req, "d", '='))) {
 			ast_log(LOG_WARNING, "Unable to retrieve DTMF signal from INFO message from %s\n", p->callid);
-			transmit_response(p, "200 OK", req); /* Should return error */
+			transmit_response(p, 200, "200 OK", req); /* Should return error */
 			return;
 		} else {
 			ast_copy_string(buf, c, sizeof(buf));
@@ -16887,7 +16910,7 @@
 
 
 		if (ast_strlen_zero(buf)) {
-			transmit_response(p, "200 OK", req);
+			transmit_response(p, 200, "200 OK", req);
 			return;
 		}
 
@@ -16924,14 +16947,14 @@
 			if (sipdebug)
 				ast_verbose("* DTMF-relay event received: %c\n", f.subclass);
 		}
-		transmit_response(p, "200 OK", req);
+		transmit_response(p, 200, "200 OK", req);
 		return;
 	} else if (!strcasecmp(c, "application/dtmf")) {
 		/*! \todo Note: Doesn't read the duration of the DTMF. Should be fixed. */
 		unsigned int duration = 0;
 
 		if (!p->owner) {	/* not a PBX call */
-			transmit_response(p, "481 Call leg/transaction does not exist", req);
+			transmit_response(p, 481, "481 Call leg/transaction does not exist", req);
 			sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
 			return;
 		}
@@ -16940,7 +16963,7 @@
 		duration = 100; /* 100 ms */
 
 		if (ast_strlen_zero(buf)) {
-			transmit_response(p, "200 OK", req);
+			transmit_response(p, 200, "200 OK", req);
 			return;
 		}
 		event = atoi(buf);
@@ -16967,14 +16990,14 @@
 			if (sipdebug)
 				ast_verbose("* DTMF-relay event received: %c\n", f.subclass);
 		}
-		transmit_response(p, "200 OK", req);
+		transmit_response(p, 200, "200 OK", req);
 		return;
 
 	} else if (!strcasecmp(c, "application/media_control+xml")) {
 		/* Eh, we'll just assume it's a fast picture update for now */
 		if (p->owner)
 			ast_queue_control(p->owner, AST_CONTROL_VIDUPDATE);
-		transmit_response(p, "200 OK", req);
+		transmit_response(p, 200, "200 OK", req);
 		return;
 	} else if (!ast_strlen_zero(c = get_header(req, "X-ClientCode"))) {
 		/* Client code (from SNOM phone) */
@@ -16983,9 +17006,9 @@
 				ast_cdr_setuserfield(p->owner, c);
 			if (p->owner && ast_bridged_channel(p->owner) && ast_bridged_channel(p->owner)->cdr)
 				ast_cdr_setuserfield(ast_bridged_channel(p->owner), c);
-			transmit_response(p, "200 OK", req);
+			transmit_response(p, 200, "200 OK", req);
 		} else {
-			transmit_response(p, "403 Forbidden", req);
+			transmit_response(p, 403, "403 Forbidden", req);
 		}
 		return;
 	} else if (!ast_strlen_zero(c = get_header(req, "Record"))) {
@@ -17005,7 +17028,7 @@
 		if (!feat || ast_strlen_zero(feat->exten)) {
 			ast_log(LOG_WARNING, "Recording requested, but no One Touch Monitor registered. (See features.conf)\n");
 			/* 403 means that we don't support this feature, so don't request it again */
-			transmit_response(p, "403 Forbidden", req);
+			transmit_response(p, 403, "403 Forbidden", req);
 			ast_unlock_call_features();
 			return;
 		}
@@ -17020,11 +17043,11 @@
 		ast_unlock_call_features();
 
 		ast_debug(1, "Got a Request to Record the channel, state %s\n", c);
-		transmit_response(p, "200 OK", req);
+		transmit_response(p, 200, "200 OK", req);
 		return;
 	} else if (ast_strlen_zero(c = get_header(req, "Content-Length")) || !strcasecmp(c, "0")) {
 		/* This is probably just a packet making sure the signalling is still up, just send back a 200 OK */
-		transmit_response(p, "200 OK", req);
+		transmit_response(p, 200, "200 OK", req);
 		return;
 	}
 

[... 790 lines stripped ...]



More information about the asterisk-commits mailing list