/*
Patch to add auto-answer feature for AMI Originate command.
The Originate command has to set a Variable "AUTO_ANSWER_A=1".
All lines marked with + have to be added in file "channels/chan_sip.c" or "channels\sip\include\sip.h".
Then you have to call "make install" for your Asterisk project again.

Tested with snom 360, firmware version: snom360-SIP 7.3.7 14671
Asterisk: 1.8
*/ 

// "channels\sip\include\sip.h":

struct sip_pvt {
	struct sip_pvt *next;			/*!< Next dialog in chain */
	
...

	struct sip_subscription_mwi *mwi;       /*!< If this is a subscription MWI dialog, to which subscription */
+	int  addHeaderAutoAnswer;		/*!< for Originate AUTO_ANSWER_A */ 
+	char addHeaderAutoAnswerInfoLine[100];	/*!< for Originate AUTO_ANSWER_A */ 
};



// "channels/chan_sip.c":

static int sip_call(struct ast_channel *ast, char *dest, int timeout)
{

...

	/* Check whether there is vxml_url, distinctive ring variables */
	headp=&ast->varshead;
	AST_LIST_TRAVERSE(headp, current, entries) {
		/* Check whether there is a VXML_URL variable */
		//ast_log(LOG_WARNING, "ast_var_name=%s\n",ast_var_name(current));
		if (!p->options->vxml_url && !strcasecmp(ast_var_name(current), "VXML_URL")) {
			p->options->vxml_url = ast_var_value(current);
		} else if (!p->options->uri_options && !strcasecmp(ast_var_name(current), "SIP_URI_OPTIONS")) {
			p->options->uri_options = ast_var_value(current);
		} else if (!p->options->addsipheaders && !strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) {
			/* Check whether there is a variable with a name starting with SIPADDHEADER */
			p->options->addsipheaders = 1;
		} else if (!strcasecmp(ast_var_name(current), "SIPFROMDOMAIN")) {
			ast_string_field_set(p, fromdomain, ast_var_value(current));
		} else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER")) {
			/* This is a transfered call */
			p->options->transfer = 1;
		} else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER_REFERER")) {
			/* This is the referrer */
			referer = ast_var_value(current);
		} else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER_REPLACES")) {
			/* We're replacing a call. */
			p->options->replaces = ast_var_value(current);
		} else if (!strcasecmp(ast_var_name(current), "T38CALL")) {
			p->t38.state = T38_LOCAL_DIRECT;
			ast_debug(1, "T38State change to %d on channel %s\n", p->t38.state, ast->name);
+		} else if (!strcasecmp(ast_var_name(current), "AUTO_ANSWER_A")) {
+			const char *value = ast_var_value(current);
+			p->addHeaderAutoAnswer = atoi(value);
+			const char *infoLine = strchr(value,';');
+			if ( infoLine )
+				strncpy(p->addHeaderAutoAnswerInfoLine,&infoLine[1],sizeof(p->addHeaderAutoAnswerInfoLine));
		}

	}
	
...

}


static int transmit_invite(struct sip_pvt *p, int sipmethod, int sdp, int init)
{

...

	/* This new INVITE is part of an attended transfer. Make sure that the
	other end knows and replace the current call with this new call */
	if (p->options && !ast_strlen_zero(p->options->replaces)) {
		add_header(&req, "Replaces", p->options->replaces);
		add_header(&req, "Require", "replaces");
	}
	
+	if ( p->addHeaderAutoAnswer )	/* if Originate sets a variable: AUTO_ANSWER_A=1..n */
+	{
+		const char *infoFmt = "";
+		switch ( p->addHeaderAutoAnswer )
+		{
+		case 2:  infoFmt = "Call-Info: answer-after=0";				break; // Mode2 (ohne IP)
+		case 4:  infoFmt = "Alert-Info: info=alert-autoanswer";			break; // Aastra 5xi
+		case 5:  infoFmt = "Alert-Info: Auto Answer";				break; // Polycom
+		case 8:  infoFmt = "Alert-Info: <sip:%s>;info=alert-autoanswer";	break; // OpenStage
+		case 10: infoFmt = p->addHeaderAutoAnswerInfoLine;			break; // User-defined Info Header
+		default: infoFmt = "Call-Info: <sip:%s>\\;answer-after=0";		break; // Standard: Lyncsys, Snom, Grandstream, Snom, Tiptel
+		}
+		if ( *infoFmt )
+		{
+			char info[100];
+			//snprintf(info, sizeof(info), infoFmt, ast_inet_ntoa(p->ourip.sin_addr));	// Asterisk 1.6
+			snprintf(info, sizeof(info), infoFmt, ast_sockaddr_stringify_addr(&p->ourip));	// Asterisk 1.8
+			char *infoParams = strchr(info,':');
+			if ( infoParams )
+			{
+				infoParams[0] = 0;
+				add_header(&req, info, &infoParams[2]);
+			}
+		}
+	}

	/* Add Session-Timers related headers */

...

}