All pastes #592896 Raw Edit

Stuff

public text v1 · immutable
#592896 ·published 2007-06-28 00:06 UTC
rendered paste body

static switch_status_t my_on_hangup(switch_core_session_t *session)
{
	switch_xml_t cdr;
	char *xml_text;
	char *path;
	int fd = -1;
	uint32_t curTry;
	long httpRes;
	CURL *curl_handle = NULL;
	char *curl_xml_text;
	char *logdir;
	switch_channel_t *channel = switch_core_session_get_channel(session);

	if (switch_ivr_generate_xml_cdr(session, &cdr) == SWITCH_STATUS_SUCCESS) {

		/* build the XML */
		if(!(xml_text = switch_mprintf("<?xml version=\"1.0\"?>\n%s",switch_xml_toxml(cdr)) )) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
			return SWITCH_STATUS_FALSE;
		}

		/* do we log to the disk no matter what? */
		/* all previous functionality is retained */

		if (!(logdir = switch_channel_get_variable(channel, "xml_cdr_base"))) {
			logdir = globals.logDir;
		}

		if(!switch_strlen_zero(logdir)) {
			if ((path = switch_mprintf("%s/xml_cdr/%s.cdr.xml", logdir, switch_core_session_get_uuid(session)))) {
				if ((fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR)) > -1) {
					write(fd, xml_text, (unsigned) strlen(xml_text));
					close(fd);
					fd = -1;
				} else {
					char ebuf[512] = { 0 };
#ifdef WIN32
					strerror_s(ebuf, sizeof(ebuf), errno);
#else
					strerror_r(errno, ebuf, sizeof(ebuf));
#endif
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error![%s]\n", ebuf);
				}
				free(path);
			}
		}

		/* try to post it to the web server */
		if(!switch_strlen_zero(globals.url)) {
			curl_handle = curl_easy_init();
			if(!(curl_xml_text = switch_mprintf("cdr=%s",xml_text) )) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
				free(xml_text);
				return SWITCH_STATUS_FALSE;
			}

			if (!switch_strlen_zero(globals.cred)) {
				curl_easy_setopt(curl_handle, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
				curl_easy_setopt(curl_handle, CURLOPT_USERPWD, globals.cred);
			}

			curl_easy_setopt(curl_handle, CURLOPT_POST, 1);
			curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDS, curl_xml_text);
			curl_easy_setopt(curl_handle, CURLOPT_URL, globals.url);
			curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "freeswitch-xml/1.0");

			/* these were used for testing, optionally they may be enabled if someone desires
			curl_easy_setopt(curl_handle, CURLOPT_TIMEOUT, 120); // tcp timeout
			curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1); // 302 recursion level
			*/

			for(curTry=0;curTry<=globals.retries;curTry++) {
				curl_easy_perform(curl_handle);
				curl_easy_getinfo(curl_handle, CURLINFO_RESPONSE_CODE,&httpRes);
				if(httpRes==200) {
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "DEBUG XXX success posting\n");
					curl_easy_cleanup(curl_handle);
					free(curl_xml_text);
					free(xml_text);
					return SWITCH_STATUS_SUCCESS;
				} else {
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Got error [%ld] posting to web server\n",httpRes);
				}

				/* bug?  feature?  we sleep even on the last failure before writing the file */
				switch_sleep(globals.delay * 1000);
			}
			free(curl_xml_text);
			curl_easy_cleanup(curl_handle);
		}

		/* if we are here the web post failed for some reason */
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to post to web server, writing to file\n");

		if ((path = switch_mprintf("%s/%s.cdr.xml", globals.errLogDir, switch_core_session_get_uuid(session)))) {
			if ((fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR)) > -1) {
				write(fd, xml_text, (unsigned) strlen(xml_text));
				close(fd);
				fd = -1;
			} else {
				char ebuf[512] = { 0 };
#ifdef WIN32
				strerror_s(ebuf, sizeof(ebuf), errno);
#else
				strerror_r(errno, ebuf, sizeof(ebuf));
#endif
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error![%s]\n", ebuf);
			}
			free(path);
		}

		free(xml_text);
		switch_xml_free(cdr);
	} else {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Generating Data!\n");
	}

	return SWITCH_STATUS_SUCCESS;
}

static switch_status_t do_config(void)
{
	char *cf = "xml_cdr.conf";
	switch_xml_t cfg, xml, settings, param;

	if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "open of %s failed\n", cf);
		return SWITCH_STATUS_TERM;
	}

	if ((settings = switch_xml_child(cfg, "settings"))) {
		for (param = switch_xml_child(settings, "param"); param; param = param->next) {
			char *var = (char *) switch_xml_attr_soft(param, "name");
			char *val = (char *) switch_xml_attr_soft(param, "value");

			if (!strcasecmp(var, "cred")) {
				globals.cred = val;
			} else if (!strcasecmp(var, "url")) {
				globals.url = val;
			} else if (!strcasecmp(var, "delay")) {
				globals.delay = (uint32_t) atoi(val);
			} else if (!strcasecmp(var, "retries")) {
				globals.retries = (uint32_t) atoi(val);
			} else if (!strcasecmp(var, "logDir")) {
				if (switch_strlen_zero(val)) {
					globals.logDir = SWITCH_GLOBAL_dirs.log_dir;
				} else {
					globals.logDir = val;
				}
			} else if (!strcasecmp(var, "errLogDir")) {
				globals.errLogDir = val;
			}

		}
	}
	if(globals.retries < 0) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "retries is negative, setting to 0\n");
		globals.retries = 0;
	}


	if(globals.retries && globals.delay<=0) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "retries set but delay 0 setting to 5000ms\n");
		globals.delay = 5000;
	}

	if(!switch_strlen_zero(globals.url) && switch_strlen_zero(globals.errLogDir)) {
		if ((globals.errLogDir = switch_mprintf("%s/xml_cdr", SWITCH_GLOBAL_dirs.log_dir))) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
			return SWITCH_STATUS_FALSE;
		}
	}

	return SWITCH_STATUS_SUCCESS;
}