add: PROTO_UDP,
context: int fifo_uac_dlg( FILE *stream, char *response_file ) {	char method[MAX_METHOD];	char dst[MAX_DST];	char r_uri[MAX_DST];	char to[MAX_FROM];	char to_tag[MAX_FROM];	char from[MAX_FROM];	char from_tag[MAX_FROM];	char cseq_buf[32]; //TODO: use a #define	int cseq_i=0;	char call_id[128]; //TODO: use a #define	char header[MAX_HEADER];	char body[MAX_BODY];	str sm, sd, sr, st, stt, sf, sft, scseq, scid, sh, sb;	char *shmem_file;	int fn_len;	int ret;	int sip_error;	char err_buf[MAX_REASON_LEN];	int err_ret;	load_tm_f        load_tm;	struct tm_binds  tmb;	sm.s=method; sd.s=dst; sr.s=r_uri; st.s=to; stt.s=to_tag; sf.s=from;	sft.s=from_tag;	scseq.s=cseq_buf; scid.s=call_id; sh.s=header; sb.s=body;	// method	if (!read_line(method, MAX_METHOD, stream,&sm.len)||sm.len==0) {		/* line breaking must have failed -- consume the rest		   and proceed to a new request		*/		LOG(L_ERR, "ERROR: fifo_vm_uac: method expected\n");		fifo_reply(response_file, 			"400 fifo_vm_uac: method expected");		return 1;	}	DBG("DEBUG: fifo_vm_uac: method: %.*s\n", sm.len, method );	// dst	if (!read_line(dst, MAX_DST, stream, &sd.len)||sd.len==0) {		fifo_reply(response_file, 			"400 fifo_vm_uac: destination expected\n");		LOG(L_ERR, "ERROR: fifo_vm_uac: destination expected\n");		return 1;	}	DBG("DEBUG: fifo_vm_uac:  dst: %.*s\n", sd.len, dst );	// [r-uri]	if (!read_line(sr.s, MAX_DST, stream, &sr.len)) {		fifo_reply(response_file, 			"400 fifo_vm_uac: r-uri expected\n");		LOG(L_ERR, "ERROR: fifo_vm_uac: r-uri expected\n");		return 1;	}	DBG("DEBUG: fifo_vm_uac:  r-uri: %.*s\n", sr.len, sr.s );	// [to]	if (!read_line(st.s, MAX_FROM, stream, &st.len)) {		fifo_reply(response_file, 			"400 fifo_vm_uac: to expected\n");		LOG(L_ERR, "ERROR: fifo_vm_uac: to expected\n");		return 1;	}	DBG("DEBUG: fifo_vm_uac:  to: %.*s\n", st.len, st.s );	// [to_tag]	if (!read_line(stt.s, MAX_FROM, stream, &stt.len)) {		fifo_reply(response_file, 			"400 fifo_vm_uac: to expected\n");		LOG(L_ERR, "ERROR: fifo_vm_uac: to expected\n");		return 1;	}	DBG("DEBUG: fifo_vm_uac:  to-tag: %.*s\n", stt.len, stt.s );	// [from]	if (!read_line(from, MAX_FROM, stream, &sf.len)) {		fifo_reply(response_file, 			"400 fifo_vm_uac: from expected\n");		LOG(L_ERR, "ERROR: fifo_vm_uac: from expected\n");		return 1;	}	DBG("DEBUG: fifo_vm_uac:  from: %.*s\n", sf.len, from);	// [from-tag]	if (!read_line(from_tag, MAX_FROM, stream, &sft.len)) {		fifo_reply(response_file, 			"400 fifo_vm_uac: from-tag expected\n");		LOG(L_ERR, "ERROR: fifo_vm_uac: from-tag expected\n");		return 1;	}	DBG("DEBUG: fifo_vm_uac:  from-tag: %.*s\n", sft.len, from_tag);	// [cseq]	if (!read_line(scseq.s, 32, stream, &scseq.len)) {		fifo_reply(response_file, 			"400 fifo_vm_uac: cseq expected\n");		LOG(L_ERR, "ERROR: fifo_vm_uac: cseq expected\n");		return 1;	}	DBG("DEBUG: fifo_vm_uac:  cseq: %.*s\n", scseq.len, scseq.s);	// convert scseq to integer into cseq	if(sscanf(scseq.s,"%i",&cseq_i) != 1){		fifo_reply(response_file, 			"400 fifo_vm_uac: cseq has bad format\n");		LOG(L_ERR, "ERROR: fifo_vm_uac: cseq has bad format\n");		return 1;	}	DBG("DEBUG: fifo_vm_uac:  cseq_i: %i\n", cseq_i);	// [call id]	if (!read_line(scid.s, 128, stream, &scid.len)) {		fifo_reply(response_file, 			"400 fifo_vm_uac: cseq expected\n");		LOG(L_ERR, "ERROR: fifo_vm_uac: cseq expected\n");		return 1;	}	DBG("DEBUG: fifo_vm_uac:  call id: %.*s\n", scid.len, scid.s);	/* now read header fields line by line */	if (!read_line_set(header, MAX_HEADER, stream, &sh.len)) {		fifo_reply(response_file, 			"400 fifo_vm_uac: HFs expected\n");		LOG(L_ERR, "ERROR: fifo_vm_uac: header fields expected\n");		return 1;	}	DBG("DEBUG: fifo_vm_uac: header: %.*s\n", sh.len, header );	/* and eventually body */	if (!read_body(body, MAX_BODY, stream, &sb.len)) {		fifo_reply(response_file, 			"400 fifo_vm_uac: body expected\n");		LOG(L_ERR, "ERROR: fifo_vm_uac: body expected\n");		return 1;	}	DBG("DEBUG: fifo_vm_uac: body: %.*s\n", sb.len, body );	DBG("DEBUG: fifo_vm_uac: EoL -- proceeding to transaction creation\n");	/* we got it all, initiate transaction now! */	if (response_file) {		fn_len=strlen(response_file)+1;		shmem_file=shm_malloc(fn_len);		if (shmem_file==0) {			LOG(L_ERR, "ERROR: fifo_vm_uac: no shmem\n");			fifo_reply(response_file, 				"500 fifo_vm_uac: no memory for shmem_file\n");			return 1;		}		memcpy(shmem_file, response_file, fn_len );	} else {		shmem_file=0;	}    if (!(load_tm = (load_tm_f)find_export("load_tm",NO_SCRIPT))){	LOG(L_ERR,"ERROR: fifo_t_reply: could not load 'load_tm'. module tm should be loaded !\n");	return 1;    }    if ((*load_tm)(&tmb)==-1) {	LOG(L_ERR,"ERROR: fifo_t_reply: 'load_tm' failed\n");	return 1;    }    /* HACK: there is yet a shortcoming -- if t_uac fails, callback       will not be triggered and no feedback will be printed       to shmem_file    */    ret=(*tmb.t_uac_dlg)(&sm,			 sd.len==0 ? 0 : &sd,			 sr.len==0 ? 0 : &sr,			 st.len==0 ? 0 : &st,			 sf.len==0 ? 0 : &sf,			 /*stt.len==0 ? 0 :*/ &stt,			 sft.len==0 ? 0 : &sft,			 (int*)&cseq_i,			 scid.len==0 ? 0 : &scid,			 sh.len==0 ? 0 : &sh,			 sb.len==0 ? 0 : &sb,			 fifo_callback,shmem_file);    if (ret<=0) {	err_ret=err2reason_phrase(ret, &sip_error, err_buf,				  sizeof(err_buf), "FIFO/UAC" ) ;	if (err_ret > 0 )	{	    fifo_reply(response_file, "%d %s", sip_error, err_buf );	} else {	    fifo_reply(response_file, "500 FIFO/UAC error: %d\n",		       ret );	}    }    return 1;}