Freeswitch-trunk
Threads by month
- ----- 2026 -----
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
December 2008
- 10 participants
- 371 discussions
11 Dec '08
Author: mikej
Date: Thu Dec 11 15:42:34 2008
New Revision: 10718
Log:
add sip_history_info var for inbound invites.
Modified:
freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia.c
Modified: freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia.c
==============================================================================
--- freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia.c (original)
+++ freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia.c Thu Dec 11 15:42:34 2008
@@ -4197,6 +4197,8 @@
free(tmp_name);
}
}
+ } else if (!strncasecmp(un->un_name, "History-Info", 12)) {
+ switch_channel_set_variable(channel, "sip_history_info", un->un_value);
} else if (!strncasecmp(un->un_name, "X-", 2) || !strncasecmp(un->un_name, "P-", 2)) {
if (!switch_strlen_zero(un->un_value)) {
char new_name[512] = "";
1
0
11 Dec '08
Author: mikej
Date: Thu Dec 11 15:24:31 2008
New Revision: 10717
Log:
SFSIP-92 add support to send a notify in the invite dialog by specifying the uuid of the call.
Modified:
freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c
Modified: freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c
==============================================================================
--- freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c (original)
+++ freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c Thu Dec 11 15:24:31 2008
@@ -2598,10 +2598,26 @@
const char *user = switch_event_get_header(event, "user");
const char *host = switch_event_get_header(event, "host");
const char *call_id = switch_event_get_header(event, "call-id");
+ const char *uuid = switch_event_get_header(event, "uuid");
const char *body = switch_event_get_body(event);
sofia_profile_t *profile;
- if (profile_name && ct && es && user && host && (profile = sofia_glue_find_profile(profile_name))) {
+ if (uuid && ct && es) {
+ switch_core_session_t *session;
+ private_object_t *tech_pvt;
+
+ if ((session = switch_core_session_locate(uuid))) {
+ if ((tech_pvt = switch_core_session_get_private(session))) {
+ nua_notify(tech_pvt->nh,
+ NUTAG_NEWSUB(1),
+ SIPTAG_EVENT_STR(es),
+ SIPTAG_CONTENT_TYPE_STR(ct),
+ TAG_IF(!switch_strlen_zero(body), SIPTAG_PAYLOAD_STR(body)),
+ TAG_END());
+ }
+ switch_core_session_rwunlock(session);
+ }
+ } else if (profile_name && ct && es && user && host && (profile = sofia_glue_find_profile(profile_name))) {
char *sql;
if (call_id) {
1
0
11 Dec '08
Author: anthm
Date: Thu Dec 11 15:20:20 2008
New Revision: 10716
Log:
The Grinch is trying to steal our presence!
Modified:
freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.h
freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia.c
freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_presence.c
freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_reg.c
Modified: freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.h
==============================================================================
--- freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.h (original)
+++ freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.h Thu Dec 11 15:20:20 2008
@@ -432,6 +432,7 @@
int rport_level;
sofia_presence_type_t pres_type;
sofia_media_options_t media_options;
+ uint32_t force_subscription_expires;
};
struct private_object {
Modified: freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia.c
==============================================================================
--- freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia.c (original)
+++ freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia.c Thu Dec 11 15:20:20 2008
@@ -70,12 +70,14 @@
char const *phrase,
nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, tagi_t tags[])
{
+#if 0
if (status >= 300 && sip && sip->sip_call_id) {
char *sql;
sql = switch_mprintf("delete from sip_subscriptions where call_id='%q'", sip->sip_call_id->i_id);
switch_assert(sql != NULL);
sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
}
+#endif
}
void sofia_handle_sip_i_notify(switch_core_session_t *session, int status,
@@ -1257,6 +1259,11 @@
} else {
switch_clear_flag(profile, TFLAG_INB_NOMEDIA);
}
+ } else if (!strcasecmp(var, "force-subscription-expires")) {
+ int tmp = atoi(val);
+ if (tmp > 0) {
+ profile->force_subscription_expires = tmp;
+ }
} else if (!strcasecmp(var, "inbound-late-negotiation")) {
if (switch_true(val)) {
switch_set_flag(profile, TFLAG_LATE_NEGOTIATION);
@@ -1686,6 +1693,11 @@
switch_set_flag(profile, TFLAG_LATE_NEGOTIATION);
} else if (!strcasecmp(var, "inbound-proxy-media") && switch_true(val)) {
switch_set_flag(profile, TFLAG_PROXY_MEDIA);
+ } else if (!strcasecmp(var, "force-subscription-expires")) {
+ int tmp = atoi(val);
+ if (tmp > 0) {
+ profile->force_subscription_expires = tmp;
+ }
} else if (!strcasecmp(var, "inbound-use-callid-as-uuid")) {
if (switch_true(val)) {
profile->pflags |= PFLAG_CALLID_AS_UUID;
Modified: freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_presence.c
==============================================================================
--- freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_presence.c (original)
+++ freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_presence.c Thu Dec 11 15:20:20 2008
@@ -34,6 +34,8 @@
*/
#include "mod_sofia.h"
+#define SUB_OVERLAP 300
+
static int sofia_presence_mwi_callback(void *pArg, int argc, char **argv, char **columnNames);
static int sofia_presence_mwi_callback2(void *pArg, int argc, char **argv, char **columnNames);
static int sofia_presence_sub_reg_callback(void *pArg, int argc, char **argv, char **columnNames);
@@ -519,16 +521,14 @@
}
- switch (event->event_id) {
- case SWITCH_EVENT_PRESENCE_IN:
- sql = switch_mprintf(
+ if ((sql = switch_mprintf(
"select sip_subscriptions.proto,sip_subscriptions.sip_user,sip_subscriptions.sip_host,"
"sip_subscriptions.sub_to_user,sip_subscriptions.sub_to_host,sip_subscriptions.event,"
"sip_subscriptions.contact,sip_subscriptions.call_id,sip_subscriptions.full_from,"
"sip_subscriptions.full_via,sip_subscriptions.expires,sip_subscriptions.user_agent,"
"sip_subscriptions.accept,sip_subscriptions.profile_name"
- ",1,'%q','%q','%q',sip_presence.status,sip_presence.rpid "
+ ",'%q','%q','%q',sip_presence.status,sip_presence.rpid "
"from sip_subscriptions "
"left join sip_presence on "
"(sip_subscriptions.sub_to_user=sip_presence.sip_user and sip_subscriptions.sub_to_host=sip_presence.sip_host and "
@@ -536,41 +536,17 @@
"where (event='%q' or event='%q') and sub_to_user='%q' "
"and (sub_to_host='%q' or presence_hosts like '%%%q%%') "
"and (sip_subscriptions.profile_name = '%q' or sip_subscriptions.presence_hosts != sip_subscriptions.sub_to_host)",
- switch_str_nil(status), switch_str_nil(rpid), host, event_type, alt_event_type, euser, host, host, profile->name);
- break;
- case SWITCH_EVENT_PRESENCE_OUT:
- sql = switch_mprintf(
- "select sip_subscriptions.proto,sip_subscriptions.sip_user,sip_subscriptions.sip_host,"
- "sip_subscriptions.sub_to_user,sip_subscriptions.sub_to_host,sip_subscriptions.event,"
- "sip_subscriptions.contact,sip_subscriptions.call_id,sip_subscriptions.full_from,"
- "sip_subscriptions.full_via,sip_subscriptions.expires,sip_subscriptions.user_agent,"
- "sip_subscriptions.accept,sip_subscriptions.profile_name"
- ",0,'%q','%q','%q',sip_presence.status,sip_presence.rpid "
- "from sip_subscriptions "
- "left join sip_presence on "
- "(sip_subscriptions.sub_to_user=sip_presence.sip_user and sip_subscriptions.sub_to_host=sip_presence.sip_host and "
- "sip_subscriptions.profile_name=sip_presence.profile_name) "
- "where (event='%q' or event='%q') and sub_to_user='%q' "
- "and (sub_to_host='%q' or presence_hosts like '%%%q%%') ",
- "and (sip_subscriptions.profile_name = '%q' or sip_subscriptions.presence_hosts != sip_subscriptions.sub_to_host)",
- switch_str_nil(status), switch_str_nil(rpid), host, event_type, alt_event_type, euser, host, host, profile->name);
- break;
- default:
- break;
- }
+ switch_str_nil(status), switch_str_nil(rpid), host, event_type, alt_event_type, euser, host, host, profile->name))) {
-
- if (sql) {
struct presence_helper helper = { 0 };
helper.profile = profile;
helper.event = event;
SWITCH_STANDARD_STREAM(helper.stream);
switch_assert(helper.stream.data);
-
-
if (mod_sofia_globals.debug_presence > 0) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s START_PRESENCE_SQL\n", profile->name);
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s START_PRESENCE_SQL (%s)\n",
+ event->event_id == SWITCH_EVENT_PRESENCE_IN ? "IN" : "OUT", profile->name);
}
if (mod_sofia_globals.debug_presence > 1) {
@@ -583,8 +559,10 @@
sofia_glue_execute_sql_callback(profile, SWITCH_FALSE,
NULL, sql, sofia_presence_sub_callback, &helper);
+
if (mod_sofia_globals.debug_presence > 0) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s END_PRESENCE_SQL\n\n", profile->name);
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s END_PRESENCE_SQL (%s)\n",
+ event->event_id == SWITCH_EVENT_PRESENCE_IN ? "IN" : "OUT", profile->name);
}
switch_safe_free(sql);
@@ -829,7 +807,7 @@
if (!switch_strlen_zero(to_user)) {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "to-user", to_user);
}
-
+
if (switch_strlen_zero(state)) {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "unique-id", SOFIA_CHAT_PROTO);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "channel-state", "CS_HANGUP");
@@ -945,27 +923,31 @@
char *expires = argv[10];
char *user_agent = argv[11];
char *profile_name = argv[13];
- uint32_t in = atoi(argv[14]);
- char *status = argv[15];
- char *rpid = argv[16];
- char *sub_to_host = argv[17];
+ uint32_t in = 0;
+ char *status = argv[14];
+ char *rpid = argv[15];
+ char *sub_to_host = argv[16];
nua_handle_t *nh;
char *to = NULL;
char *open;
char *prpid;
- int done = 0;
const char *ct = "no/idea";
time_t exptime = switch_timestamp(NULL) + 3600;
int is_dialog = 0;
sofia_profile_t *ext_profile = NULL, *profile = helper->profile;
+ char sstr[128] = "";
+ int kill_handle = 0;
+ char expires_str[10] = "";
-
- if (argc > 19 && !switch_strlen_zero(argv[18]) && !switch_strlen_zero(argv[19])) {
- status = argv[18];
- rpid = argv[19];
+ if (argc > 18 && !switch_strlen_zero(argv[17]) && !switch_strlen_zero(argv[18])) {
+ status = argv[17];
+ rpid = argv[18];
}
+ in = helper->event && helper->event->event_id == SWITCH_EVENT_PRESENCE_IN;
+
+
if (switch_strlen_zero(rpid)) {
rpid = "unknown";
}
@@ -988,29 +970,25 @@
}
}
-
+ if (!(nh = nua_handle_by_call_id(profile->nua, call_id))) {
+ goto end;
+ }
+
if (expires) {
long tmp = atol(expires);
if (tmp > 0) {
- exptime = tmp - switch_timestamp(NULL);
+ exptime = tmp - switch_timestamp(NULL) - SUB_OVERLAP;
+ } else {
+ exptime = tmp;
}
}
-
- if (!(nh = nua_handle_by_call_id(profile->nua, call_id))) {
- goto end;
- }
-
+
if (!rpid) {
rpid = "unknown";
}
prpid = translate_rpid(rpid);
- if (in < 0) {
- done = 1;
- in = 0;
- }
-
if (!strcasecmp(proto, SOFIA_CHAT_PROTO)) {
clean_id = switch_mprintf("sip:%s@%s", sub_to_user, sub_to_host);
} else {
@@ -1020,7 +998,7 @@
if (mod_sofia_globals.debug_presence > 0) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE,
"SEND PRESENCE\nTo: \t%s@%s\nFrom: \t%s@%s\nCall-ID: \t%s\nProfile:\t%s [%s]\n\n",
- sub_to_user, sub_to_host, user, host, call_id, profile_name, helper->profile->name);
+ user, host, sub_to_user, sub_to_host, call_id, profile_name, helper->profile->name);
}
if (!strcasecmp(sub_to_host, host)) {
@@ -1210,7 +1188,7 @@
prpid = translate_rpid(rpid);
pl = gen_pidf(user_agent, clean_id, profile->url, open, rpid, prpid, status_line, &ct);
}
-
+
} else {
if (in) {
open = "open";
@@ -1222,7 +1200,23 @@
}
nua_handle_bind(nh, &mod_sofia_globals.keep_private);
- nua_notify(nh, SIPTAG_SUBSCRIPTION_STATE_STR("active"),
+
+ if (helper->event && helper->event->event_id == SWITCH_EVENT_PRESENCE_OUT) {
+ switch_set_string(sstr, "terminated;reason=noresource");
+ switch_set_string(expires_str, "0");
+ kill_handle = 1;
+ } else if (exptime > 0) {
+ switch_snprintf(sstr, sizeof(sstr), "active;expires=%d", exptime);
+ } else {
+ long delta = exptime * -1;
+ switch_snprintf(sstr, sizeof(sstr), "active;expires=%d", delta);
+ switch_snprintf(expires_str, sizeof(expires_str), "%d", delta);
+ nua_dialog_usage_set_refresh_range(nh->nh_ds->ds_usage, delta, delta);
+ }
+
+ nua_notify(nh,
+ TAG_IF(*expires_str, SIPTAG_EXPIRES_STR(expires_str)),
+ SIPTAG_SUBSCRIPTION_STATE_STR(sstr),
SIPTAG_EVENT_STR(event), SIPTAG_CONTENT_TYPE_STR(ct), SIPTAG_PAYLOAD_STR(pl), TAG_END());
end:
@@ -1236,6 +1230,10 @@
switch_safe_free(pl);
switch_safe_free(to);
+ if (nh && kill_handle) {
+ nua_handle_destroy(nh);
+ }
+
return 0;
}
@@ -1374,7 +1372,8 @@
tagi_t tags[])
{
if (sip) {
- long exp, exp_raw;
+ long exp_abs, exp_delta;
+ char exp_delta_str[30] = "";
sip_to_t const *to = sip->sip_to;
sip_from_t const *from = sip->sip_from;
sip_contact_t const *contact = sip->sip_contact;
@@ -1567,15 +1566,18 @@
call_id = sip->sip_call_id->i_id;
full_from = sip_header_as_string(profile->home, (void *) sip->sip_from);
full_via = sip_header_as_string(profile->home, (void *) sip->sip_via);
-
- exp_raw = (sip->sip_expires ? sip->sip_expires->ex_delta : 3600);
- if (exp_raw) {
- exp = (long) switch_timestamp(NULL) + exp_raw + 120;
+
+ exp_delta = profile->force_subscription_expires ? profile->force_subscription_expires : (sip->sip_expires ? sip->sip_expires->ex_delta : 3600);
+
+ if (exp_delta) {
+ exp_abs = (long) switch_timestamp(NULL) + exp_delta;
} else {
- exp = 0;
+ exp_abs = 0;
sub_state = nua_substate_terminated;
}
+ switch_snprintf(exp_delta_str, sizeof(exp_delta_str), "%ld", exp_delta);
+
if (sofia_test_pflag(profile, PFLAG_MULTIREG)) {
sql = switch_mprintf("delete from sip_subscriptions where call_id='%q'", call_id);
} else {
@@ -1598,18 +1600,38 @@
switch_snprintf(accept + strlen(accept), sizeof(accept) - strlen(accept), "%s%s ", ap->ac_type, ap->ac_next ? "," : "");
ap = ap->ac_next;
}
+
+ /* negative in exptime means keep bumping up sub time to avoid a snafu where every device has it's own rules about subscriptions
+ that somehow barely resemble the RFC not that I blame them because the RFC MAY be amibiguous and SHOULD be deleted.
+ So to avoid the problem we keep resetting the expiration date of the subscription so it never expires.
+
+ Eybeam completely ignores this option and most other subscription-state: directives from rfc3265 and still expires.
+ Polycom is happy to keep upping the subscription expiry back to the original time on each new notify.
+ The rest ... who knows...?
+
+ */
+
sql = switch_mprintf("insert into sip_subscriptions "
"(proto,sip_user,sip_host,sub_to_user,sub_to_host,presence_hosts,event,contact,call_id,full_from,"
"full_via,expires,user_agent,accept,profile_name,hostname) "
"values ('%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q',%ld,'%q','%q','%q','%q')",
proto, from_user, from_host, to_user, to_host, profile->presence_hosts ? profile->presence_hosts : to_host,
- event, contact_str, call_id, full_from, full_via, exp, full_agent, accept, profile->name,mod_sofia_globals.hostname);
+ event, contact_str, call_id, full_from, full_via,
+
+ exp_delta * -1,
+ //exp_abs + SUB_OVERLAP,
+
+ full_agent, accept, profile->name,mod_sofia_globals.hostname);
+ if (mod_sofia_globals.debug_presence > 0) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "%s SUBSCRIBE %s@%s %s@%s\n", profile->name, from_user, from_host, to_user, to_host);
+ }
+
switch_assert(sql != NULL);
sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
- sstr = switch_mprintf("active;expires=%ld", exp_raw);
+ sstr = switch_mprintf("active;expires=%ld", exp_delta);
}
switch_mutex_unlock(profile->ireg_mutex);
@@ -1639,10 +1661,14 @@
contactstr = profile->tls_contact;
}
- nua_dialog_usage_set_refresh_range(nh->nh_ds->ds_usage, exp_raw + 120, exp_raw + 120);
+
+
+ nua_dialog_usage_set_refresh_range(nh->nh_ds->ds_usage, exp_delta + SUB_OVERLAP, exp_delta + SUB_OVERLAP);
+
nua_respond(nh, SIP_202_ACCEPTED, SIPTAG_CONTACT_STR(contact_str), NUTAG_WITH_THIS(nua),
SIPTAG_SUBSCRIPTION_STATE_STR(sstr),
+ SIPTAG_EXPIRES_STR(exp_delta_str),
TAG_IF(sticky, NUTAG_PROXY(sticky)), TAG_END());
switch_safe_free(sticky);
@@ -1653,9 +1679,9 @@
#if 0
nua_notify(nh,
- NUTAG_NEWSUB(1),
SIPTAG_SUBSCRIPTION_STATE_STR(sstr), SIPTAG_EVENT_STR(event),
- SIPTAG_CONTENT_TYPE_STR("application/simple-message-summary"),
+ SIPTAG_EXPIRES_STR(exp_delta_str),
+ SIPTAG_CONTENT_TYPE_STR("application/notice"),
SIPTAG_PAYLOAD_STR("Note: Come to ClueCon http://www.cluecon.com\n\n"), TAG_END());
#endif
@@ -1780,7 +1806,7 @@
uint8_t in = 0;
char *sql;
char *full_agent = NULL;
- long exp, exp_raw;
+ long exp, exp_delta;
if ((xml = switch_xml_parse_str(payload->pl_data, strlen(payload->pl_data)))) {
char *status_txt = "", *note_txt = "";
@@ -1817,8 +1843,8 @@
}
}
- exp_raw = (sip->sip_expires ? sip->sip_expires->ex_delta : 3600);
- exp = (long) switch_timestamp(NULL) + exp_raw;
+ exp_delta = (sip->sip_expires ? sip->sip_expires->ex_delta : 3600);
+ exp = (long) switch_timestamp(NULL) + exp_delta;
if ((sql =
switch_mprintf("delete from sip_presence where sip_user='%q' and sip_host='%q' "
Modified: freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_reg.c
==============================================================================
--- freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_reg.c (original)
+++ freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_reg.c Thu Dec 11 15:20:20 2008
@@ -995,7 +995,34 @@
switch_event_fire(&event);
}
#endif
+
+
} else {
+
+ if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_OUT) == SWITCH_STATUS_SUCCESS) {
+ switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", SOFIA_CHAT_PROTO);
+ switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "rpid", rpid);
+ switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "login", profile->url);
+ switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "user-agent",
+ (sip && sip->sip_user_agent) ? sip->sip_user_agent->g_string : "unknown");
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s@%s", to_user, reg_host);
+ switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "status", "UNRegistered");
+ switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "event_type", "presence");
+ switch_event_fire(&event);
+ }
+#if 0
+ if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_OUT) == SWITCH_STATUS_SUCCESS) {
+ switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", "sip");
+ switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "login", profile->url);
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s+%s@%s", SOFIA_CHAT_PROTO, to_user, reg_host);
+
+ switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "status", "unavailable");
+ switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "rpid", rpid);
+ switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "event_type", "presence");
+ switch_event_fire(&event);
+ }
+#endif
+
if (multi_reg) {
char *icontact, *p;
icontact = sofia_glue_get_url_from_contact(contact_str, 1);
@@ -1032,16 +1059,6 @@
sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
}
}
- if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_OUT) == SWITCH_STATUS_SUCCESS) {
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", "sip");
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "login", profile->url);
- switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s+%s@%s", SOFIA_CHAT_PROTO, to_user, reg_host);
-
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "status", "unavailable");
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "rpid", rpid);
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "event_type", "presence");
- switch_event_fire(&event);
- }
}
1
0
[commit] r10715 - in freeswitch/trunk: conf/autoload_configs src/mod/endpoints/mod_sofia
by FreeSWITCH SVN 11 Dec '08
by FreeSWITCH SVN 11 Dec '08
11 Dec '08
Author: brian
Date: Thu Dec 11 15:16:32 2008
New Revision: 10715
Log:
option to turn of auto_restart of sofia profiles on ip change
Modified:
freeswitch/trunk/conf/autoload_configs/sofia.conf.xml
freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c
freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.h
freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia.c
Modified: freeswitch/trunk/conf/autoload_configs/sofia.conf.xml
==============================================================================
--- freeswitch/trunk/conf/autoload_configs/sofia.conf.xml (original)
+++ freeswitch/trunk/conf/autoload_configs/sofia.conf.xml Thu Dec 11 15:16:32 2008
@@ -2,6 +2,8 @@
<global_settings>
<param name="log-level" value="0"/>
+ <!-- <param name="auto-restart" value="false"/> -->
+ <param name="debug-presence" value="0"/>
</global_settings>
<!--
Modified: freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c
==============================================================================
--- freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c (original)
+++ freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c Thu Dec 11 15:16:32 2008
@@ -2686,7 +2686,7 @@
{
const char *cond = switch_event_get_header(event, "condition");
- if (cond && !strcmp(cond, "network-address-change")) {
+ if (cond && !strcmp(cond, "network-address-change") && mod_sofia_globals.auto_restart) {
sofia_glue_restart_all_profiles();
}
Modified: freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.h
==============================================================================
--- freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.h (original)
+++ freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.h Thu Dec 11 15:16:32 2008
@@ -243,6 +243,7 @@
switch_event_node_t *custom_node;
switch_event_node_t *mwi_node;
int debug_presence;
+ int auto_restart;
};
extern struct mod_sofia_globals mod_sofia_globals;
Modified: freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia.c
==============================================================================
--- freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia.c (original)
+++ freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia.c Thu Dec 11 15:16:32 2008
@@ -1571,6 +1571,8 @@
goto done;
}
+ mod_sofia_globals.auto_restart = SWITCH_TRUE;
+
if ((settings = switch_xml_child(cfg, "global_settings"))) {
for (param = switch_xml_child(settings, "param"); param; param = param->next) {
char *var = (char *) switch_xml_attr_soft(param, "name");
@@ -1579,6 +1581,8 @@
su_log_set_level(NULL, atoi(val));
} else if (!strcasecmp(var, "debug-presence")) {
mod_sofia_globals.debug_presence = atoi(val);
+ } else if (!strcasecmp(var, "auto-restart")) {
+ mod_sofia_globals.auto_restart = switch_true(val);
}
}
}
1
0
11 Dec '08
Author: mikej
Date: Thu Dec 11 12:56:51 2008
New Revision: 10714
Log:
mod_commands only send content-type on status when it really is http.
Modified:
freeswitch/trunk/src/mod/applications/mod_commands/mod_commands.c
Modified: freeswitch/trunk/src/mod/applications/mod_commands/mod_commands.c
==============================================================================
--- freeswitch/trunk/src/mod/applications/mod_commands/mod_commands.c (original)
+++ freeswitch/trunk/src/mod/applications/mod_commands/mod_commands.c Thu Dec 11 12:56:51 2008
@@ -704,13 +704,14 @@
if (stream->param_event) {
http = switch_event_get_header(stream->param_event, "http-host");
+ if ((var = switch_event_get_header(stream->param_event, "content-type"))) {
+ if (!strcasecmp(var, "text/plain")) {
+ http = NULL;
+ }
+ }
}
- if ((var = switch_event_get_header(stream->param_event, "content-type"))) {
- if (!strcasecmp(var, "text/plain")) {
- http = NULL;
- }
- } else {
+ if (http) {
stream->write_function(stream, "%s", "Content-Type: text/html\n\n");
}
1
0
Author: brian
Date: Thu Dec 11 10:51:15 2008
New Revision: 10712
Log:
tweak this
Modified:
freeswitch/trunk/conf/autoload_configs/local_stream.conf.xml
Modified: freeswitch/trunk/conf/autoload_configs/local_stream.conf.xml
==============================================================================
--- freeswitch/trunk/conf/autoload_configs/local_stream.conf.xml (original)
+++ freeswitch/trunk/conf/autoload_configs/local_stream.conf.xml Thu Dec 11 10:51:15 2008
@@ -14,7 +14,7 @@
<param name="interval" value="20"/>
<param name="timer-name" value="soft"/>
</directory>
- <!--
+
<directory name="moh/32000" path="$${base_dir}/sounds/music/32000">
<param name="rate" value="32000"/>
<param name="shuffle" value="true"/>
@@ -22,5 +22,5 @@
<param name="interval" value="20"/>
<param name="timer-name" value="soft"/>
</directory>
- -->
+
</configuration>
1
0
[commit] r10711 - freeswitch/trunk/src/mod/event_handlers/mod_event_socket
by FreeSWITCH SVN 11 Dec '08
by FreeSWITCH SVN 11 Dec '08
11 Dec '08
Author: mikej
Date: Thu Dec 11 10:25:59 2008
New Revision: 10711
Log:
MODEVENT-33 missing : after Content-Length in event socket
Modified:
freeswitch/trunk/src/mod/event_handlers/mod_event_socket/mod_event_socket.c
Modified: freeswitch/trunk/src/mod/event_handlers/mod_event_socket/mod_event_socket.c
==============================================================================
--- freeswitch/trunk/src/mod/event_handlers/mod_event_socket/mod_event_socket.c (original)
+++ freeswitch/trunk/src/mod/event_handlers/mod_event_socket/mod_event_socket.c Thu Dec 11 10:25:59 2008
@@ -1649,7 +1649,7 @@
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "IP %s Rejected by acl \"%s\"\n", listener->remote_ip, prefs.acl[x]);
- switch_snprintf(buf, sizeof(buf), "Content-Type: text/rude-rejection\nContent-Length %d\n\n", mlen);
+ switch_snprintf(buf, sizeof(buf), "Content-Type: text/rude-rejection\nContent-Length: %d\n\n", mlen);
len = strlen(buf);
switch_socket_send(listener->sock, buf, &len);
len = mlen;
@@ -1799,7 +1799,7 @@
const char message[] = "Disconnected, goodbye!\nSee you at ClueCon http://www.cluecon.com!\n";
int mlen = strlen(message);
- switch_snprintf(disco_buf, sizeof(disco_buf), "Content-Type: text/disconnect-notice\nContent-Length %d\n\n", mlen);
+ switch_snprintf(disco_buf, sizeof(disco_buf), "Content-Type: text/disconnect-notice\nContent-Length: %d\n\n", mlen);
len = strlen(disco_buf);
switch_socket_send(listener->sock, disco_buf, &len);
len = mlen;
1
0
[commit] r10710 - in freeswitch/trunk/src: . include mod/languages/mod_managed mod/languages/mod_managed/managed
by FreeSWITCH SVN 11 Dec '08
by FreeSWITCH SVN 11 Dec '08
11 Dec '08
Author: mikej
Date: Thu Dec 11 10:20:24 2008
New Revision: 10710
Log:
FSCORE-237 make channel flags array based so we do not have 32 flag limit
Modified:
freeswitch/trunk/src/include/switch_channel.h
freeswitch/trunk/src/include/switch_types.h
freeswitch/trunk/src/mod/languages/mod_managed/freeswitch_wrap.cxx
freeswitch/trunk/src/mod/languages/mod_managed/managed/swig.cs
freeswitch/trunk/src/switch_channel.c
Modified: freeswitch/trunk/src/include/switch_channel.h
==============================================================================
--- freeswitch/trunk/src/include/switch_channel.h (original)
+++ freeswitch/trunk/src/include/switch_channel.h Thu Dec 11 10:20:24 2008
@@ -145,7 +145,7 @@
\param flags the initial channel flags
*/
SWITCH_DECLARE(switch_status_t) switch_channel_init(switch_channel_t *channel, switch_core_session_t *session, switch_channel_state_t state,
- uint32_t flags);
+ switch_channel_flag_t flag);
/*!
\brief Fire A presence event for the channel
@@ -259,49 +259,49 @@
SWITCH_DECLARE(switch_caller_extension_t *) switch_channel_get_caller_extension(switch_channel_t *channel);
/*!
- \brief Test for presence of given flag(s) on a given channel
+ \brief Test for presence of given flag on a given channel
\param channel channel to test
- \param flags or'd list of channel flags to test
+ \param flag to test
\return TRUE if flags were present
*/
-SWITCH_DECLARE(uint32_t) switch_channel_test_flag(switch_channel_t *channel, switch_channel_flag_t flags);
+SWITCH_DECLARE(uint32_t) switch_channel_test_flag(switch_channel_t *channel, switch_channel_flag_t flag);
/*!
\brief Set given flag(s) on a given channel
- \param channel channel on which to set flag(s)
- \param flags or'd list of flags to set
+ \param channel channel on which to set flag
+ \param flag or'd list of flags to set
*/
-SWITCH_DECLARE(void) switch_channel_set_flag(switch_channel_t *channel, switch_channel_flag_t flags);
+SWITCH_DECLARE(void) switch_channel_set_flag(switch_channel_t *channel, switch_channel_flag_t flag);
/*!
\brief Set given flag(s) on a given channel's bridge partner
- \param channel channel to derive the partner channel to set flag(s) on
- \param flags or'd list of flags to set
+ \param channel channel to derive the partner channel to set flag on
+ \param flag to set
\return true if the flag was set
*/
-SWITCH_DECLARE(switch_bool_t) switch_channel_set_flag_partner(switch_channel_t *channel, switch_channel_flag_t flags);
+SWITCH_DECLARE(switch_bool_t) switch_channel_set_flag_partner(switch_channel_t *channel, switch_channel_flag_t flag);
/*!
\brief Clears given flag(s) on a given channel's bridge partner
\param channel channel to derive the partner channel to clear flag(s) from
- \param flags the flags to clear
+ \param flag the flag to clear
\return true if the flag was cleared
*/
-SWITCH_DECLARE(switch_bool_t) switch_channel_clear_flag_partner(switch_channel_t *channel, switch_channel_flag_t flags);
+SWITCH_DECLARE(switch_bool_t) switch_channel_clear_flag_partner(switch_channel_t *channel, switch_channel_flag_t flag);
/*!
\brief Set given flag(s) on a given channel to be applied on the next state change
\param channel channel on which to set flag(s)
- \param flags or'd list of flags to set
+ \param flag flag to set
*/
-SWITCH_DECLARE(void) switch_channel_set_state_flag(switch_channel_t *channel, switch_channel_flag_t flags);
+SWITCH_DECLARE(void) switch_channel_set_state_flag(switch_channel_t *channel, switch_channel_flag_t flag);
/*!
\brief Clear given flag(s) from a channel
\param channel channel to clear flags from
- \param flags or'd list of flags to clear
+ \param flag flag to clear
*/
-SWITCH_DECLARE(void) switch_channel_clear_flag(switch_channel_t *channel, switch_channel_flag_t flags);
+SWITCH_DECLARE(void) switch_channel_clear_flag(switch_channel_t *channel, switch_channel_flag_t flag);
SWITCH_DECLARE(switch_status_t) switch_channel_perform_answer(switch_channel_t *channel, const char *file, const char *func, int line);
@@ -484,7 +484,7 @@
_In_opt_ const char *prefix);
SWITCH_DECLARE(switch_status_t) switch_channel_set_timestamps(_In_ switch_channel_t *channel);
-#define switch_channel_stop_broadcast(_channel) if (switch_channel_test_flag(_channel, CF_BROADCAST)) switch_channel_set_flag(_channel, CF_BREAK | CF_STOP_BROADCAST)
+#define switch_channel_stop_broadcast(_channel) for(;;) {if (switch_channel_test_flag(_channel, CF_BROADCAST)) {switch_channel_set_flag(_channel, CF_STOP_BROADCAST); switch_channel_set_flag(_channel, CF_BREAK); } break;}
#define switch_channel_media_ready(_channel) ((switch_channel_test_flag(_channel, CF_ANSWERED) || switch_channel_test_flag(_channel, CF_EARLY_MEDIA)) && !switch_channel_test_flag(_channel, CF_PROXY_MODE))
Modified: freeswitch/trunk/src/include/switch_types.h
==============================================================================
--- freeswitch/trunk/src/include/switch_types.h (original)
+++ freeswitch/trunk/src/include/switch_types.h Thu Dec 11 10:20:24 2008
@@ -732,73 +732,70 @@
\brief Channel Flags
<pre>
-CF_ANSWERED = (1 << 0) - Channel is answered
-CF_OUTBOUND = (1 << 1) - Channel is an outbound channel
-CF_EARLY_MEDIA = (1 << 2) - Channel is ready for audio before answer
-CF_ORIGINATOR = (1 << 3) - Channel is an originator
-CF_TRANSFER = (1 << 4) - Channel is being transfered
-CF_ACCEPT_CNG = (1 << 5) - Channel will accept CNG frames
-CF_REDIRECT = (1 << 6) - Channel is being redirected
-CF_BRIDGED = (1 << 7) - Channel in a bridge
-CF_HOLD = (1 << 8) - Channel is on hold
-CF_SERVICE = (1 << 9) - Channel has a service thread
-CF_TAGGED = (1 << 10) - Channel is tagged
-CF_WINNER = (1 << 11) - Channel is the winner
-CF_CONTROLLED = (1 << 12) - Channel is under control
-CF_PROXY_MODE = (1 << 13) - Channel has no media
-CF_SUSPEND = (1 << 14) - Suspend i/o
-CF_EVENT_PARSE = (1 << 15) - Suspend control events
-CF_USE_ME = (1 << 16) - use me
-CF_GEN_RINGBACK = (1 << 17) - Channel is generating it's own ringback
-CF_RING_READY = (1 << 18) - Channel is ready to send ringback
-CF_BREAK = (1 << 19) - Channel should stop what it's doing
-CF_BROADCAST = (1 << 20) - Channel is broadcasting
-CF_UNICAST = (1 << 21) - Channel has a unicast connection
-CF_VIDEO = (1 << 22) - Channel has video
-CF_EVENT_LOCK = (1 << 23) - Don't parse events
-CF_RESET = (1 << 24) - Tell extension parser to reset
-CF_ORIGINATING = (1 << 25) - Channel is originating
-CF_STOP_BROADCAST = (1 << 26) - Signal to stop broadcast
+CF_ANSWERED - Channel is answered
+CF_OUTBOUND - Channel is an outbound channel
+CF_EARLY_MEDIA - Channel is ready for audio before answer
+CF_ORIGINATOR - Channel is an originator
+CF_TRANSFER - Channel is being transfered
+CF_ACCEPT_CNG - Channel will accept CNG frames
+CF_REDIRECT - Channel is being redirected
+CF_BRIDGED - Channel in a bridge
+CF_HOLD - Channel is on hold
+CF_SERVICE - Channel has a service thread
+CF_TAGGED - Channel is tagged
+CF_WINNER - Channel is the winner
+CF_CONTROLLED - Channel is under control
+CF_PROXY_MODE - Channel has no media
+CF_SUSPEND - Suspend i/o
+CF_EVENT_PARSE - Suspend control events
+CF_GEN_RINGBACK - Channel is generating it's own ringback
+CF_RING_READY - Channel is ready to send ringback
+CF_BREAK - Channel should stop what it's doing
+CF_BROADCAST - Channel is broadcasting
+CF_UNICAST - Channel has a unicast connection
+CF_VIDEO - Channel has video
+CF_EVENT_LOCK - Don't parse events
+CF_RESET - Tell extension parser to reset
+CF_ORIGINATING - Channel is originating
+CF_STOP_BROADCAST - Signal to stop broadcast
</pre>
*/
typedef enum {
- CF_ANSWERED = (1 << 0),
- CF_OUTBOUND = (1 << 1),
- CF_EARLY_MEDIA = (1 << 2),
- CF_ORIGINATOR = (1 << 3),
- CF_TRANSFER = (1 << 4),
- CF_ACCEPT_CNG = (1 << 5),
- CF_REDIRECT = (1 << 6),
- CF_BRIDGED = (1 << 7),
- CF_HOLD = (1 << 8),
- CF_SERVICE = (1 << 9),
- CF_TAGGED = (1 << 10),
- CF_WINNER = (1 << 11),
- CF_CONTROLLED = (1 << 12),
- CF_PROXY_MODE = (1 << 13),
- CF_SUSPEND = (1 << 14),
- CF_EVENT_PARSE = (1 << 15),
- CF_USE_ME = (1 << 16),
- CF_GEN_RINGBACK = (1 << 17),
- CF_RING_READY = (1 << 18),
- CF_BREAK = (1 << 19),
- CF_BROADCAST = (1 << 20),
- CF_UNICAST = (1 << 21),
- CF_VIDEO = (1 << 22),
- CF_EVENT_LOCK = (1 << 23),
- CF_RESET = (1 << 24),
- CF_ORIGINATING = (1 << 25),
- CF_STOP_BROADCAST = (1 << 26),
- CF_PROXY_MEDIA = (1 << 27),
- CF_INNER_BRIDGE = (1 << 28),
- CF_REQ_MEDIA = (1 << 29),
- CF_VERBOSE_EVENTS = (1 << 30)
-} switch_channel_flag_enum_t;
-
-typedef uint32_t switch_channel_flag_t;
-
-
+ CF_ANSWERED = 1,
+ CF_OUTBOUND,
+ CF_EARLY_MEDIA,
+ CF_ORIGINATOR,
+ CF_TRANSFER,
+ CF_ACCEPT_CNG,
+ CF_REDIRECT,
+ CF_BRIDGED,
+ CF_HOLD,
+ CF_SERVICE,
+ CF_TAGGED,
+ CF_WINNER,
+ CF_CONTROLLED,
+ CF_PROXY_MODE,
+ CF_SUSPEND,
+ CF_EVENT_PARSE,
+ CF_GEN_RINGBACK,
+ CF_RING_READY,
+ CF_BREAK,
+ CF_BROADCAST,
+ CF_UNICAST,
+ CF_VIDEO,
+ CF_EVENT_LOCK,
+ CF_RESET,
+ CF_ORIGINATING,
+ CF_STOP_BROADCAST,
+ CF_PROXY_MEDIA,
+ CF_INNER_BRIDGE,
+ CF_REQ_MEDIA,
+ CF_VERBOSE_EVENTS,
+
+ /* WARNING: DO NOT ADD ANY FLAGS BELOW THIS LINE */
+ CF_FLAG_MAX
+} switch_channel_flag_t;
/*!
\enum switch_frame_flag_t
Modified: freeswitch/trunk/src/mod/languages/mod_managed/freeswitch_wrap.cxx
==============================================================================
--- freeswitch/trunk/src/mod/languages/mod_managed/freeswitch_wrap.cxx (original)
+++ freeswitch/trunk/src/mod/languages/mod_managed/freeswitch_wrap.cxx Thu Dec 11 10:20:24 2008
@@ -17084,7 +17084,7 @@
}
-SWIGEXPORT int SWIGSTDCALL CSharp_switch_channel_wait_for_flag(void * jarg1, unsigned long jarg2, int jarg3, unsigned long jarg4, void * jarg5) {
+SWIGEXPORT int SWIGSTDCALL CSharp_switch_channel_wait_for_flag(void * jarg1, int jarg2, int jarg3, unsigned long jarg4, void * jarg5) {
int jresult ;
switch_channel_t *arg1 = (switch_channel_t *) 0 ;
switch_channel_flag_t arg2 ;
@@ -17230,18 +17230,18 @@
}
-SWIGEXPORT int SWIGSTDCALL CSharp_switch_channel_init(void * jarg1, void * jarg2, int jarg3, unsigned long jarg4) {
+SWIGEXPORT int SWIGSTDCALL CSharp_switch_channel_init(void * jarg1, void * jarg2, int jarg3, int jarg4) {
int jresult ;
switch_channel_t *arg1 = (switch_channel_t *) 0 ;
switch_core_session_t *arg2 = (switch_core_session_t *) 0 ;
switch_channel_state_t arg3 ;
- uint32_t arg4 ;
+ switch_channel_flag_t arg4 ;
switch_status_t result;
arg1 = (switch_channel_t *)jarg1;
arg2 = (switch_core_session_t *)jarg2;
arg3 = (switch_channel_state_t)jarg3;
- arg4 = (uint32_t)jarg4;
+ arg4 = (switch_channel_flag_t)jarg4;
result = (switch_status_t)switch_channel_init(arg1,arg2,arg3,arg4);
jresult = result;
return jresult;
@@ -17481,7 +17481,7 @@
}
-SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_channel_test_flag(void * jarg1, unsigned long jarg2) {
+SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_channel_test_flag(void * jarg1, int jarg2) {
unsigned long jresult ;
switch_channel_t *arg1 = (switch_channel_t *) 0 ;
switch_channel_flag_t arg2 ;
@@ -17495,7 +17495,7 @@
}
-SWIGEXPORT void SWIGSTDCALL CSharp_switch_channel_set_flag(void * jarg1, unsigned long jarg2) {
+SWIGEXPORT void SWIGSTDCALL CSharp_switch_channel_set_flag(void * jarg1, int jarg2) {
switch_channel_t *arg1 = (switch_channel_t *) 0 ;
switch_channel_flag_t arg2 ;
@@ -17505,7 +17505,7 @@
}
-SWIGEXPORT int SWIGSTDCALL CSharp_switch_channel_set_flag_partner(void * jarg1, unsigned long jarg2) {
+SWIGEXPORT int SWIGSTDCALL CSharp_switch_channel_set_flag_partner(void * jarg1, int jarg2) {
int jresult ;
switch_channel_t *arg1 = (switch_channel_t *) 0 ;
switch_channel_flag_t arg2 ;
@@ -17519,7 +17519,7 @@
}
-SWIGEXPORT int SWIGSTDCALL CSharp_switch_channel_clear_flag_partner(void * jarg1, unsigned long jarg2) {
+SWIGEXPORT int SWIGSTDCALL CSharp_switch_channel_clear_flag_partner(void * jarg1, int jarg2) {
int jresult ;
switch_channel_t *arg1 = (switch_channel_t *) 0 ;
switch_channel_flag_t arg2 ;
@@ -17533,7 +17533,7 @@
}
-SWIGEXPORT void SWIGSTDCALL CSharp_switch_channel_set_state_flag(void * jarg1, unsigned long jarg2) {
+SWIGEXPORT void SWIGSTDCALL CSharp_switch_channel_set_state_flag(void * jarg1, int jarg2) {
switch_channel_t *arg1 = (switch_channel_t *) 0 ;
switch_channel_flag_t arg2 ;
@@ -17543,7 +17543,7 @@
}
-SWIGEXPORT void SWIGSTDCALL CSharp_switch_channel_clear_flag(void * jarg1, unsigned long jarg2) {
+SWIGEXPORT void SWIGSTDCALL CSharp_switch_channel_clear_flag(void * jarg1, int jarg2) {
switch_channel_t *arg1 = (switch_channel_t *) 0 ;
switch_channel_flag_t arg2 ;
Modified: freeswitch/trunk/src/mod/languages/mod_managed/managed/swig.cs
==============================================================================
--- freeswitch/trunk/src/mod/languages/mod_managed/managed/swig.cs (original)
+++ freeswitch/trunk/src/mod/languages/mod_managed/managed/swig.cs Thu Dec 11 10:20:24 2008
@@ -2209,8 +2209,8 @@
freeswitchPINVOKE.switch_channel_wait_for_state(SWIGTYPE_p_switch_channel.getCPtr(channel), SWIGTYPE_p_switch_channel.getCPtr(other_channel), (int)want_state);
}
- public static switch_status_t switch_channel_wait_for_flag(SWIGTYPE_p_switch_channel channel, uint want_flag, switch_bool_t pres, uint to, SWIGTYPE_p_switch_channel super_channel) {
- switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_channel_wait_for_flag(SWIGTYPE_p_switch_channel.getCPtr(channel), want_flag, (int)pres, to, SWIGTYPE_p_switch_channel.getCPtr(super_channel));
+ public static switch_status_t switch_channel_wait_for_flag(SWIGTYPE_p_switch_channel channel, switch_channel_flag_t want_flag, switch_bool_t pres, uint to, SWIGTYPE_p_switch_channel super_channel) {
+ switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_channel_wait_for_flag(SWIGTYPE_p_switch_channel.getCPtr(channel), (int)want_flag, (int)pres, to, SWIGTYPE_p_switch_channel.getCPtr(super_channel));
return ret;
}
@@ -2260,8 +2260,8 @@
return ret;
}
- public static switch_status_t switch_channel_init(SWIGTYPE_p_switch_channel channel, SWIGTYPE_p_switch_core_session session, switch_channel_state_t state, uint flags) {
- switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_channel_init(SWIGTYPE_p_switch_channel.getCPtr(channel), SWIGTYPE_p_switch_core_session.getCPtr(session), (int)state, flags);
+ public static switch_status_t switch_channel_init(SWIGTYPE_p_switch_channel channel, SWIGTYPE_p_switch_core_session session, switch_channel_state_t state, switch_channel_flag_t flag) {
+ switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_channel_init(SWIGTYPE_p_switch_channel.getCPtr(channel), SWIGTYPE_p_switch_core_session.getCPtr(session), (int)state, (int)flag);
return ret;
}
@@ -2358,31 +2358,31 @@
return ret;
}
- public static uint switch_channel_test_flag(SWIGTYPE_p_switch_channel channel, uint flags) {
- uint ret = freeswitchPINVOKE.switch_channel_test_flag(SWIGTYPE_p_switch_channel.getCPtr(channel), flags);
+ public static uint switch_channel_test_flag(SWIGTYPE_p_switch_channel channel, switch_channel_flag_t flag) {
+ uint ret = freeswitchPINVOKE.switch_channel_test_flag(SWIGTYPE_p_switch_channel.getCPtr(channel), (int)flag);
return ret;
}
- public static void switch_channel_set_flag(SWIGTYPE_p_switch_channel channel, uint flags) {
- freeswitchPINVOKE.switch_channel_set_flag(SWIGTYPE_p_switch_channel.getCPtr(channel), flags);
+ public static void switch_channel_set_flag(SWIGTYPE_p_switch_channel channel, switch_channel_flag_t flag) {
+ freeswitchPINVOKE.switch_channel_set_flag(SWIGTYPE_p_switch_channel.getCPtr(channel), (int)flag);
}
- public static switch_bool_t switch_channel_set_flag_partner(SWIGTYPE_p_switch_channel channel, uint flags) {
- switch_bool_t ret = (switch_bool_t)freeswitchPINVOKE.switch_channel_set_flag_partner(SWIGTYPE_p_switch_channel.getCPtr(channel), flags);
+ public static switch_bool_t switch_channel_set_flag_partner(SWIGTYPE_p_switch_channel channel, switch_channel_flag_t flag) {
+ switch_bool_t ret = (switch_bool_t)freeswitchPINVOKE.switch_channel_set_flag_partner(SWIGTYPE_p_switch_channel.getCPtr(channel), (int)flag);
return ret;
}
- public static switch_bool_t switch_channel_clear_flag_partner(SWIGTYPE_p_switch_channel channel, uint flags) {
- switch_bool_t ret = (switch_bool_t)freeswitchPINVOKE.switch_channel_clear_flag_partner(SWIGTYPE_p_switch_channel.getCPtr(channel), flags);
+ public static switch_bool_t switch_channel_clear_flag_partner(SWIGTYPE_p_switch_channel channel, switch_channel_flag_t flag) {
+ switch_bool_t ret = (switch_bool_t)freeswitchPINVOKE.switch_channel_clear_flag_partner(SWIGTYPE_p_switch_channel.getCPtr(channel), (int)flag);
return ret;
}
- public static void switch_channel_set_state_flag(SWIGTYPE_p_switch_channel channel, uint flags) {
- freeswitchPINVOKE.switch_channel_set_state_flag(SWIGTYPE_p_switch_channel.getCPtr(channel), flags);
+ public static void switch_channel_set_state_flag(SWIGTYPE_p_switch_channel channel, switch_channel_flag_t flag) {
+ freeswitchPINVOKE.switch_channel_set_state_flag(SWIGTYPE_p_switch_channel.getCPtr(channel), (int)flag);
}
- public static void switch_channel_clear_flag(SWIGTYPE_p_switch_channel channel, uint flags) {
- freeswitchPINVOKE.switch_channel_clear_flag(SWIGTYPE_p_switch_channel.getCPtr(channel), flags);
+ public static void switch_channel_clear_flag(SWIGTYPE_p_switch_channel channel, switch_channel_flag_t flag) {
+ freeswitchPINVOKE.switch_channel_clear_flag(SWIGTYPE_p_switch_channel.getCPtr(channel), (int)flag);
}
public static switch_status_t switch_channel_perform_answer(SWIGTYPE_p_switch_channel channel, string file, string func, int line) {
@@ -8343,7 +8343,7 @@
public static extern void switch_channel_wait_for_state(HandleRef jarg1, HandleRef jarg2, int jarg3);
[DllImport("mod_managed", EntryPoint="CSharp_switch_channel_wait_for_flag")]
- public static extern int switch_channel_wait_for_flag(HandleRef jarg1, uint jarg2, int jarg3, uint jarg4, HandleRef jarg5);
+ public static extern int switch_channel_wait_for_flag(HandleRef jarg1, int jarg2, int jarg3, uint jarg4, HandleRef jarg5);
[DllImport("mod_managed", EntryPoint="CSharp_switch_channel_perform_set_state")]
public static extern int switch_channel_perform_set_state(HandleRef jarg1, string jarg2, string jarg3, int jarg4, int jarg5);
@@ -8373,7 +8373,7 @@
public static extern int switch_channel_alloc(HandleRef jarg1, HandleRef jarg2);
[DllImport("mod_managed", EntryPoint="CSharp_switch_channel_init")]
- public static extern int switch_channel_init(HandleRef jarg1, HandleRef jarg2, int jarg3, uint jarg4);
+ public static extern int switch_channel_init(HandleRef jarg1, HandleRef jarg2, int jarg3, int jarg4);
[DllImport("mod_managed", EntryPoint="CSharp_switch_channel_presence")]
public static extern void switch_channel_presence(HandleRef jarg1, string jarg2, string jarg3, string jarg4);
@@ -8433,22 +8433,22 @@
public static extern IntPtr switch_channel_get_caller_extension(HandleRef jarg1);
[DllImport("mod_managed", EntryPoint="CSharp_switch_channel_test_flag")]
- public static extern uint switch_channel_test_flag(HandleRef jarg1, uint jarg2);
+ public static extern uint switch_channel_test_flag(HandleRef jarg1, int jarg2);
[DllImport("mod_managed", EntryPoint="CSharp_switch_channel_set_flag")]
- public static extern void switch_channel_set_flag(HandleRef jarg1, uint jarg2);
+ public static extern void switch_channel_set_flag(HandleRef jarg1, int jarg2);
[DllImport("mod_managed", EntryPoint="CSharp_switch_channel_set_flag_partner")]
- public static extern int switch_channel_set_flag_partner(HandleRef jarg1, uint jarg2);
+ public static extern int switch_channel_set_flag_partner(HandleRef jarg1, int jarg2);
[DllImport("mod_managed", EntryPoint="CSharp_switch_channel_clear_flag_partner")]
- public static extern int switch_channel_clear_flag_partner(HandleRef jarg1, uint jarg2);
+ public static extern int switch_channel_clear_flag_partner(HandleRef jarg1, int jarg2);
[DllImport("mod_managed", EntryPoint="CSharp_switch_channel_set_state_flag")]
- public static extern void switch_channel_set_state_flag(HandleRef jarg1, uint jarg2);
+ public static extern void switch_channel_set_state_flag(HandleRef jarg1, int jarg2);
[DllImport("mod_managed", EntryPoint="CSharp_switch_channel_clear_flag")]
- public static extern void switch_channel_clear_flag(HandleRef jarg1, uint jarg2);
+ public static extern void switch_channel_clear_flag(HandleRef jarg1, int jarg2);
[DllImport("mod_managed", EntryPoint="CSharp_switch_channel_perform_answer")]
public static extern int switch_channel_perform_answer(HandleRef jarg1, string jarg2, string jarg3, int jarg4);
@@ -16832,38 +16832,38 @@
namespace FreeSWITCH.Native {
-[System.Flags] public enum switch_channel_flag_enum_t {
- CF_ANSWERED = (1 << 0),
- CF_OUTBOUND = (1 << 1),
- CF_EARLY_MEDIA = (1 << 2),
- CF_ORIGINATOR = (1 << 3),
- CF_TRANSFER = (1 << 4),
- CF_ACCEPT_CNG = (1 << 5),
- CF_REDIRECT = (1 << 6),
- CF_BRIDGED = (1 << 7),
- CF_HOLD = (1 << 8),
- CF_SERVICE = (1 << 9),
- CF_TAGGED = (1 << 10),
- CF_WINNER = (1 << 11),
- CF_CONTROLLED = (1 << 12),
- CF_PROXY_MODE = (1 << 13),
- CF_SUSPEND = (1 << 14),
- CF_EVENT_PARSE = (1 << 15),
- CF_USE_ME = (1 << 16),
- CF_GEN_RINGBACK = (1 << 17),
- CF_RING_READY = (1 << 18),
- CF_BREAK = (1 << 19),
- CF_BROADCAST = (1 << 20),
- CF_UNICAST = (1 << 21),
- CF_VIDEO = (1 << 22),
- CF_EVENT_LOCK = (1 << 23),
- CF_RESET = (1 << 24),
- CF_ORIGINATING = (1 << 25),
- CF_STOP_BROADCAST = (1 << 26),
- CF_PROXY_MEDIA = (1 << 27),
- CF_INNER_BRIDGE = (1 << 28),
- CF_REQ_MEDIA = (1 << 29),
- CF_VERBOSE_EVENTS = (1 << 30)
+public enum switch_channel_flag_t {
+ CF_ANSWERED = 1,
+ CF_OUTBOUND,
+ CF_EARLY_MEDIA,
+ CF_ORIGINATOR,
+ CF_TRANSFER,
+ CF_ACCEPT_CNG,
+ CF_REDIRECT,
+ CF_BRIDGED,
+ CF_HOLD,
+ CF_SERVICE,
+ CF_TAGGED,
+ CF_WINNER,
+ CF_CONTROLLED,
+ CF_PROXY_MODE,
+ CF_SUSPEND,
+ CF_EVENT_PARSE,
+ CF_GEN_RINGBACK,
+ CF_RING_READY,
+ CF_BREAK,
+ CF_BROADCAST,
+ CF_UNICAST,
+ CF_VIDEO,
+ CF_EVENT_LOCK,
+ CF_RESET,
+ CF_ORIGINATING,
+ CF_STOP_BROADCAST,
+ CF_PROXY_MEDIA,
+ CF_INNER_BRIDGE,
+ CF_REQ_MEDIA,
+ CF_VERBOSE_EVENTS,
+ CF_FLAG_MAX
}
}
Modified: freeswitch/trunk/src/switch_channel.c
==============================================================================
--- freeswitch/trunk/src/switch_channel.c (original)
+++ freeswitch/trunk/src/switch_channel.c Thu Dec 11 10:20:24 2008
@@ -115,9 +115,9 @@
switch_core_session_t *session;
switch_channel_state_t state;
switch_channel_state_t running_state;
- switch_channel_flag_t flags;
+ uint8_t flags[CF_FLAG_MAX];
+ uint8_t state_flags[CF_FLAG_MAX];
uint32_t private_flags;
- switch_channel_flag_t state_flags;
switch_caller_profile_t *caller_profile;
const switch_state_handler_table_t *state_handlers[SWITCH_MAX_STATE_HANDLERS];
int state_handler_index;
@@ -410,11 +410,11 @@
}
SWITCH_DECLARE(switch_status_t) switch_channel_init(switch_channel_t *channel, switch_core_session_t *session, switch_channel_state_t state,
- uint32_t flags)
+ switch_channel_flag_t flag)
{
switch_assert(channel != NULL);
channel->state = state;
- channel->flags = flags;
+ switch_channel_set_flag(channel, flag);
channel->session = session;
channel->running_state = CS_NONE;
return SWITCH_STATUS_SUCCESS;
@@ -643,13 +643,13 @@
return SWITCH_STATUS_FALSE;
}
-SWITCH_DECLARE(uint32_t) switch_channel_test_flag(switch_channel_t *channel, switch_channel_flag_t flags)
+SWITCH_DECLARE(uint32_t) switch_channel_test_flag(switch_channel_t *channel, switch_channel_flag_t flag)
{
switch_assert(channel != NULL);
- return switch_test_flag(channel, flags) ? 1 : 0;
+ return channel->flags[flag] ? 1 : 0;
}
-SWITCH_DECLARE(switch_bool_t) switch_channel_set_flag_partner(switch_channel_t *channel, switch_channel_flag_t flags)
+SWITCH_DECLARE(switch_bool_t) switch_channel_set_flag_partner(switch_channel_t *channel, switch_channel_flag_t flag)
{
const char *uuid;
@@ -658,7 +658,7 @@
if ((uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE))) {
switch_core_session_t *session;
if ((session = switch_core_session_locate(uuid))) {
- switch_channel_set_flag(switch_core_session_get_channel(session), flags);
+ switch_channel_set_flag(switch_core_session_get_channel(session), flag);
switch_core_session_rwunlock(session);
return SWITCH_TRUE;
}
@@ -667,7 +667,7 @@
return SWITCH_FALSE;
}
-SWITCH_DECLARE(switch_bool_t) switch_channel_clear_flag_partner(switch_channel_t *channel, switch_channel_flag_t flags)
+SWITCH_DECLARE(switch_bool_t) switch_channel_clear_flag_partner(switch_channel_t *channel, switch_channel_flag_t flag)
{
const char *uuid;
@@ -676,7 +676,7 @@
if ((uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE))) {
switch_core_session_t *session;
if ((session = switch_core_session_locate(uuid))) {
- switch_channel_clear_flag(switch_core_session_get_channel(session), flags);
+ switch_channel_clear_flag(switch_core_session_get_channel(session), flag);
switch_core_session_rwunlock(session);
return SWITCH_TRUE;
}
@@ -714,11 +714,11 @@
for (;;) {
if (pres) {
- if (switch_test_flag(channel, want_flag)) {
+ if (switch_channel_test_flag(channel, want_flag)) {
break;
}
} else {
- if (!switch_test_flag(channel, want_flag)) {
+ if (!switch_channel_test_flag(channel, want_flag)) {
break;
}
}
@@ -741,11 +741,16 @@
return SWITCH_STATUS_SUCCESS;
}
-SWITCH_DECLARE(void) switch_channel_set_flag(switch_channel_t *channel, switch_channel_flag_t flags)
+SWITCH_DECLARE(void) switch_channel_set_flag(switch_channel_t *channel, switch_channel_flag_t flag)
{
- switch_assert(channel != NULL);
- switch_set_flag_locked(channel, flags);
- if (flags & CF_OUTBOUND) {
+ switch_assert(channel);
+ switch_assert(channel->flag_mutex);
+
+ switch_mutex_lock(channel->flag_mutex);
+ channel->flags[flag] = 1;
+ switch_mutex_unlock(channel->flag_mutex);
+
+ if (flag == CF_OUTBOUND) {
switch_channel_set_variable(channel, "is_outbound", "true");
}
}
@@ -773,21 +778,25 @@
return (channel->private_flags & flags);
}
-
-SWITCH_DECLARE(void) switch_channel_set_state_flag(switch_channel_t *channel, switch_channel_flag_t flags)
+SWITCH_DECLARE(void) switch_channel_set_state_flag(switch_channel_t *channel, switch_channel_flag_t flag)
{
switch_assert(channel != NULL);
switch_mutex_lock(channel->flag_mutex);
- channel->state_flags |= flags;
+ channel->state_flags[0] = 1;
+ channel->state_flags[flag] = 1;
switch_mutex_unlock(channel->flag_mutex);
}
-SWITCH_DECLARE(void) switch_channel_clear_flag(switch_channel_t *channel, switch_channel_flag_t flags)
+SWITCH_DECLARE(void) switch_channel_clear_flag(switch_channel_t *channel, switch_channel_flag_t flag)
{
switch_assert(channel != NULL);
- switch_clear_flag_locked(channel, flags);
- if (flags & CF_OUTBOUND) {
+ switch_assert(channel->flag_mutex);
+
+ switch_mutex_lock(channel->flag_mutex);
+ channel->flags[flag] = 0;
+ switch_mutex_unlock(channel->flag_mutex);
+ if (flag == CF_OUTBOUND) {
switch_channel_set_variable(channel, "is_outbound", NULL);
}
}
@@ -823,7 +832,7 @@
switch_assert(channel != NULL);
if (!channel->hangup_cause && channel->state > CS_ROUTING && channel->state < CS_HANGUP && channel->state != CS_RESET &&
- !switch_test_flag(channel, CF_TRANSFER)) {
+ !switch_channel_test_flag(channel, CF_TRANSFER)) {
ret++;
}
@@ -867,16 +876,22 @@
SWITCH_DECLARE(switch_channel_state_t) switch_channel_perform_set_running_state(switch_channel_t *channel, switch_channel_state_t state,
const char *file, const char *func, int line)
{
+ int x;
switch_mutex_lock(channel->flag_mutex);
switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_DEBUG, "(%s) Running State Change %s\n", channel->name, state_names[state]);
channel->running_state = state;
- if (channel->state_flags) {
- channel->flags |= channel->state_flags;
- channel->state_flags = 0;
+ if (channel->state_flags[0]) {
+ for(x = 1; x < CF_FLAG_MAX ; x++ ) {
+ if (channel->state_flags[x]) {
+ channel->flags[x] = 1;
+ channel->state_flags[x] = 0;
+ }
+ }
+ channel->state_flags[0] = 0;
}
- switch_clear_flag(channel, CF_TAGGED);
+ switch_channel_clear_flag(channel, CF_TAGGED);
if (channel->state >= CS_ROUTING) {
switch_channel_presence(channel, "unknown", (char *) state_names[state], NULL);
@@ -1185,7 +1200,7 @@
}
- if (switch_test_flag(channel, CF_VERBOSE_EVENTS) ||
+ if (switch_channel_test_flag(channel, CF_VERBOSE_EVENTS) ||
event->event_id == SWITCH_EVENT_CHANNEL_ORIGINATE ||
event->event_id == SWITCH_EVENT_CHANNEL_UUID ||
event->event_id == SWITCH_EVENT_CHANNEL_ANSWER ||
1
0
[commit] r10709 - in freeswitch/trunk/src/mod/languages: mod_java mod_java/src/org/freeswitch/swig mod_lua mod_perl mod_python
by FreeSWITCH SVN 11 Dec '08
by FreeSWITCH SVN 11 Dec '08
11 Dec '08
Author: mikej
Date: Thu Dec 11 10:19:03 2008
New Revision: 10709
Log:
swigall
Modified:
freeswitch/trunk/src/mod/languages/mod_java/src/org/freeswitch/swig/CoreSession.java
freeswitch/trunk/src/mod/languages/mod_java/src/org/freeswitch/swig/freeswitchJNI.java
freeswitch/trunk/src/mod/languages/mod_java/switch_swig_wrap.cpp
freeswitch/trunk/src/mod/languages/mod_lua/mod_lua_wrap.cpp
freeswitch/trunk/src/mod/languages/mod_perl/mod_perl_wrap.cpp
freeswitch/trunk/src/mod/languages/mod_python/mod_python_wrap.cpp
Modified: freeswitch/trunk/src/mod/languages/mod_java/src/org/freeswitch/swig/CoreSession.java
==============================================================================
--- freeswitch/trunk/src/mod/languages/mod_java/src/org/freeswitch/swig/CoreSession.java (original)
+++ freeswitch/trunk/src/mod/languages/mod_java/src/org/freeswitch/swig/CoreSession.java Thu Dec 11 10:19:03 2008
@@ -245,12 +245,8 @@
return freeswitchJNI.CoreSession_streamFile__SWIG_1(swigCPtr, this, file);
}
- public int sleep(int ms, int sync) {
- return freeswitchJNI.CoreSession_sleep__SWIG_0(swigCPtr, this, ms, sync);
- }
-
public int sleep(int ms) {
- return freeswitchJNI.CoreSession_sleep__SWIG_1(swigCPtr, this, ms);
+ return freeswitchJNI.CoreSession_sleep(swigCPtr, this, ms);
}
public int flushEvents() {
Modified: freeswitch/trunk/src/mod/languages/mod_java/src/org/freeswitch/swig/freeswitchJNI.java
==============================================================================
--- freeswitch/trunk/src/mod/languages/mod_java/src/org/freeswitch/swig/freeswitchJNI.java (original)
+++ freeswitch/trunk/src/mod/languages/mod_java/src/org/freeswitch/swig/freeswitchJNI.java Thu Dec 11 10:19:03 2008
@@ -136,8 +136,7 @@
public final static native String CoreSession_playAndGetDigits(long jarg1, CoreSession jarg1_, int jarg2, int jarg3, int jarg4, int jarg5, String jarg6, String jarg7, String jarg8, String jarg9);
public final static native int CoreSession_streamFile__SWIG_0(long jarg1, CoreSession jarg1_, String jarg2, int jarg3);
public final static native int CoreSession_streamFile__SWIG_1(long jarg1, CoreSession jarg1_, String jarg2);
- public final static native int CoreSession_sleep__SWIG_0(long jarg1, CoreSession jarg1_, int jarg2, int jarg3);
- public final static native int CoreSession_sleep__SWIG_1(long jarg1, CoreSession jarg1_, int jarg2);
+ public final static native int CoreSession_sleep(long jarg1, CoreSession jarg1_, int jarg2);
public final static native int CoreSession_flushEvents(long jarg1, CoreSession jarg1_);
public final static native int CoreSession_flushDigits(long jarg1, CoreSession jarg1_);
public final static native int CoreSession_setAutoHangup(long jarg1, CoreSession jarg1_, boolean jarg2);
Modified: freeswitch/trunk/src/mod/languages/mod_java/switch_swig_wrap.cpp
==============================================================================
--- freeswitch/trunk/src/mod/languages/mod_java/switch_swig_wrap.cpp (original)
+++ freeswitch/trunk/src/mod/languages/mod_java/switch_swig_wrap.cpp Thu Dec 11 10:19:03 2008
@@ -2674,26 +2674,7 @@
}
-SWIGEXPORT jint JNICALL Java_org_freeswitch_swig_freeswitchJNI_CoreSession_1sleep_1_1SWIG_10(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2, jint jarg3) {
- jint jresult = 0 ;
- CoreSession *arg1 = (CoreSession *) 0 ;
- int arg2 ;
- int arg3 ;
- int result;
-
- (void)jenv;
- (void)jcls;
- (void)jarg1_;
- arg1 = *(CoreSession **)&jarg1;
- arg2 = (int)jarg2;
- arg3 = (int)jarg3;
- result = (int)(arg1)->sleep(arg2,arg3);
- jresult = (jint)result;
- return jresult;
-}
-
-
-SWIGEXPORT jint JNICALL Java_org_freeswitch_swig_freeswitchJNI_CoreSession_1sleep_1_1SWIG_11(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2) {
+SWIGEXPORT jint JNICALL Java_org_freeswitch_swig_freeswitchJNI_CoreSession_1sleep(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jint jarg2) {
jint jresult = 0 ;
CoreSession *arg1 = (CoreSession *) 0 ;
int arg2 ;
Modified: freeswitch/trunk/src/mod/languages/mod_lua/mod_lua_wrap.cpp
==============================================================================
--- freeswitch/trunk/src/mod/languages/mod_lua/mod_lua_wrap.cpp (original)
+++ freeswitch/trunk/src/mod/languages/mod_lua/mod_lua_wrap.cpp Thu Dec 11 10:19:03 2008
@@ -6077,38 +6077,7 @@
}
-static int _wrap_CoreSession_sleep__SWIG_0(lua_State* L) {
- int SWIG_arg = -1;
- CoreSession *arg1 = (CoreSession *) 0 ;
- int arg2 ;
- int arg3 ;
- int result;
-
- SWIG_check_num_args("sleep",3,3)
- if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("sleep",1,"CoreSession *");
- if(!lua_isnumber(L,2)) SWIG_fail_arg("sleep",2,"int");
- if(!lua_isnumber(L,3)) SWIG_fail_arg("sleep",3,"int");
-
- if (!SWIG_IsOK(SWIG_ConvertPtr(L,1,(void**)&arg1,SWIGTYPE_p_CoreSession,0))){
- SWIG_fail_ptr("CoreSession_sleep",1,SWIGTYPE_p_CoreSession);
- }
-
- arg2 = (int)lua_tonumber(L, 2);
- arg3 = (int)lua_tonumber(L, 3);
- result = (int)(arg1)->sleep(arg2,arg3);
- SWIG_arg=0;
- lua_pushnumber(L, (lua_Number) result); SWIG_arg++;
- return SWIG_arg;
-
- if(0) SWIG_fail;
-
-fail:
- lua_error(L);
- return SWIG_arg;
-}
-
-
-static int _wrap_CoreSession_sleep__SWIG_1(lua_State* L) {
+static int _wrap_CoreSession_sleep(lua_State* L) {
int SWIG_arg = -1;
CoreSession *arg1 = (CoreSession *) 0 ;
int arg2 ;
@@ -6136,62 +6105,6 @@
}
-static int _wrap_CoreSession_sleep(lua_State* L) {
- int argc;
- int argv[4]={
- 1,2,3,4
- };
-
- argc = lua_gettop(L);
- if (argc == 2) {
- int _v;
- {
- void *ptr;
- if (SWIG_isptrtype(L,argv[0])==0 || SWIG_ConvertPtr(L,argv[0], (void **) &ptr, SWIGTYPE_p_CoreSession, 0)) {
- _v = 0;
- } else {
- _v = 1;
- }
- }
- if (_v) {
- {
- _v = lua_isnumber(L,argv[1]);
- }
- if (_v) {
- return _wrap_CoreSession_sleep__SWIG_1(L);
- }
- }
- }
- if (argc == 3) {
- int _v;
- {
- void *ptr;
- if (SWIG_isptrtype(L,argv[0])==0 || SWIG_ConvertPtr(L,argv[0], (void **) &ptr, SWIGTYPE_p_CoreSession, 0)) {
- _v = 0;
- } else {
- _v = 1;
- }
- }
- if (_v) {
- {
- _v = lua_isnumber(L,argv[1]);
- }
- if (_v) {
- {
- _v = lua_isnumber(L,argv[2]);
- }
- if (_v) {
- return _wrap_CoreSession_sleep__SWIG_0(L);
- }
- }
- }
- }
-
- lua_pushstring(L,"No matching function for overloaded 'CoreSession_sleep'");
- lua_error(L);return 0;
-}
-
-
static int _wrap_CoreSession_flushEvents(lua_State* L) {
int SWIG_arg = -1;
CoreSession *arg1 = (CoreSession *) 0 ;
Modified: freeswitch/trunk/src/mod/languages/mod_perl/mod_perl_wrap.cpp
==============================================================================
--- freeswitch/trunk/src/mod/languages/mod_perl/mod_perl_wrap.cpp (original)
+++ freeswitch/trunk/src/mod/languages/mod_perl/mod_perl_wrap.cpp Thu Dec 11 10:19:03 2008
@@ -8146,55 +8146,7 @@
}
-XS(_wrap_CoreSession_sleep__SWIG_0) {
- {
- CoreSession *arg1 = (CoreSession *) 0 ;
- int arg2 ;
- int arg3 ;
- int result;
- void *argp1 = 0 ;
- int res1 = 0 ;
- int val2 ;
- int ecode2 = 0 ;
- int val3 ;
- int ecode3 = 0 ;
- int argvi = 0;
- dXSARGS;
-
- if ((items < 3) || (items > 3)) {
- SWIG_croak("Usage: CoreSession_sleep(self,ms,sync);");
- }
- res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_CoreSession, 0 | 0 );
- if (!SWIG_IsOK(res1)) {
- SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CoreSession_sleep" "', argument " "1"" of type '" "CoreSession *""'");
- }
- arg1 = reinterpret_cast< CoreSession * >(argp1);
- ecode2 = SWIG_AsVal_int SWIG_PERL_CALL_ARGS_2(ST(1), &val2);
- if (!SWIG_IsOK(ecode2)) {
- SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "CoreSession_sleep" "', argument " "2"" of type '" "int""'");
- }
- arg2 = static_cast< int >(val2);
- ecode3 = SWIG_AsVal_int SWIG_PERL_CALL_ARGS_2(ST(2), &val3);
- if (!SWIG_IsOK(ecode3)) {
- SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "CoreSession_sleep" "', argument " "3"" of type '" "int""'");
- }
- arg3 = static_cast< int >(val3);
- result = (int)(arg1)->sleep(arg2,arg3);
- ST(argvi) = SWIG_From_int SWIG_PERL_CALL_ARGS_1(static_cast< int >(result)); argvi++ ;
-
-
-
- XSRETURN(argvi);
- fail:
-
-
-
- SWIG_croak_null();
- }
-}
-
-
-XS(_wrap_CoreSession_sleep__SWIG_1) {
+XS(_wrap_CoreSession_sleep) {
{
CoreSession *arg1 = (CoreSession *) 0 ;
int arg2 ;
@@ -8232,98 +8184,6 @@
}
-XS(_wrap_CoreSession_sleep) {
- dXSARGS;
-
- {
- unsigned long _index = 0;
- SWIG_TypeRank _rank = 0;
- if (items == 2) {
- SWIG_TypeRank _ranki = 0;
- SWIG_TypeRank _rankm = 0;
- SWIG_TypeRank _pi = 1;
- int _v = 0;
- {
- void *vptr = 0;
- int res = SWIG_ConvertPtr(ST(0), &vptr, SWIGTYPE_p_CoreSession, 0);
- _v = SWIG_CheckState(res);
- }
- if (!_v) goto check_1;
- _ranki += _v*_pi;
- _rankm += _pi;
- _pi *= SWIG_MAXCASTRANK;
- {
- {
- int res = SWIG_AsVal_int SWIG_PERL_CALL_ARGS_2(ST(1), NULL);
- _v = SWIG_CheckState(res);
- }
- }
- if (!_v) goto check_1;
- _ranki += _v*_pi;
- _rankm += _pi;
- _pi *= SWIG_MAXCASTRANK;
- if (!_index || (_ranki < _rank)) {
- _rank = _ranki; _index = 1;
- if (_rank == _rankm) goto dispatch;
- }
- }
- check_1:
-
- if (items == 3) {
- SWIG_TypeRank _ranki = 0;
- SWIG_TypeRank _rankm = 0;
- SWIG_TypeRank _pi = 1;
- int _v = 0;
- {
- void *vptr = 0;
- int res = SWIG_ConvertPtr(ST(0), &vptr, SWIGTYPE_p_CoreSession, 0);
- _v = SWIG_CheckState(res);
- }
- if (!_v) goto check_2;
- _ranki += _v*_pi;
- _rankm += _pi;
- _pi *= SWIG_MAXCASTRANK;
- {
- {
- int res = SWIG_AsVal_int SWIG_PERL_CALL_ARGS_2(ST(1), NULL);
- _v = SWIG_CheckState(res);
- }
- }
- if (!_v) goto check_2;
- _ranki += _v*_pi;
- _rankm += _pi;
- _pi *= SWIG_MAXCASTRANK;
- {
- {
- int res = SWIG_AsVal_int SWIG_PERL_CALL_ARGS_2(ST(2), NULL);
- _v = SWIG_CheckState(res);
- }
- }
- if (!_v) goto check_2;
- _ranki += _v*_pi;
- _rankm += _pi;
- _pi *= SWIG_MAXCASTRANK;
- if (!_index || (_ranki < _rank)) {
- _rank = _ranki; _index = 2;
- if (_rank == _rankm) goto dispatch;
- }
- }
- check_2:
-
- dispatch:
- switch(_index) {
- case 1:
- ++PL_markstack_ptr; SWIG_CALLXS(_wrap_CoreSession_sleep__SWIG_1); return;
- case 2:
- ++PL_markstack_ptr; SWIG_CALLXS(_wrap_CoreSession_sleep__SWIG_0); return;
- }
- }
-
- croak("No matching function for overloaded 'CoreSession_sleep'");
- XSRETURN(0);
-}
-
-
XS(_wrap_CoreSession_flushEvents) {
{
CoreSession *arg1 = (CoreSession *) 0 ;
Modified: freeswitch/trunk/src/mod/languages/mod_python/mod_python_wrap.cpp
==============================================================================
--- freeswitch/trunk/src/mod/languages/mod_python/mod_python_wrap.cpp (original)
+++ freeswitch/trunk/src/mod/languages/mod_python/mod_python_wrap.cpp Thu Dec 11 10:19:03 2008
@@ -8018,47 +8018,7 @@
}
-SWIGINTERN PyObject *_wrap_CoreSession_sleep__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
- PyObject *resultobj = 0;
- CoreSession *arg1 = (CoreSession *) 0 ;
- int arg2 ;
- int arg3 ;
- int result;
- void *argp1 = 0 ;
- int res1 = 0 ;
- int val2 ;
- int ecode2 = 0 ;
- int val3 ;
- int ecode3 = 0 ;
- PyObject * obj0 = 0 ;
- PyObject * obj1 = 0 ;
- PyObject * obj2 = 0 ;
-
- if (!PyArg_ParseTuple(args,(char *)"OOO:CoreSession_sleep",&obj0,&obj1,&obj2)) SWIG_fail;
- res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CoreSession, 0 | 0 );
- if (!SWIG_IsOK(res1)) {
- SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CoreSession_sleep" "', argument " "1"" of type '" "CoreSession *""'");
- }
- arg1 = reinterpret_cast< CoreSession * >(argp1);
- ecode2 = SWIG_AsVal_int(obj1, &val2);
- if (!SWIG_IsOK(ecode2)) {
- SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "CoreSession_sleep" "', argument " "2"" of type '" "int""'");
- }
- arg2 = static_cast< int >(val2);
- ecode3 = SWIG_AsVal_int(obj2, &val3);
- if (!SWIG_IsOK(ecode3)) {
- SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "CoreSession_sleep" "', argument " "3"" of type '" "int""'");
- }
- arg3 = static_cast< int >(val3);
- result = (int)(arg1)->sleep(arg2,arg3);
- resultobj = SWIG_From_int(static_cast< int >(result));
- return resultobj;
-fail:
- return NULL;
-}
-
-
-SWIGINTERN PyObject *_wrap_CoreSession_sleep__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_CoreSession_sleep(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
CoreSession *arg1 = (CoreSession *) 0 ;
int arg2 ;
@@ -8089,62 +8049,6 @@
}
-SWIGINTERN PyObject *_wrap_CoreSession_sleep(PyObject *self, PyObject *args) {
- int argc;
- PyObject *argv[4];
- int ii;
-
- if (!PyTuple_Check(args)) SWIG_fail;
- argc = (int)PyObject_Length(args);
- for (ii = 0; (ii < argc) && (ii < 3); ii++) {
- argv[ii] = PyTuple_GET_ITEM(args,ii);
- }
- if (argc == 2) {
- int _v;
- void *vptr = 0;
- int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_CoreSession, 0);
- _v = SWIG_CheckState(res);
- if (_v) {
- {
- int res = SWIG_AsVal_int(argv[1], NULL);
- _v = SWIG_CheckState(res);
- }
- if (_v) {
- return _wrap_CoreSession_sleep__SWIG_1(self, args);
- }
- }
- }
- if (argc == 3) {
- int _v;
- void *vptr = 0;
- int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_CoreSession, 0);
- _v = SWIG_CheckState(res);
- if (_v) {
- {
- int res = SWIG_AsVal_int(argv[1], NULL);
- _v = SWIG_CheckState(res);
- }
- if (_v) {
- {
- int res = SWIG_AsVal_int(argv[2], NULL);
- _v = SWIG_CheckState(res);
- }
- if (_v) {
- return _wrap_CoreSession_sleep__SWIG_0(self, args);
- }
- }
- }
- }
-
-fail:
- SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'CoreSession_sleep'.\n"
- " Possible C/C++ prototypes are:\n"
- " sleep(CoreSession *,int,int)\n"
- " sleep(CoreSession *,int)\n");
- return NULL;
-}
-
-
SWIGINTERN PyObject *_wrap_CoreSession_flushEvents(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
CoreSession *arg1 = (CoreSession *) 0 ;
1
0
10 Dec '08
Author: ericdc
Date: Wed Dec 10 16:43:26 2008
New Revision: 10705
Log:
Initial upload.
Added:
freeswitch/trunk/src/mod/applications/mod_http/Makefile
freeswitch/trunk/src/mod/applications/mod_http/arraylist.c
freeswitch/trunk/src/mod/applications/mod_http/arraylist.h
freeswitch/trunk/src/mod/applications/mod_http/bits.h
freeswitch/trunk/src/mod/applications/mod_http/config.h
freeswitch/trunk/src/mod/applications/mod_http/debug.c
freeswitch/trunk/src/mod/applications/mod_http/debug.h
freeswitch/trunk/src/mod/applications/mod_http/http_req.c
freeswitch/trunk/src/mod/applications/mod_http/http_req.h
freeswitch/trunk/src/mod/applications/mod_http/json.h
freeswitch/trunk/src/mod/applications/mod_http/json_object.c
freeswitch/trunk/src/mod/applications/mod_http/json_object.h
freeswitch/trunk/src/mod/applications/mod_http/json_object_private.h
freeswitch/trunk/src/mod/applications/mod_http/json_tokener.c
freeswitch/trunk/src/mod/applications/mod_http/json_tokener.h
freeswitch/trunk/src/mod/applications/mod_http/json_util.c
freeswitch/trunk/src/mod/applications/mod_http/json_util.h
freeswitch/trunk/src/mod/applications/mod_http/linkhash.c
freeswitch/trunk/src/mod/applications/mod_http/linkhash.h
freeswitch/trunk/src/mod/applications/mod_http/mod_http.c
freeswitch/trunk/src/mod/applications/mod_http/printbuf.c
freeswitch/trunk/src/mod/applications/mod_http/printbuf.h
freeswitch/trunk/src/mod/applications/mod_http/url_encoding.c
freeswitch/trunk/src/mod/applications/mod_http/url_encoding.h
Added: freeswitch/trunk/src/mod/applications/mod_http/Makefile
==============================================================================
--- (empty file)
+++ freeswitch/trunk/src/mod/applications/mod_http/Makefile Wed Dec 10 16:43:26 2008
@@ -0,0 +1,5 @@
+BASE=../../../..
+LOCAL_SOURCES=arraylist.c debug.c json_object.c json_tokener.c json_util.c linkhash.c printbuf.c url_encoding.c http_req.c
+LOCAL_OBJS=arraylist.o debug.o json_object.o json_tokener.o json_util.o linkhash.o printbuf.o url_encoding.o http_req.o
+include $(BASE)/build/modmake.rules
+
Added: freeswitch/trunk/src/mod/applications/mod_http/arraylist.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/src/mod/applications/mod_http/arraylist.c Wed Dec 10 16:43:26 2008
@@ -0,0 +1,93 @@
+/*
+ * $Id: arraylist.c,v 1.4 2006/01/26 02:16:28 mclark Exp $
+ *
+ * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
+ * Michael Clark <michael(a)metaparadigm.com>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See COPYING for details.
+ *
+ */
+
+#include "config.h"
+
+#if STDC_HEADERS
+# include <stdlib.h>
+# include <string.h>
+#endif /* STDC_HEADERS */
+
+#if HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+
+#include "bits.h"
+#include "arraylist.h"
+
+struct array_list*
+array_list_new(array_list_free_fn *free_fn)
+{
+ struct array_list *this;
+
+ if(!(this = calloc(1, sizeof(struct array_list)))) return NULL;
+ this->size = ARRAY_LIST_DEFAULT_SIZE;
+ this->length = 0;
+ this->free_fn = free_fn;
+ if(!(this->array = calloc(sizeof(void*), this->size))) {
+ free(this);
+ return NULL;
+ }
+ return this;
+}
+
+extern void
+array_list_free(struct array_list *this)
+{
+ int i;
+ for(i = 0; i < this->length; i++)
+ if(this->array[i]) this->free_fn(this->array[i]);
+ free(this->array);
+ free(this);
+}
+
+void*
+array_list_get_idx(struct array_list *this, int i)
+{
+ if(i >= this->length) return NULL;
+ return this->array[i];
+}
+
+static int array_list_expand_internal(struct array_list *this, int max)
+{
+ void *t;
+ int new_size;
+
+ if(max < this->size) return 0;
+ new_size = max(this->size << 1, max);
+ if(!(t = realloc(this->array, new_size*sizeof(void*)))) return -1;
+ this->array = t;
+ (void)memset(this->array + this->size, 0, (new_size-this->size)*sizeof(void*));
+ this->size = new_size;
+ return 0;
+}
+
+int
+array_list_put_idx(struct array_list *this, int idx, void *data)
+{
+ if(array_list_expand_internal(this, idx)) return -1;
+ if(this->array[idx]) this->free_fn(this->array[idx]);
+ this->array[idx] = data;
+ if(this->length <= idx) this->length = idx + 1;
+ return 0;
+}
+
+int
+array_list_add(struct array_list *this, void *data)
+{
+ return array_list_put_idx(this, this->length, data);
+}
+
+int
+array_list_length(struct array_list *this)
+{
+ return this->length;
+}
Added: freeswitch/trunk/src/mod/applications/mod_http/arraylist.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/src/mod/applications/mod_http/arraylist.h Wed Dec 10 16:43:26 2008
@@ -0,0 +1,45 @@
+/*
+ * $Id: arraylist.h,v 1.4 2006/01/26 02:16:28 mclark Exp $
+ *
+ * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
+ * Michael Clark <michael(a)metaparadigm.com>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See COPYING for details.
+ *
+ */
+
+#ifndef _arraylist_h_
+#define _arraylist_h_
+
+#define ARRAY_LIST_DEFAULT_SIZE 32
+
+typedef void (array_list_free_fn) (void *data);
+
+struct array_list
+{
+ void **array;
+ int length;
+ int size;
+ array_list_free_fn *free_fn;
+};
+
+extern struct array_list*
+array_list_new(array_list_free_fn *free_fn);
+
+extern void
+array_list_free(struct array_list *al);
+
+extern void*
+array_list_get_idx(struct array_list *al, int i);
+
+extern int
+array_list_put_idx(struct array_list *al, int i, void *data);
+
+extern int
+array_list_add(struct array_list *al, void *data);
+
+extern int
+array_list_length(struct array_list *al);
+
+#endif
Added: freeswitch/trunk/src/mod/applications/mod_http/bits.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/src/mod/applications/mod_http/bits.h Wed Dec 10 16:43:26 2008
@@ -0,0 +1,27 @@
+/*
+ * $Id: bits.h,v 1.10 2006/01/30 23:07:57 mclark Exp $
+ *
+ * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
+ * Michael Clark <michael(a)metaparadigm.com>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See COPYING for details.
+ *
+ */
+
+#ifndef _bits_h_
+#define _bits_h_
+
+#ifndef min
+#define min(a,b) ((a) < (b) ? (a) : (b))
+#endif
+
+#ifndef max
+#define max(a,b) ((a) > (b) ? (a) : (b))
+#endif
+
+#define hexdigit(x) (((x) <= '9') ? (x) - '0' : ((x) & 7) + 9)
+#define error_ptr(error) ((void*)error)
+#define is_error(ptr) ((unsigned long)ptr > (unsigned long)-4000L)
+
+#endif
Added: freeswitch/trunk/src/mod/applications/mod_http/config.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/src/mod/applications/mod_http/config.h Wed Dec 10 16:43:26 2008
@@ -0,0 +1,118 @@
+/* config.h. Generated from config.h.in by configure. */
+/* config.h.in. Generated from configure.in by autoheader. */
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#define HAVE_DLFCN_H 1
+
+/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
+/* #undef HAVE_DOPRNT */
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H 1
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the <limits.h> header file. */
+#define HAVE_LIMITS_H 1
+
+/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
+ to 0 otherwise. */
+#define HAVE_MALLOC 1
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the `open' function. */
+#define HAVE_OPEN 1
+
+/* Define to 1 if your system has a GNU libc compatible `realloc' function,
+ and to 0 otherwise. */
+#define HAVE_REALLOC 1
+
+/* Define to 1 if you have the <stdarg.h> header file. */
+#define HAVE_STDARG_H 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the `strerror' function. */
+#define HAVE_STRERROR 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the `strncasecmp' function. */
+#define HAVE_STRNCASECMP 1
+
+/* Define to 1 if you have the `strndup' function. */
+#define HAVE_STRNDUP 1
+
+/* Define to 1 if you have the <syslog.h> header file. */
+#define HAVE_SYSLOG_H 1
+
+/* Define to 1 if you have the <sys/param.h> header file. */
+#define HAVE_SYS_PARAM_H 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define to 1 if you have the `vasprintf' function. */
+#define HAVE_VASPRINTF 1
+
+/* Define to 1 if you have the `vprintf' function. */
+#define HAVE_VPRINTF 1
+
+/* Define to 1 if you have the `vsnprintf' function. */
+#define HAVE_VSNPRINTF 1
+
+/* Define to 1 if you have the `vsyslog' function. */
+#define HAVE_VSYSLOG 1
+
+/* Name of package */
+#define PACKAGE ""
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "michael(a)metaparadigm.com"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "JSON C Library"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "JSON C Library 0.3"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "json-c"
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "0.3"
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Version number of package */
+#define VERSION "0.3"
+
+/* Define to empty if `const' does not conform to ANSI C. */
+/* #undef const */
+
+/* Define to rpl_malloc if the replacement function should be used. */
+/* #undef malloc */
+
+/* Define to rpl_realloc if the replacement function should be used. */
+/* #undef realloc */
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+/* #undef size_t */
Added: freeswitch/trunk/src/mod/applications/mod_http/debug.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/src/mod/applications/mod_http/debug.c Wed Dec 10 16:43:26 2008
@@ -0,0 +1,94 @@
+/*
+ * $Id: debug.c,v 1.5 2006/01/26 02:16:28 mclark Exp $
+ *
+ * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
+ * Michael Clark <michael(a)metaparadigm.com>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See COPYING for details.
+ *
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+
+#if HAVE_SYSLOG_H
+# include <syslog.h>
+#endif /* HAVE_SYSLOG_H */
+
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
+#if HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif /* HAVE_SYS_PARAM_H */
+
+#include "debug.h"
+
+static int _syslog = 0;
+static int _debug = 0;
+
+void mc_set_debug(int debug) { _debug = debug; }
+int mc_get_debug() { return _debug; }
+
+extern void mc_set_syslog(int syslog)
+{
+ _syslog = syslog;
+}
+
+void mc_abort(const char *msg, ...)
+{
+ va_list ap;
+ va_start(ap, msg);
+#if HAVE_VSYSLOG
+ if(_syslog) {
+ vsyslog(LOG_ERR, msg, ap);
+ } else
+#endif
+ vprintf(msg, ap);
+ exit(1);
+}
+
+
+void mc_debug(const char *msg, ...)
+{
+ va_list ap;
+ if(_debug) {
+ va_start(ap, msg);
+#if HAVE_VSYSLOG
+ if(_syslog) {
+ vsyslog(LOG_DEBUG, msg, ap);
+ } else
+#endif
+ vprintf(msg, ap);
+ }
+}
+
+void mc_error(const char *msg, ...)
+{
+ va_list ap;
+ va_start(ap, msg);
+#if HAVE_VSYSLOG
+ if(_syslog) {
+ vsyslog(LOG_ERR, msg, ap);
+ } else
+#endif
+ vfprintf(stderr, msg, ap);
+}
+
+void mc_info(const char *msg, ...)
+{
+ va_list ap;
+ va_start(ap, msg);
+#if HAVE_VSYSLOG
+ if(_syslog) {
+ vsyslog(LOG_INFO, msg, ap);
+ } else
+#endif
+ vfprintf(stderr, msg, ap);
+}
Added: freeswitch/trunk/src/mod/applications/mod_http/debug.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/src/mod/applications/mod_http/debug.h Wed Dec 10 16:43:26 2008
@@ -0,0 +1,24 @@
+/*
+ * $Id: debug.h,v 1.5 2006/01/30 23:07:57 mclark Exp $
+ *
+ * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
+ * Michael Clark <michael(a)metaparadigm.com>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See COPYING for details.
+ *
+ */
+
+#ifndef _DEBUG_H_
+#define _DEBUG_H_
+
+extern void mc_set_debug(int debug);
+extern int mc_get_debug();
+
+extern void mc_set_syslog(int syslog);
+extern void mc_abort(const char *msg, ...);
+extern void mc_debug(const char *msg, ...);
+extern void mc_error(const char *msg, ...);
+extern void mc_info(const char *msg, ...);
+
+#endif
Added: freeswitch/trunk/src/mod/applications/mod_http/http_req.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/src/mod/applications/mod_http/http_req.c Wed Dec 10 16:43:26 2008
@@ -0,0 +1,680 @@
+/*
+ * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
+ * Copyright (C) 2008, Eric des Courtis <eric.des.courtis(a)benbria.com>
+ *
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * Eric des Courtis <eric.des.courtis(a)benbria.com>
+ * Copyright (C) Benbria. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Eric des Courtis <eric.des.courtis(a)benbria.com>
+ *
+ *
+ * http_req.c -- HTTP client implementation
+ *
+ */
+
+#include "http_req.h"
+
+/*
+extern int dprintf(int, const char *, ...);
+extern int isblank(int);
+*/
+
+/* NOTE: v = version, header = h, status = s, newline = n, phrase = p */
+static accept_state_t state_start(char c, state_machine_t *sm);
+static accept_state_t state_shp (char c, state_machine_t *sm);
+static accept_state_t state_n (char c, state_machine_t *sm);
+static accept_state_t state_vhp_A(char c, state_machine_t *sm);
+static accept_state_t state_vhp_B(char c, state_machine_t *sm);
+static accept_state_t state_vhp_C(char c, state_machine_t *sm);
+static accept_state_t state_vhp_D(char c, state_machine_t *sm);
+static accept_state_t state_vhp_E(char c, state_machine_t *sm);
+static accept_state_t state_vhp_F(char c, state_machine_t *sm);
+static accept_state_t state_vhp_G(char c, state_machine_t *sm);
+static accept_state_t state_vhp_H(char c, state_machine_t *sm);
+static accept_state_t state_hp_A (char c, state_machine_t *sm);
+static accept_state_t state_hp_B (char c, state_machine_t *sm);
+static accept_state_t state_p (char c, state_machine_t *sm);
+static accept_state_t state_error(char c, state_machine_t *sm);
+
+static int read_all(int s, char *buf, size_t len);
+
+#ifdef DEBUG
+int main(int argc, char *argv[])
+{
+ http_response_t response;
+ http_request_t request;
+ int ret;
+ int i;
+
+ if(argc != 2) return EXIT_FAILURE;
+
+ request.method = GET;
+ request.version = DEFAULT_HTTP_VERSION;
+ request.url = argv[1];
+ request.header_len = 0;
+ request.body_len = 0;
+
+ ret = http_req(&request, &response);
+ if(ret == ERROR) return EXIT_FAILURE;
+
+ printf("Version : %s\n", response.version);
+ printf("Status Code : %d\n", response.status_code);
+ printf("Phrase : %s\n", response.phrase);
+
+ for(i = 0; i < response.header_len; i++){
+ printf(
+ "Header : key = [%s] value = [%s]\n",
+ response.headers[i].field_name, response.headers[i].value
+ );
+ }
+
+ fflush(stdout);
+ write(STDOUT_FILENO, response.body, response.body_len);
+ printf("\n");
+
+ free_http_response(&response);
+
+ return EXIT_SUCCESS;
+}
+#endif
+
+int http_req(http_request_t *req, http_response_t *res)
+{
+ uint32_t addr;
+ int s;
+ int ret;
+ uint16_t port = 0;
+ size_t len;
+ struct sockaddr_in sck;
+ struct hostent *hst;
+ char *hostname;
+ char *method;
+ char *buf;
+ int buf_len;
+ ssize_t i;
+ int j;
+ int l;
+ int m;
+ int p;
+ int q = 0;
+ char f = HTTP_FALSE;
+ char port_s[MAX_PORT_LEN];
+ sighandler_t sig;
+ struct timeval tv;
+
+ tv.tv_sec = 1;
+ tv.tv_usec = 0;
+
+
+ (void)memset(&sck, 0, sizeof(sck));
+
+ sig = signal(SIGPIPE, SIG_IGN);
+ if(sig == SIG_ERR){
+ fprintf(stderr, "Cannot ignore SIGPIPE signal\n");
+ return ERROR;
+ }
+
+ s = socket(PF_INET, SOCK_STREAM, 0);
+ if(s == ERROR){
+ perror("Could not create socket");
+ return ERROR;
+ }
+
+ (void)setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
+ (void)setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
+
+ len = strlen(req->url);
+ hostname = (char *)malloc(len * sizeof(char) + 1);
+ if(hostname == NULL){
+ perror("Could not allocate memory for hostname");
+ close(s);
+ return ERROR;
+ }
+
+ EMPTY_STRING(hostname);
+
+ l = strlen(req->url) + 1;
+ m = strlen("http://");
+ for(p = 0, j = m; j < l; j++){
+ if(req->url[j] == ':'){
+ strncpy(hostname, req->url + m, j - m);
+ hostname[j - m] = '\0';
+ f = HTTP_TRUE;
+ p = j;
+ continue;
+ }
+
+ if((req->url[j] == '/' || req->url[j] == '\0') && f == HTTP_TRUE){
+ if((j - p) < MAX_PORT_LEN){
+ strncpy(port_s, req->url + p + 1, j - p);
+ port_s[j - p] = '\0';
+ port = (uint16_t)atoi(port_s);
+ }else port = 0;
+ q = j;
+ break;
+ }
+
+ if((req->url[j] == '/' || req->url[j] == '\0') && f == HTTP_FALSE){
+ strncpy(hostname, req->url + m, j - m);
+ hostname[j - m] = '\0';
+ port = DEFAULT_HTTP_PORT;
+ q = j;
+ break;
+ }
+ }
+
+ if(port == 0 || hostname[0] == '\0'){
+ fprintf(stderr, "Invalid URL\n");
+ close(s);
+ free(hostname);
+ return ERROR;
+ }
+
+ l = strlen(hostname);
+ for(j = 0; j < l; j++){
+ if(hostname[j] == '/'){
+ hostname[j] = '\0';
+ break;
+ }
+ }
+
+ hst = gethostbyname(hostname);
+ if(hst == NULL){
+ herror("Could not find host");
+ close(s);
+ free(hostname);
+ return ERROR;
+ }
+
+ addr = *((uint32_t *)hst->h_addr_list[0]);
+
+ sck.sin_family = AF_INET;
+ sck.sin_port = htons(port);
+ sck.sin_addr.s_addr = addr;
+
+ ret = connect(s, (struct sockaddr *)&sck, sizeof(sck));
+ if(ret == ERROR){
+ perror("Could not connect to host");
+ close(s);
+ free(hostname);
+ return ERROR;
+ }
+
+ switch(req->method){
+ case GET:
+ method = HTTP_GET_METHOD;
+ break;
+ case HEAD:
+ method = HTTP_HEAD_METHOD;
+ break;
+ case POST:
+ method = HTTP_POST_METHOD;
+ break;
+ case DELETE:
+ method = HTTP_DELETE_METHOD;
+ break;
+ case PUT:
+ method = HTTP_PUT_METHOD;
+ break;
+ default:
+ method = HTTP_GET_METHOD;
+ }
+
+ if(req->url[q] == '/'){
+ dprintf(s, "%s %s HTTP/%s\r\n", method, req->url + q, req->version);
+ }else{
+ dprintf(s, "%s /%s HTTP/%s\r\n", method, req->url + q, req->version);
+ }
+
+ if(port != DEFAULT_HTTP_PORT)
+ dprintf(s, "Host: %s:%d\r\n", hostname, port);
+ else dprintf(s, "Host: %s\r\n", hostname);
+ dprintf(s, "Connection: close\r\n");
+ dprintf(s, "Content-Length: %d\r\n", req->body_len);
+
+ for(i = 0; i < req->header_len; i++){
+ dprintf(
+ s,
+ "%s: %s\r\n",
+ req->headers[i].field_name,
+ req->headers[i].value
+ );
+ }
+
+ dprintf(s, "\r\n");
+
+
+ if(req->body != NULL && req->body_len != 0){
+ ret = write(s, req->body, req->body_len);
+ if(ret == ERROR){
+ perror("Could not write body to socket");
+ free(hostname);
+ return ERROR;
+ }
+ }
+
+ buf = (char *)malloc(RECV_BUFF_SIZE * sizeof(char));
+ if(buf == NULL){
+ perror("Could not allocate memory for buffer");
+ close(s);
+ free(hostname);
+ return ERROR;
+ }
+
+ buf_len = read_all(s, buf, RECV_BUFF_SIZE -1);
+ if(buf_len == ERROR){
+ perror("Could not read into buffer");
+ free(hostname);
+ return ERROR;
+ }
+ buf[buf_len] = '\0';
+
+ close(s);
+
+ (void)signal(SIGPIPE, sig);
+ free(hostname);
+ return http_parse_response(buf, buf_len, res);
+}
+
+int http_parse_response(char *buf, ssize_t buf_len, http_response_t *response)
+{
+ token_t token;
+ state_machine_t sm;
+ int pos;
+ ssize_t size;
+ char buff[STATUS_CODE_LEN];
+ int old_pos;
+ int nt;
+ int i;
+ int j;
+ int f;
+
+ INIT_STATE_MACHINE(&sm);
+
+ sm.buf = buf;
+ sm.buf_len = buf_len;
+
+ pos = sm.pos;
+ token = get_next_token(&sm);
+ if(token != VERSION){
+ fprintf(stderr, "ERROR %d-%d\n", VERSION, token);
+ return ERROR;
+ }
+
+ size = sm.pos - pos;
+ response->version = (char *)malloc((size + 1) * sizeof(char));
+ if(response->version == NULL){
+ perror("Cannot allocate memory for version number");
+ return ERROR;
+ }
+ strncpy(response->version, sm.buf + pos, size);
+ response->version[size] = '\0';
+
+ pos = sm.pos;
+ token = get_next_token(&sm);
+ if(token != STATUS_CODE){
+ fprintf(stderr, "ERROR %d-%d\n", STATUS_CODE, token);
+ return ERROR;
+ }
+
+ size = sm.pos - pos;
+
+ buff[STATUS_CODE_LEN - 1] = '\0';
+ strncpy(buff, sm.buf + pos, STATUS_CODE_LEN - 1);
+
+ response->status_code = atoi(buff);
+
+ pos = sm.pos;
+ token = get_next_token(&sm);
+ if(token != PHRASE){
+ fprintf(stderr, "ERROR %d-%d\n", PHRASE, token);
+ return ERROR;
+ }
+
+ size = sm.pos - pos - 2;
+ response->phrase = (char *)malloc((size + 1) * sizeof(char));
+ if(response->phrase == NULL){
+ perror("Cannot allocate memory for phrase");
+ return ERROR;
+ }
+ strncpy(response->phrase, sm.buf + pos, size);
+ response->phrase[size] = '\0';
+
+ old_pos = sm.pos;
+ nt = 0;
+ f = HTTP_FALSE;
+ do{
+ token = get_next_token(&sm);
+ switch(token){
+ case PHRASE:
+ case STATUS_CODE:
+ f = HTTP_FALSE;
+ case VERSION:
+ case NEWLINE:
+ break;
+ case HEADER:
+ if(f == HTTP_FALSE){
+ nt++;
+ f = HTTP_TRUE;
+ }
+ else f = HTTP_FALSE;
+ break;
+ case SYNTAX_ERROR:
+ return ERROR;
+ }
+
+ if(token != HEADER && token != PHRASE && token != STATUS_CODE) break;
+ }while(token != SYNTAX_ERROR);
+
+ if(nt != 0){
+ response->headers = (http_header_t *)malloc(sizeof(http_header_t)*nt);
+ if(response->headers == NULL){
+ perror("Could not allocate memory for headers");
+ return ERROR;
+ }
+ }else response->headers = NULL;
+
+ response->header_len = nt;
+
+ sm.pos = old_pos;
+ for(i = 0; i < nt; i++){
+ pos = sm.pos;
+ sm.state = state_start;
+ sm.stop = HTTP_FALSE;
+ token = get_next_token(&sm);
+ size = sm.pos - pos;
+ size -= 2;
+
+ response->headers[i].field_name =
+ (char *)malloc((size + 1) * sizeof(char));
+
+ if(response->headers[i].field_name == NULL){
+ perror("Could not allocate memory for header");
+ return ERROR;
+ }
+
+ strncpy(response->headers[i].field_name, sm.buf + pos, size);
+ response->headers[i].field_name[size] = '\0';
+
+ pos = sm.pos;
+ token = get_next_token(&sm);
+ if(token == HEADER || token == STATUS_CODE){
+ for(j = 0;
+ ((sm.buf + pos)[j] == '\r'
+ && (sm.buf + pos)[j + 1] == '\n') == 0;
+ j++
+ );
+ size = j;
+ sm.pos = j + 2;
+ }else size = sm.pos - pos - 2;
+
+ response->headers[i].value =
+ (char *)malloc((size + 1) * sizeof(char));
+
+ if(response->headers[i].value == NULL){
+ perror("Could not allocate memory for header");
+ return ERROR;
+ }
+ strncpy(response->headers[i].value, sm.buf + pos, size);
+ response->headers[i].value[size] = '\0';
+
+ }
+
+ pos = sm.pos;
+ token = get_next_token(&sm);
+ if(token != NEWLINE){
+ fprintf(stderr, "ERROR %d-%d\n", NEWLINE, token);
+ return ERROR;
+ }
+
+
+ response->body = (char *)malloc((buf_len - sm.pos + 1) * sizeof(char));
+ if(response->body == NULL){
+ perror("Could not allocate memory for body");
+ return ERROR;
+ }
+
+ response->body_len = buf_len - sm.pos;
+ response->body[response->body_len] = '\0';
+
+ (void)memcpy(response->body, buf + sm.pos, response->body_len);
+
+ return SUCCESS;
+}
+
+void free_http_response(http_response_t *response)
+{
+ free(response->version);
+ free(response->phrase);
+ if(response->headers != NULL) free(response->headers);
+ if(response->body != NULL) free(response->body);
+}
+
+token_t get_next_token(state_machine_t *sm)
+{
+ char c;
+ accept_state_t accept;
+
+ while(sm->stop != HTTP_TRUE){
+ c = sm->buf[sm->pos];
+ accept = sm->state(c, sm);
+ switch(accept){
+ case NOAS:
+ case ASNR:
+ sm->pos++;
+ case ASWR:
+ break;
+ }
+
+ switch(accept){
+ case ASNR:
+ case ASWR:
+ sm->state = state_start;
+ return sm->token;
+ case NOAS:
+ break;
+ }
+
+ if(sm->pos >= sm->buf_len){
+ sm->stop = HTTP_TRUE;
+ break;
+ }
+ }
+
+ return SYNTAX_ERROR;
+}
+
+static accept_state_t state_start(char c, state_machine_t *sm)
+{
+ if(toupper(c) == 'H') sm->state = state_vhp_A;
+ else if(isdigit(c)) sm->state = state_shp;
+ else if(c == '\r' || c == '\n') sm->state = state_n;
+ else if(isprint(c)) sm->state = state_hp_A;
+ else sm->state = state_error;
+
+ return NOAS;
+}
+
+static accept_state_t state_shp(char c, state_machine_t *sm)
+{
+ if(isdigit(c)) sm->state = state_shp;
+ else if(isblank(c)){
+ sm->token = STATUS_CODE;
+ return ASNR;
+ }else if(c == ':') sm->state = state_hp_B;
+ else if(c == '\r' || c == '\n') sm->state = state_p;
+ else if(isprint(c)) sm->state = state_hp_A;
+ else sm->state = state_error;
+
+ return NOAS;
+}
+
+static accept_state_t state_n(char c, state_machine_t *sm)
+{
+ if(c == '\r' || c == '\n'){
+ sm->token = NEWLINE;
+ return ASNR;
+ }else if(c == ':') sm->state = state_hp_B;
+ else if(isprint(c)) sm->state = state_hp_A;
+ else sm->state = state_error;
+
+ return NOAS;
+}
+
+static accept_state_t state_vhp_A(char c, state_machine_t *sm)
+{
+ if(toupper(c) == 'T') sm->state = state_vhp_B;
+ else if(isprint(c)) sm->state = state_hp_A;
+ else if(c == '\n' || c == '\r') sm->state = state_p;
+ else sm->state = state_error;
+
+ return NOAS;
+}
+
+static accept_state_t state_vhp_B(char c, state_machine_t *sm)
+{
+ if(toupper(c) == 'T') sm->state = state_vhp_C;
+ else if(isprint(c)) sm->state = state_hp_A;
+ else if(c == '\n' || c == '\r') sm->state = state_p;
+ else sm->state = state_error;
+
+ return NOAS;
+}
+
+static accept_state_t state_vhp_C(char c, state_machine_t *sm)
+{
+ if(toupper(c) == 'P') sm->state = state_vhp_D;
+ else if(isprint(c)) sm->state = state_hp_A;
+ else if(c == '\n' || c == '\r') sm->state = state_p;
+ else sm->state = state_error;
+
+ return NOAS;
+}
+
+static accept_state_t state_vhp_D(char c, state_machine_t *sm)
+{
+ if(toupper(c) == '/') sm->state = state_vhp_E;
+ else if(isprint(c)) sm->state = state_hp_A;
+ else if(c == '\n' || c == '\r') sm->state = state_p;
+ else sm->state = state_error;
+
+ return NOAS;
+}
+
+static accept_state_t state_vhp_E(char c, state_machine_t *sm)
+{
+ if(isdigit(c)) sm->state = state_vhp_F;
+ else if(isprint(c)) sm->state = state_hp_A;
+ else if(c == '\n' || c == '\r') sm->state = state_p;
+ else sm->state = state_error;
+
+ return NOAS;
+}
+
+static accept_state_t state_vhp_F(char c, state_machine_t *sm)
+{
+ if(isdigit(c)) sm->state = state_vhp_F;
+ else if(c == '.') sm->state = state_vhp_G;
+ else if(isprint(c)) sm->state = state_hp_A;
+ else if(c == '\n' || c == '\r') sm->state = state_p;
+ else sm->state = state_error;
+
+ return NOAS;
+}
+
+static accept_state_t state_vhp_G(char c, state_machine_t *sm)
+{
+ if(isdigit(c)) sm->state = state_vhp_H;
+ else if(isprint(c)) sm->state = state_hp_A;
+ else if(c == '\n' || c == '\r') sm->state = state_p;
+ else sm->state = state_error;
+
+ return NOAS;
+}
+
+static accept_state_t state_vhp_H(char c, state_machine_t *sm)
+{
+ if(isdigit(c)) sm->state = state_vhp_H;
+ else if(isblank(c)){
+ sm->token = VERSION;
+ return ASNR;
+
+ }else if(isprint(c)) sm->state = state_hp_A;
+
+ return NOAS;
+}
+
+static accept_state_t state_hp_A(char c, state_machine_t *sm)
+{
+ if(c == ':') sm->state = state_hp_B;
+ else if(c == '\r' || c == '\n') sm->state = state_p;
+ else if(isprint(c)) sm->state = state_hp_A;
+ else sm->state = state_error;
+
+ return NOAS;
+}
+
+static accept_state_t state_hp_B(char c, state_machine_t *sm)
+{
+ if(isblank(c)){
+ sm->token = HEADER;
+ return ASNR;
+ } else if(c == '\r' || c == '\n') sm->state = state_p;
+ else if(c == ':') sm->state = state_hp_B;
+ else if(isprint(c)) sm->state = state_hp_A;
+ else sm->state = state_error;
+
+ return NOAS;
+}
+
+static accept_state_t state_p(char c, state_machine_t *sm)
+{
+ if(c == '\r' || c == '\n'){
+ sm->token = PHRASE;
+ return ASNR;
+ }else if(c == ':') sm->state = state_hp_B;
+ else if(isprint(c)) sm->state = state_hp_A;
+ else sm->state = state_error;
+
+ return NOAS;
+}
+
+static accept_state_t state_error(char c, state_machine_t *sm)
+{
+ c = 0;
+ sm->token = SYNTAX_ERROR;
+
+ return ASNR;
+}
+
+static int read_all(int s, char *buf, size_t len)
+{
+ size_t t;
+ size_t r = ERROR;
+
+ for(t = 0; t < len && r != 0;){
+ r = read(s, buf + t, len - t);
+ if((int)r == ERROR){
+ return ERROR;
+ }else{
+ t += r;
+ }
+ }
+
+ return (int)t;
+}
+
Added: freeswitch/trunk/src/mod/applications/mod_http/http_req.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/src/mod/applications/mod_http/http_req.h Wed Dec 10 16:43:26 2008
@@ -0,0 +1,138 @@
+/*
+ * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
+ * Copyright (C) 2008, Eric des Courtis <eric.des.courtis(a)benbria.com>
+ *
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * Eric des Courtis <eric.des.courtis(a)benbria.com>
+ * Copyright (C) Benbria. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Eric des Courtis <eric.des.courtis(a)benbria.com>
+ *
+ *
+ * http_req.h -- HTTP client implementation
+ *
+ */
+
+#ifndef __HTTP_REQ_H__
+#define __HTTP_REQ_H__
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <signal.h>
+#include <errno.h>
+
+#define ERROR -1
+#define SUCCESS 0
+#define EMPTY_STRING(s) s[0] = '\0'
+
+#define DEFAULT_HTTP_VERSION "1.1"
+#define DEFAULT_HTTP_PORT 80
+
+#define HTTP_GET_METHOD "GET"
+#define HTTP_HEAD_METHOD "HEAD"
+#define HTTP_POST_METHOD "POST"
+#define HTTP_DELETE_METHOD "DELETE"
+#define HTTP_PUT_METHOD "PUT"
+
+#define MAX_PORT_LEN 6
+
+#define RECV_BUFF_SIZE 65536
+
+#define HTTP_TRUE 1
+#define HTTP_FALSE 0
+
+#define INIT_STATE_MACHINE(m) \
+do {\
+ (m)->pos = 0;\
+ (m)->buf = NULL;\
+ (m)->token = SYNTAX_ERROR;\
+ (m)->stop = HTTP_FALSE;\
+ (m)->state = state_start;\
+} while(0)
+
+#define STATUS_CODE_LEN 4
+
+typedef enum tokens {
+ VERSION,
+ STATUS_CODE,
+ PHRASE,
+ HEADER,
+ NEWLINE,
+ SYNTAX_ERROR
+} token_t;
+
+typedef enum accept_states {
+ ASWR,
+ ASNR,
+ NOAS
+} accept_state_t;
+
+typedef struct state_machines {
+ accept_state_t (*state)(char, struct state_machines *);
+ int pos;
+ char *buf;
+ ssize_t buf_len;
+ int stop;
+ token_t token;
+} state_machine_t;
+
+typedef enum http_methods {
+ GET,
+ HEAD,
+ POST,
+ DELETE,
+ PUT
+} http_method_t;
+
+typedef struct http_headers {
+ char *field_name;
+ char *value;
+} http_header_t;
+
+typedef struct http_requests {
+ http_method_t method;
+ char *version;
+ char *url;
+ http_header_t *headers;
+ ssize_t header_len;
+ char *body;
+ ssize_t body_len;
+} http_request_t;
+
+typedef struct http_responses {
+ char *version;
+ int status_code;
+ char *phrase;
+ http_header_t *headers;
+ ssize_t header_len;
+ char *body;
+ int body_len;
+} http_response_t;
+
+token_t get_next_token(state_machine_t *sm);
+int http_parse_response(char *buf, ssize_t buf_len, http_response_t *response);
+int http_req(http_request_t *req, http_response_t *res);
+void free_http_response(http_response_t *response);
+
+#endif
Added: freeswitch/trunk/src/mod/applications/mod_http/json.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/src/mod/applications/mod_http/json.h Wed Dec 10 16:43:26 2008
@@ -0,0 +1,31 @@
+/*
+ * $Id: json.h,v 1.6 2006/01/26 02:16:28 mclark Exp $
+ *
+ * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
+ * Michael Clark <michael(a)metaparadigm.com>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See COPYING for details.
+ *
+ */
+
+#ifndef _json_h_
+#define _json_h_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "bits.h"
+#include "debug.h"
+#include "linkhash.h"
+#include "arraylist.h"
+#include "json_util.h"
+#include "json_object.h"
+#include "json_tokener.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Added: freeswitch/trunk/src/mod/applications/mod_http/json_object.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/src/mod/applications/mod_http/json_object.c Wed Dec 10 16:43:26 2008
@@ -0,0 +1,510 @@
+/*
+ * $Id: json_object.c,v 1.17 2006/07/25 03:24:50 mclark Exp $
+ *
+ * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
+ * Michael Clark <michael(a)metaparadigm.com>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See COPYING for details.
+ *
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "debug.h"
+#include "printbuf.h"
+#include "linkhash.h"
+#include "arraylist.h"
+#include "json_object.h"
+#include "json_object_private.h"
+#include "json_tokener.h"
+
+#if !HAVE_STRNDUP
+
+ char* strndup(const char* str, size_t n);
+
+#endif /* !HAVE_STRNDUP */
+
+/* #define REFCOUNT_DEBUG 1 */
+
+char *json_number_chars = "0123456789.+-e";
+char *json_hex_chars = "0123456789abcdef";
+
+#ifdef REFCOUNT_DEBUG
+static char* json_type_name[] = {
+ "null",
+ "boolean",
+ "double",
+ "int",
+ "object",
+ "array",
+ "string",
+};
+#endif /* REFCOUNT_DEBUG */
+
+static void json_object_generic_delete(struct json_object* this);
+static struct json_object* json_object_new(enum json_type o_type);
+
+
+/* ref count debugging */
+
+#ifdef REFCOUNT_DEBUG
+
+static struct lh_table *json_object_table;
+
+static void json_object_init() __attribute__ ((constructor));
+static void json_object_init() {
+ mc_debug("json_object_init: creating object table\n");
+ json_object_table = lh_kptr_table_new(128, "json_object_table", NULL);
+}
+
+static void json_object_fini() __attribute__ ((destructor));
+static void json_object_fini() {
+ struct lh_entry *ent;
+ if(mc_get_debug() && json_object_table->count) {
+ mc_debug("json_object_fini: %d referenced objects at exit\n",
+ json_object_table->count);
+ lh_foreach(json_object_table, ent) {
+ struct json_object* obj = (struct json_object*)ent->v;
+ mc_debug("\t%s:%p\n", json_type_name[obj->o_type], obj);
+ }
+ }
+ mc_debug("json_object_fini: freeing object table\n");
+ lh_table_free(json_object_table);
+}
+#endif /* REFCOUNT_DEBUG */
+
+
+/* string escaping */
+
+static int json_escape_str(struct printbuf *pb, char *str)
+{
+ int pos = 0, start_offset = 0;
+ unsigned char c;
+ do {
+ c = str[pos];
+ switch(c) {
+ case '\0':
+ break;
+ case '\b':
+ case '\n':
+ case '\r':
+ case '\t':
+ case '"':
+ case '\\':
+ case '/':
+ if(pos - start_offset > 0)
+ printbuf_memappend(pb, str + start_offset, pos - start_offset);
+ if(c == '\b') printbuf_memappend(pb, "\\b", 2);
+ else if(c == '\n') printbuf_memappend(pb, "\\n", 2);
+ else if(c == '\r') printbuf_memappend(pb, "\\r", 2);
+ else if(c == '\t') printbuf_memappend(pb, "\\t", 2);
+ else if(c == '"') printbuf_memappend(pb, "\\\"", 2);
+ else if(c == '\\') printbuf_memappend(pb, "\\\\", 2);
+ else if(c == '/') printbuf_memappend(pb, "\\/", 2);
+ start_offset = ++pos;
+ break;
+ default:
+ if(c < ' ') {
+ if(pos - start_offset > 0)
+ printbuf_memappend(pb, str + start_offset, pos - start_offset);
+ sprintbuf(pb, "\\u00%c%c",
+ json_hex_chars[c >> 4],
+ json_hex_chars[c & 0xf]);
+ start_offset = ++pos;
+ } else pos++;
+ }
+ } while(c);
+ if(pos - start_offset > 0)
+ printbuf_memappend(pb, str + start_offset, pos - start_offset);
+ return 0;
+}
+
+
+/* reference counting */
+
+extern struct json_object* json_object_get(struct json_object *this)
+{
+ if(this) {
+ this->_ref_count++;
+ }
+ return this;
+}
+
+extern void json_object_put(struct json_object *this)
+{
+ if(this) {
+ this->_ref_count--;
+ if(!this->_ref_count) this->_delete(this);
+ }
+}
+
+
+/* generic object construction and destruction parts */
+
+static void json_object_generic_delete(struct json_object* this)
+{
+#ifdef REFCOUNT_DEBUG
+ mc_debug("json_object_delete_%s: %p\n",
+ json_type_name[this->o_type], this);
+ lh_table_delete(json_object_table, this);
+#endif /* REFCOUNT_DEBUG */
+ printbuf_free(this->_pb);
+ free(this);
+}
+
+static struct json_object* json_object_new(enum json_type o_type)
+{
+ struct json_object *this = calloc(sizeof(struct json_object), 1);
+ if(!this) return NULL;
+ this->o_type = o_type;
+ this->_ref_count = 1;
+ this->_delete = &json_object_generic_delete;
+#ifdef REFCOUNT_DEBUG
+ lh_table_insert(json_object_table, this, this);
+ mc_debug("json_object_new_%s: %p\n", json_type_name[this->o_type], this);
+#endif /* REFCOUNT_DEBUG */
+ return this;
+}
+
+
+/* type checking functions */
+
+int json_object_is_type(struct json_object *this, enum json_type type)
+{
+ return (this->o_type == type);
+}
+
+enum json_type json_object_get_type(struct json_object *this)
+{
+ return this->o_type;
+}
+
+
+/* json_object_to_json_string */
+
+char* json_object_to_json_string(struct json_object *this)
+{
+ if(!this) return "null";
+ if(!this->_pb) {
+ if(!(this->_pb = printbuf_new())) return NULL;
+ } else {
+ printbuf_reset(this->_pb);
+ }
+ if(this->_to_json_string(this, this->_pb) < 0) return NULL;
+ return this->_pb->buf;
+}
+
+
+/* json_object_object */
+
+static int json_object_object_to_json_string(struct json_object* this,
+ struct printbuf *pb)
+{
+ int i=0;
+ struct json_object_iter iter;
+ sprintbuf(pb, "{");
+
+ /* CAW: scope operator to make ANSI correctness */
+ /* CAW: switched to json_object_object_foreachC which uses an iterator struct */
+ json_object_object_foreachC(this, iter) {
+ if(i) sprintbuf(pb, ",");
+ sprintbuf(pb, " \"");
+ json_escape_str(pb, iter.key);
+ sprintbuf(pb, "\": ");
+ if(iter.val == NULL) sprintbuf(pb, "null");
+ else iter.val->_to_json_string(iter.val, pb);
+ i++;
+ }
+
+ return sprintbuf(pb, " }");
+}
+
+static void json_object_lh_entry_free(struct lh_entry *ent)
+{
+ free(ent->k);
+ json_object_put((struct json_object*)ent->v);
+}
+
+static void json_object_object_delete(struct json_object* this)
+{
+ lh_table_free(this->o.c_object);
+ json_object_generic_delete(this);
+}
+
+struct json_object* json_object_new_object()
+{
+ struct json_object *this = json_object_new(json_type_object);
+ if(!this) return NULL;
+ this->_delete = &json_object_object_delete;
+ this->_to_json_string = &json_object_object_to_json_string;
+ this->o.c_object = lh_kchar_table_new(JSON_OBJECT_DEF_HASH_ENTIRES,
+ NULL, &json_object_lh_entry_free);
+ return this;
+}
+
+struct lh_table* json_object_get_object(struct json_object *this)
+{
+ if(!this) return NULL;
+ switch(this->o_type) {
+ case json_type_object:
+ return this->o.c_object;
+ default:
+ return NULL;
+ }
+}
+
+void json_object_object_add(struct json_object* this, char *key,
+ struct json_object *val)
+{
+ lh_table_delete(this->o.c_object, key);
+ lh_table_insert(this->o.c_object, strdup(key), val);
+}
+
+struct json_object* json_object_object_get(struct json_object* this, char *key)
+{
+ return (struct json_object*) lh_table_lookup(this->o.c_object, key);
+}
+
+void json_object_object_del(struct json_object* this, char *key)
+{
+ lh_table_delete(this->o.c_object, key);
+}
+
+
+/* json_object_boolean */
+
+static int json_object_boolean_to_json_string(struct json_object* this,
+ struct printbuf *pb)
+{
+ if(this->o.c_boolean) return sprintbuf(pb, "true");
+ else return sprintbuf(pb, "false");
+}
+
+struct json_object* json_object_new_boolean(boolean b)
+{
+ struct json_object *this = json_object_new(json_type_boolean);
+ if(!this) return NULL;
+ this->_to_json_string = &json_object_boolean_to_json_string;
+ this->o.c_boolean = b;
+ return this;
+}
+
+boolean json_object_get_boolean(struct json_object *this)
+{
+ if(!this) return FALSE;
+ switch(this->o_type) {
+ case json_type_boolean:
+ return this->o.c_boolean;
+ case json_type_int:
+ return (this->o.c_int != 0);
+ case json_type_double:
+ return (this->o.c_double != 0);
+ case json_type_string:
+ if(strlen(this->o.c_string)) return TRUE;
+ default:
+ return TRUE;
+ }
+}
+
+
+/* json_object_int */
+
+static int json_object_int_to_json_string(struct json_object* this,
+ struct printbuf *pb)
+{
+ return sprintbuf(pb, "%d", this->o.c_int);
+}
+
+struct json_object* json_object_new_int(int i)
+{
+ struct json_object *this = json_object_new(json_type_int);
+ if(!this) return NULL;
+ this->_to_json_string = &json_object_int_to_json_string;
+ this->o.c_int = i;
+ return this;
+}
+
+int json_object_get_int(struct json_object *this)
+{
+ int cint;
+
+ if(!this) return 0;
+ switch(this->o_type) {
+ case json_type_int:
+ return this->o.c_int;
+ case json_type_double:
+ return (int)this->o.c_double;
+ case json_type_boolean:
+ return this->o.c_boolean;
+ case json_type_string:
+ if(sscanf(this->o.c_string, "%d", &cint) == 1) return cint;
+ default:
+ return 0;
+ }
+}
+
+
+/* json_object_double */
+
+static int json_object_double_to_json_string(struct json_object* this,
+ struct printbuf *pb)
+{
+ return sprintbuf(pb, "%lf", this->o.c_double);
+}
+
+struct json_object* json_object_new_double(double d)
+{
+ struct json_object *this = json_object_new(json_type_double);
+ if(!this) return NULL;
+ this->_to_json_string = &json_object_double_to_json_string;
+ this->o.c_double = d;
+ return this;
+}
+
+double json_object_get_double(struct json_object *this)
+{
+ double cdouble;
+
+ if(!this) return 0.0;
+ switch(this->o_type) {
+ case json_type_double:
+ return this->o.c_double;
+ case json_type_int:
+ return this->o.c_int;
+ case json_type_boolean:
+ return this->o.c_boolean;
+ case json_type_string:
+ if(sscanf(this->o.c_string, "%lf", &cdouble) == 1) return cdouble;
+ default:
+ return 0.0;
+ }
+}
+
+
+/* json_object_string */
+
+static int json_object_string_to_json_string(struct json_object* this,
+ struct printbuf *pb)
+{
+ sprintbuf(pb, "\"");
+ json_escape_str(pb, this->o.c_string);
+ sprintbuf(pb, "\"");
+ return 0;
+}
+
+static void json_object_string_delete(struct json_object* this)
+{
+ free(this->o.c_string);
+ json_object_generic_delete(this);
+}
+
+struct json_object* json_object_new_string(char *s)
+{
+ struct json_object *this = json_object_new(json_type_string);
+ if(!this) return NULL;
+ this->_delete = &json_object_string_delete;
+ this->_to_json_string = &json_object_string_to_json_string;
+ this->o.c_string = strdup(s);
+ return this;
+}
+
+struct json_object* json_object_new_string_len(char *s, int len)
+{
+ struct json_object *this = json_object_new(json_type_string);
+ if(!this) return NULL;
+ this->_delete = &json_object_string_delete;
+ this->_to_json_string = &json_object_string_to_json_string;
+ this->o.c_string = strndup(s, len);
+ return this;
+}
+
+char* json_object_get_string(struct json_object *this)
+{
+ if(!this) return NULL;
+ switch(this->o_type) {
+ case json_type_string:
+ return this->o.c_string;
+ default:
+ return json_object_to_json_string(this);
+ }
+}
+
+
+/* json_object_array */
+
+static int json_object_array_to_json_string(struct json_object* this,
+ struct printbuf *pb)
+{
+ int i;
+ sprintbuf(pb, "[");
+ for(i=0; i < json_object_array_length(this); i++) {
+ struct json_object *val;
+ if(i) { sprintbuf(pb, ", "); }
+ else { sprintbuf(pb, " "); }
+
+ val = json_object_array_get_idx(this, i);
+ if(val == NULL) { sprintbuf(pb, "null"); }
+ else { val->_to_json_string(val, pb); }
+ }
+ return sprintbuf(pb, " ]");
+}
+
+static void json_object_array_entry_free(void *data)
+{
+ json_object_put((struct json_object*)data);
+}
+
+static void json_object_array_delete(struct json_object* this)
+{
+ array_list_free(this->o.c_array);
+ json_object_generic_delete(this);
+}
+
+struct json_object* json_object_new_array()
+{
+ struct json_object *this = json_object_new(json_type_array);
+ if(!this) return NULL;
+ this->_delete = &json_object_array_delete;
+ this->_to_json_string = &json_object_array_to_json_string;
+ this->o.c_array = array_list_new(&json_object_array_entry_free);
+ return this;
+}
+
+struct array_list* json_object_get_array(struct json_object *this)
+{
+ if(!this) return NULL;
+ switch(this->o_type) {
+ case json_type_array:
+ return this->o.c_array;
+ default:
+ return NULL;
+ }
+}
+
+int json_object_array_length(struct json_object *this)
+{
+ return array_list_length(this->o.c_array);
+}
+
+int json_object_array_add(struct json_object *this,struct json_object *val)
+{
+ return array_list_add(this->o.c_array, val);
+}
+
+int json_object_array_put_idx(struct json_object *this, int idx,
+ struct json_object *val)
+{
+ return array_list_put_idx(this->o.c_array, idx, val);
+}
+
+struct json_object* json_object_array_get_idx(struct json_object *this,
+ int idx)
+{
+ return (struct json_object*)array_list_get_idx(this->o.c_array, idx);
+}
+
Added: freeswitch/trunk/src/mod/applications/mod_http/json_object.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/src/mod/applications/mod_http/json_object.h Wed Dec 10 16:43:26 2008
@@ -0,0 +1,308 @@
+/*
+ * $Id: json_object.h,v 1.12 2006/01/30 23:07:57 mclark Exp $
+ *
+ * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
+ * Michael Clark <michael(a)metaparadigm.com>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See COPYING for details.
+ *
+ */
+
+#ifndef _json_object_h_
+#define _json_object_h_
+
+#define JSON_OBJECT_DEF_HASH_ENTIRES 16
+
+#undef FALSE
+#define FALSE ((boolean)0)
+
+#undef TRUE
+#define TRUE ((boolean)1)
+
+extern char *json_number_chars;
+extern char *json_hex_chars;
+
+/* forward structure definitions */
+
+typedef int boolean;
+struct printbuf;
+struct lh_table;
+struct array_list;
+struct json_object;
+struct json_object_iter;
+
+/* supported object types */
+
+enum json_type {
+ json_type_null,
+ json_type_boolean,
+ json_type_double,
+ json_type_int,
+ json_type_object,
+ json_type_array,
+ json_type_string
+};
+
+/* reference counting functions */
+
+/**
+ * Increment the reference count of json_object
+ * @param obj the json_object instance
+ */
+extern struct json_object* json_object_get(struct json_object *obj);
+
+/**
+ * Decrement the reference count of json_object and free if it reaches zero
+ * @param obj the json_object instance
+ */
+extern void json_object_put(struct json_object *obj);
+
+
+/**
+ * Check if the json_object is of a given type
+ * @param obj the json_object instance
+ * @param type one of:
+ json_type_boolean,
+ json_type_double,
+ json_type_int,
+ json_type_object,
+ json_type_array,
+ json_type_string,
+ */
+extern int json_object_is_type(struct json_object *obj, enum json_type type);
+
+/**
+ * Get the type of the json_object
+ * @param obj the json_object instance
+ * @returns type being one of:
+ json_type_boolean,
+ json_type_double,
+ json_type_int,
+ json_type_object,
+ json_type_array,
+ json_type_string,
+ */
+extern enum json_type json_object_get_type(struct json_object *obj);
+
+
+/** Stringify object to json format
+ * @param obj the json_object instance
+ * @returns a string in JSON format
+ */
+extern char* json_object_to_json_string(struct json_object *obj);
+
+
+/* object type methods */
+
+/** Create a new empty object
+ * @returns a json_object of type json_type_object
+ */
+extern struct json_object* json_object_new_object();
+
+/** Get the hashtable of a json_object of type json_type_object
+ * @param obj the json_object instance
+ * @returns a linkhash
+ */
+extern struct lh_table* json_object_get_object(struct json_object *obj);
+
+/** Add an object field to a json_object of type json_type_object
+ *
+ * The reference count will *not* be incremented. This is to make adding
+ * fields to objects in code more compact. If you want to retain a reference
+ * to an added object you must wrap the passed object with json_object_get
+ *
+ * @param obj the json_object instance
+ * @param key the object field name (a private copy will be duplicated)
+ * @param val a json_object or NULL member to associate with the given field
+ */
+extern void json_object_object_add(struct json_object* obj, char *key,
+ struct json_object *val);
+
+/** Get the json_object associate with a given object field
+ * @param obj the json_object instance
+ * @param key the object field name
+ * @returns the json_object associated with the given field name
+ */
+extern struct json_object* json_object_object_get(struct json_object* obj,
+ char *key);
+
+/** Delete the given json_object field
+ *
+ * The reference count will be decremented for the deleted object
+ *
+ * @param obj the json_object instance
+ * @param key the object field name
+ */
+extern void json_object_object_del(struct json_object* obj, char *key);
+
+/** Iterate through all keys and values of an object
+ * @param obj the json_object instance
+ * @param key the local name for the char* key variable defined in the body
+ * @param val the local name for the json_object* object variable defined in the body
+ */
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
+
+# define json_object_object_foreach(obj,key,val) \
+ for(entry = json_object_get_object(obj)->head; ({ if(entry) { key = (char*)entry->k; val = (struct json_object*)entry->v; } ; entry; }); entry = entry->next )
+
+#else /* ANSI C or MSC */
+
+# define json_object_object_foreach(obj,key,val) \
+ for(entry = json_object_get_object(obj)->head; (entry ? (key = (char*)entry->k, val = (struct json_object*)entry->v, entry) : 0); entry = entry->next)
+
+#endif /* defined(__GNUC__) && !defined(__STRICT_ANSI__) */
+
+/** Iterate through all keys and values of an object (ANSI C Safe)
+ * @param obj the json_object instance
+ * @param iter the object iterator
+ */
+#define json_object_object_foreachC(obj,iter) \
+ for(iter.entry = json_object_get_object(obj)->head; (iter.entry ? (iter.key = (char*)iter.entry->k, iter.val = (struct json_object*)iter.entry->v, iter.entry) : 0); iter.entry = iter.entry->next)
+
+/* Array type methods */
+
+/** Create a new empty json_object of type json_type_array
+ * @returns a json_object of type json_type_array
+ */
+extern struct json_object* json_object_new_array();
+
+/** Get the arraylist of a json_object of type json_type_array
+ * @param obj the json_object instance
+ * @returns an arraylist
+ */
+extern struct array_list* json_object_get_array(struct json_object *obj);
+
+/** Get the length of a json_object of type json_type_array
+ * @param obj the json_object instance
+ * @returns an int
+ */
+extern int json_object_array_length(struct json_object *obj);
+
+/** Add an element to the end of a json_object of type json_type_array
+ *
+ * The reference count will *not* be incremented. This is to make adding
+ * fields to objects in code more compact. If you want to retain a reference
+ * to an added object you must wrap the passed object with json_object_get
+ *
+ * @param obj the json_object instance
+ * @param val the json_object to be added
+ */
+extern int json_object_array_add(struct json_object *obj,
+ struct json_object *val);
+
+/** Insert or replace an element at a specified index in an array (a json_object of type json_type_array)
+ *
+ * The reference count will *not* be incremented. This is to make adding
+ * fields to objects in code more compact. If you want to retain a reference
+ * to an added object you must wrap the passed object with json_object_get
+ *
+ * The reference count of a replaced object will be decremented.
+ *
+ * The array size will be automatically be expanded to the size of the
+ * index if the index is larger than the current size.
+ *
+ * @param obj the json_object instance
+ * @param idx the index to insert the element at
+ * @param val the json_object to be added
+ */
+extern int json_object_array_put_idx(struct json_object *obj, int idx,
+ struct json_object *val);
+
+/** Get the element at specificed index of the array (a json_object of type json_type_array)
+ * @param obj the json_object instance
+ * @param idx the index to get the element at
+ * @returns the json_object at the specified index (or NULL)
+ */
+extern struct json_object* json_object_array_get_idx(struct json_object *obj,
+ int idx);
+
+/* boolean type methods */
+
+/** Create a new empty json_object of type json_type_boolean
+ * @param b a boolean TRUE or FALSE (0 or 1)
+ * @returns a json_object of type json_type_boolean
+ */
+extern struct json_object* json_object_new_boolean(boolean b);
+
+/** Get the boolean value of a json_object
+ *
+ * The type is coerced to a boolean if the passed object is not a boolean.
+ * integer and double objects will return FALSE if there value is zero
+ * or TRUE otherwise. If the passed object is a string it will return
+ * TRUE if it has a non zero length. If any other object type is passed
+ * TRUE will be returned if the object is not NULL.
+ *
+ * @param obj the json_object instance
+ * @returns a boolean
+ */
+extern boolean json_object_get_boolean(struct json_object *obj);
+
+
+/* int type methods */
+
+/** Create a new empty json_object of type json_type_int
+ * @param i the integer
+ * @returns a json_object of type json_type_int
+ */
+extern struct json_object* json_object_new_int(int i);
+
+/** Get the int value of a json_object
+ *
+ * The type is coerced to a int if the passed object is not a int.
+ * double objects will return their integer conversion. Strings will be
+ * parsed as an integer. If no conversion exists then 0 is returned.
+ *
+ * @param obj the json_object instance
+ * @returns an int
+ */
+extern int json_object_get_int(struct json_object *obj);
+
+
+/* double type methods */
+
+/** Create a new empty json_object of type json_type_double
+ * @param d the double
+ * @returns a json_object of type json_type_double
+ */
+extern struct json_object* json_object_new_double(double d);
+
+/** Get the double value of a json_object
+ *
+ * The type is coerced to a double if the passed object is not a double.
+ * integer objects will return their dboule conversion. Strings will be
+ * parsed as a double. If no conversion exists then 0.0 is returned.
+ *
+ * @param obj the json_object instance
+ * @returns an double
+ */
+extern double json_object_get_double(struct json_object *obj);
+
+
+/* string type methods */
+
+/** Create a new empty json_object of type json_type_string
+ *
+ * A copy of the string is made and the memory is managed by the json_object
+ *
+ * @param s the string
+ * @returns a json_object of type json_type_string
+ */
+extern struct json_object* json_object_new_string(char *s);
+
+extern struct json_object* json_object_new_string_len(char *s, int len);
+
+/** Get the string value of a json_object
+ *
+ * If the passed object is not of type json_type_string then the JSON
+ * representation of the object is returned.
+ *
+ * The returned string memory is managed by the json_object and will
+ * be freed when the reference count of the json_object drops to zero.
+ *
+ * @param obj the json_object instance
+ * @returns a string
+ */
+extern char* json_object_get_string(struct json_object *obj);
+
+#endif
Added: freeswitch/trunk/src/mod/applications/mod_http/json_object_private.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/src/mod/applications/mod_http/json_object_private.h Wed Dec 10 16:43:26 2008
@@ -0,0 +1,44 @@
+/*
+ * $Id: json_object_private.h,v 1.4 2006/01/26 02:16:28 mclark Exp $
+ *
+ * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
+ * Michael Clark <michael(a)metaparadigm.com>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See COPYING for details.
+ *
+ */
+
+#ifndef _json_object_private_h_
+#define _json_object_private_h_
+
+typedef void (json_object_delete_fn)(struct json_object *o);
+typedef int (json_object_to_json_string_fn)(struct json_object *o,
+ struct printbuf *pb);
+
+struct json_object
+{
+ enum json_type o_type;
+ json_object_delete_fn *_delete;
+ json_object_to_json_string_fn *_to_json_string;
+ int _ref_count;
+ struct printbuf *_pb;
+ union data {
+ boolean c_boolean;
+ double c_double;
+ int c_int;
+ struct lh_table *c_object;
+ struct array_list *c_array;
+ char *c_string;
+ } o;
+};
+
+/* CAW: added for ANSI C iteration correctness */
+struct json_object_iter
+{
+ char *key;
+ struct json_object *val;
+ struct lh_entry *entry;
+};
+
+#endif
Added: freeswitch/trunk/src/mod/applications/mod_http/json_tokener.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/src/mod/applications/mod_http/json_tokener.c Wed Dec 10 16:43:26 2008
@@ -0,0 +1,520 @@
+/*
+ * $Id: json_tokener.c,v 1.20 2006/07/25 03:24:50 mclark Exp $
+ *
+ * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
+ * Michael Clark <michael(a)metaparadigm.com>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See COPYING for details.
+ *
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+
+#include "bits.h"
+#include "debug.h"
+#include "printbuf.h"
+#include "arraylist.h"
+#include "json_object.h"
+#include "json_tokener.h"
+
+
+#if !HAVE_STRNCASECMP && defined(_MSC_VER)
+ /* MSC has the version as _strnicmp */
+# define strncasecmp _strnicmp
+#elif !HAVE_STRNCASECMP
+# error You do not have strncasecmp on your system.
+#endif /* HAVE_STRNCASECMP */
+
+
+static const char* json_null_str = "null";
+static const char* json_true_str = "true";
+static const char* json_false_str = "false";
+
+const char* json_tokener_errors[] = {
+ "success",
+ "continue",
+ "nesting to deep",
+ "unexpected end of data",
+ "unexpected character",
+ "null expected",
+ "boolean expected",
+ "number expected",
+ "array value separator ',' expected",
+ "quoted object property name expected",
+ "object property name separator ':' expected",
+ "object value separator ',' expected",
+ "invalid string sequence",
+ "expected comment",
+};
+
+
+struct json_tokener* json_tokener_new()
+{
+ struct json_tokener *tok = calloc(1, sizeof(struct json_tokener));
+ tok->pb = printbuf_new();
+ json_tokener_reset(tok);
+ return tok;
+}
+
+void json_tokener_free(struct json_tokener *tok)
+{
+ json_tokener_reset(tok);
+ if(tok) printbuf_free(tok->pb);
+ free(tok);
+}
+
+static void json_tokener_reset_level(struct json_tokener *tok, int depth)
+{
+ tok->stack[depth].state = json_tokener_state_eatws;
+ tok->stack[depth].saved_state = json_tokener_state_start;
+ json_object_put(tok->stack[depth].current);
+ tok->stack[depth].current = NULL;
+ free(tok->stack[depth].obj_field_name);
+ tok->stack[depth].obj_field_name = NULL;
+}
+
+void json_tokener_reset(struct json_tokener *tok)
+{
+ int i;
+ for(i = tok->depth; i >= 0; i--)
+ json_tokener_reset_level(tok, i);
+ tok->depth = 0;
+ tok->err = json_tokener_success;
+}
+
+struct json_object* json_tokener_parse(char *str)
+{
+ struct json_tokener* tok;
+ struct json_object* obj;
+
+ tok = json_tokener_new();
+ obj = json_tokener_parse_ex(tok, str, -1);
+ if(tok->err != json_tokener_success)
+ obj = error_ptr(-tok->err);
+ json_tokener_free(tok);
+ return obj;
+}
+
+
+#if !HAVE_STRNDUP
+/* CAW: compliant version of strndup() */
+char* strndup(const char* str, size_t n)
+{
+ if(str) {
+ size_t len = strlen(str);
+ size_t nn = min(len,n);
+ char* s = (char*)malloc(sizeof(char) * (nn + 1));
+
+ if(s) {
+ memcpy(s, str, nn);
+ s[nn] = '\0';
+ }
+
+ return s;
+ }
+
+ return NULL;
+}
+#endif
+
+
+#define state tok->stack[tok->depth].state
+#define saved_state tok->stack[tok->depth].saved_state
+#define current tok->stack[tok->depth].current
+#define obj_field_name tok->stack[tok->depth].obj_field_name
+
+struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
+ char *str, int len)
+{
+ struct json_object *obj = NULL;
+ char c;
+
+ tok->char_offset = 0;
+ tok->err = json_tokener_success;
+
+ do {
+ if(tok->char_offset == len) {
+ if(tok->depth == 0 && state == json_tokener_state_eatws &&
+ saved_state == json_tokener_state_finish)
+ tok->err = json_tokener_success;
+ else
+ tok->err = json_tokener_continue;
+ goto out;
+ }
+
+ c = *str;
+ redo_char:
+ switch(state) {
+
+ case json_tokener_state_eatws:
+ if(isspace(c)) {
+ /* okay */
+ } else if(c == '/') {
+ printbuf_reset(tok->pb);
+ printbuf_memappend(tok->pb, &c, 1);
+ state = json_tokener_state_comment_start;
+ } else {
+ state = saved_state;
+ goto redo_char;
+ }
+ break;
+
+ case json_tokener_state_start:
+ switch(c) {
+ case '{':
+ state = json_tokener_state_eatws;
+ saved_state = json_tokener_state_object_field_start;
+ current = json_object_new_object();
+ break;
+ case '[':
+ state = json_tokener_state_eatws;
+ saved_state = json_tokener_state_array;
+ current = json_object_new_array();
+ break;
+ case 'N':
+ case 'n':
+ state = json_tokener_state_null;
+ printbuf_reset(tok->pb);
+ tok->st_pos = 0;
+ goto redo_char;
+ case '"':
+ case '\'':
+ state = json_tokener_state_string;
+ printbuf_reset(tok->pb);
+ tok->quote_char = c;
+ break;
+ case 'T':
+ case 't':
+ case 'F':
+ case 'f':
+ state = json_tokener_state_boolean;
+ printbuf_reset(tok->pb);
+ tok->st_pos = 0;
+ goto redo_char;
+/*
+#if defined(__GNUC__)
+ case '0' ... '9':
+#else
+*/
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+/*
+#endif
+*/
+ case '-':
+ state = json_tokener_state_number;
+ printbuf_reset(tok->pb);
+ tok->is_double = 0;
+ goto redo_char;
+ default:
+ tok->err = json_tokener_error_parse_unexpected;
+ goto out;
+ }
+ break;
+
+ case json_tokener_state_finish:
+ if(tok->depth == 0) goto out;
+ obj = json_object_get(current);
+ json_tokener_reset_level(tok, tok->depth);
+ tok->depth--;
+ goto redo_char;
+
+ case json_tokener_state_null:
+ printbuf_memappend(tok->pb, &c, 1);
+ if(strncasecmp(json_null_str, tok->pb->buf,
+ min(tok->st_pos+1, strlen(json_null_str))) == 0) {
+ if(tok->st_pos == strlen(json_null_str)) {
+ current = NULL;
+ saved_state = json_tokener_state_finish;
+ state = json_tokener_state_eatws;
+ goto redo_char;
+ }
+ } else {
+ tok->err = json_tokener_error_parse_null;
+ goto out;
+ }
+ tok->st_pos++;
+ break;
+
+ case json_tokener_state_comment_start:
+ if(c == '*') {
+ state = json_tokener_state_comment;
+ } else if(c == '/') {
+ state = json_tokener_state_comment_eol;
+ } else {
+ tok->err = json_tokener_error_parse_comment;
+ goto out;
+ }
+ printbuf_memappend(tok->pb, &c, 1);
+ break;
+
+ case json_tokener_state_comment:
+ if(c == '*') state = json_tokener_state_comment_end;
+ printbuf_memappend(tok->pb, &c, 1);
+ break;
+
+ case json_tokener_state_comment_eol:
+ if(c == '\n') {
+ mc_debug("json_tokener_comment: %s\n", tok->pb->buf);
+ state = json_tokener_state_eatws;
+ } else {
+ printbuf_memappend(tok->pb, &c, 1);
+ }
+ break;
+
+ case json_tokener_state_comment_end:
+ printbuf_memappend(tok->pb, &c, 1);
+ if(c == '/') {
+ mc_debug("json_tokener_comment: %s\n", tok->pb->buf);
+ state = json_tokener_state_eatws;
+ } else {
+ state = json_tokener_state_comment;
+ }
+ break;
+
+ case json_tokener_state_string:
+ if(c == tok->quote_char) {
+ current = json_object_new_string(tok->pb->buf);
+ saved_state = json_tokener_state_finish;
+ state = json_tokener_state_eatws;
+ } else if(c == '\\') {
+ saved_state = json_tokener_state_string;
+ state = json_tokener_state_string_escape;
+ } else {
+ printbuf_memappend(tok->pb, &c, 1);
+ }
+ break;
+
+ case json_tokener_state_string_escape:
+ switch(c) {
+ case '"':
+ case '\\':
+ case '/':
+ printbuf_memappend(tok->pb, &c, 1);
+ state = saved_state;
+ break;
+ case 'b':
+ case 'n':
+ case 'r':
+ case 't':
+ if(c == 'b') printbuf_memappend(tok->pb, "\b", 1);
+ else if(c == 'n') printbuf_memappend(tok->pb, "\n", 1);
+ else if(c == 'r') printbuf_memappend(tok->pb, "\r", 1);
+ else if(c == 't') printbuf_memappend(tok->pb, "\t", 1);
+ state = saved_state;
+ break;
+ case 'u':
+ tok->ucs_char = 0;
+ tok->st_pos = 0;
+ state = json_tokener_state_escape_unicode;
+ break;
+ default:
+ tok->err = json_tokener_error_parse_string;
+ goto out;
+ }
+ break;
+
+ case json_tokener_state_escape_unicode:
+ if(strchr(json_hex_chars, c)) {
+ tok->ucs_char += ((unsigned int)hexdigit(c) << ((3-tok->st_pos++)*4));
+ if(tok->st_pos == 4) {
+ unsigned char utf_out[3];
+ if (tok->ucs_char < 0x80) {
+ utf_out[0] = tok->ucs_char;
+ printbuf_memappend(tok->pb, (char*)utf_out, 1);
+ } else if (tok->ucs_char < 0x800) {
+ utf_out[0] = 0xc0 | (tok->ucs_char >> 6);
+ utf_out[1] = 0x80 | (tok->ucs_char & 0x3f);
+ printbuf_memappend(tok->pb, (char*)utf_out, 2);
+ } else {
+ utf_out[0] = 0xe0 | (tok->ucs_char >> 12);
+ utf_out[1] = 0x80 | ((tok->ucs_char >> 6) & 0x3f);
+ utf_out[2] = 0x80 | (tok->ucs_char & 0x3f);
+ printbuf_memappend(tok->pb, (char*)utf_out, 3);
+ }
+ state = saved_state;
+ }
+ } else {
+ tok->err = json_tokener_error_parse_string;
+ goto out;
+ }
+ break;
+
+ case json_tokener_state_boolean:
+ printbuf_memappend(tok->pb, &c, 1);
+ if(strncasecmp(json_true_str, tok->pb->buf,
+ min(tok->st_pos+1, strlen(json_true_str))) == 0) {
+ if(tok->st_pos == strlen(json_true_str)) {
+ current = json_object_new_boolean(1);
+ saved_state = json_tokener_state_finish;
+ state = json_tokener_state_eatws;
+ goto redo_char;
+ }
+ } else if(strncasecmp(json_false_str, tok->pb->buf,
+ min(tok->st_pos+1, strlen(json_false_str))) == 0) {
+ if(tok->st_pos == strlen(json_false_str)) {
+ current = json_object_new_boolean(0);
+ saved_state = json_tokener_state_finish;
+ state = json_tokener_state_eatws;
+ goto redo_char;
+ }
+ } else {
+ tok->err = json_tokener_error_parse_boolean;
+ goto out;
+ }
+ tok->st_pos++;
+ break;
+
+ case json_tokener_state_number:
+ if(c && strchr(json_number_chars, c)) {
+ printbuf_memappend(tok->pb, &c, 1);
+ if(c == '.' || c == 'e') tok->is_double = 1;
+ } else {
+ int numi;
+ double numd;
+ if(!tok->is_double && sscanf(tok->pb->buf, "%d", &numi) == 1) {
+ current = json_object_new_int(numi);
+ } else if(tok->is_double && sscanf(tok->pb->buf, "%lf", &numd) == 1) {
+ current = json_object_new_double(numd);
+ } else {
+ tok->err = json_tokener_error_parse_number;
+ goto out;
+ }
+ saved_state = json_tokener_state_finish;
+ state = json_tokener_state_eatws;
+ goto redo_char;
+ }
+ break;
+
+ case json_tokener_state_array:
+ if(c == ']') {
+ saved_state = json_tokener_state_finish;
+ state = json_tokener_state_eatws;
+ } else {
+ if(tok->depth >= JSON_TOKENER_MAX_DEPTH-1) {
+ tok->err = json_tokener_error_depth;
+ goto out;
+ }
+ state = json_tokener_state_array_add;
+ tok->depth++;
+ json_tokener_reset_level(tok, tok->depth);
+ goto redo_char;
+ }
+ break;
+
+ case json_tokener_state_array_add:
+ json_object_array_add(current, obj);
+ saved_state = json_tokener_state_array_sep;
+ state = json_tokener_state_eatws;
+ goto redo_char;
+
+ case json_tokener_state_array_sep:
+ if(c == ']') {
+ saved_state = json_tokener_state_finish;
+ state = json_tokener_state_eatws;
+ } else if(c == ',') {
+ saved_state = json_tokener_state_array;
+ state = json_tokener_state_eatws;
+ } else {
+ tok->err = json_tokener_error_parse_array;
+ goto out;
+ }
+ break;
+
+ case json_tokener_state_object_field_start:
+ if(c == '}') {
+ saved_state = json_tokener_state_finish;
+ state = json_tokener_state_eatws;
+ } else if (c == '"' || c == '\'') {
+ tok->quote_char = c;
+ printbuf_reset(tok->pb);
+ state = json_tokener_state_object_field;
+ } else {
+ tok->err = json_tokener_error_parse_object_key_name;
+ goto out;
+ }
+ break;
+
+ case json_tokener_state_object_field:
+ if(c == tok->quote_char) {
+ obj_field_name = strdup(tok->pb->buf);
+ saved_state = json_tokener_state_object_field_end;
+ state = json_tokener_state_eatws;
+ } else if(c == '\\') {
+ saved_state = json_tokener_state_object_field;
+ state = json_tokener_state_string_escape;
+ } else {
+ printbuf_memappend(tok->pb, &c, 1);
+ }
+ break;
+
+ case json_tokener_state_object_field_end:
+ if(c == ':') {
+ saved_state = json_tokener_state_object_value;
+ state = json_tokener_state_eatws;
+ } else {
+ tok->err = json_tokener_error_parse_object_key_sep;
+ goto out;
+ }
+ break;
+
+ case json_tokener_state_object_value:
+ if(tok->depth >= JSON_TOKENER_MAX_DEPTH-1) {
+ tok->err = json_tokener_error_depth;
+ goto out;
+ }
+ state = json_tokener_state_object_value_add;
+ tok->depth++;
+ json_tokener_reset_level(tok, tok->depth);
+ goto redo_char;
+
+ case json_tokener_state_object_value_add:
+ json_object_object_add(current, obj_field_name, obj);
+ free(obj_field_name);
+ obj_field_name = NULL;
+ saved_state = json_tokener_state_object_sep;
+ state = json_tokener_state_eatws;
+ goto redo_char;
+
+ case json_tokener_state_object_sep:
+ if(c == '}') {
+ saved_state = json_tokener_state_finish;
+ state = json_tokener_state_eatws;
+ } else if(c == ',') {
+ saved_state = json_tokener_state_object_field_start;
+ state = json_tokener_state_eatws;
+ } else {
+ tok->err = json_tokener_error_parse_object_value_sep;
+ goto out;
+ }
+ break;
+
+ }
+ str++;
+ tok->char_offset++;
+ } while(c);
+
+ if(state != json_tokener_state_finish &&
+ saved_state != json_tokener_state_finish)
+ tok->err = json_tokener_error_parse_eof;
+
+ out:
+ if(tok->err == json_tokener_success) return json_object_get(current);
+ mc_debug("json_tokener_parse_ex: error %s at offset %d\n",
+ json_tokener_errors[tok->err], tok->char_offset);
+ return NULL;
+}
Added: freeswitch/trunk/src/mod/applications/mod_http/json_tokener.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/src/mod/applications/mod_http/json_tokener.h Wed Dec 10 16:43:26 2008
@@ -0,0 +1,89 @@
+/*
+ * $Id: json_tokener.h,v 1.10 2006/07/25 03:24:50 mclark Exp $
+ *
+ * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
+ * Michael Clark <michael(a)metaparadigm.com>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See COPYING for details.
+ *
+ */
+
+#ifndef _json_tokener_h_
+#define _json_tokener_h_
+
+#include "json_object.h"
+
+enum json_tokener_error {
+ json_tokener_success,
+ json_tokener_continue,
+ json_tokener_error_depth,
+ json_tokener_error_parse_eof,
+ json_tokener_error_parse_unexpected,
+ json_tokener_error_parse_null,
+ json_tokener_error_parse_boolean,
+ json_tokener_error_parse_number,
+ json_tokener_error_parse_array,
+ json_tokener_error_parse_object_key_name,
+ json_tokener_error_parse_object_key_sep,
+ json_tokener_error_parse_object_value_sep,
+ json_tokener_error_parse_string,
+ json_tokener_error_parse_comment
+};
+
+enum json_tokener_state {
+ json_tokener_state_eatws,
+ json_tokener_state_start,
+ json_tokener_state_finish,
+ json_tokener_state_null,
+ json_tokener_state_comment_start,
+ json_tokener_state_comment,
+ json_tokener_state_comment_eol,
+ json_tokener_state_comment_end,
+ json_tokener_state_string,
+ json_tokener_state_string_escape,
+ json_tokener_state_escape_unicode,
+ json_tokener_state_boolean,
+ json_tokener_state_number,
+ json_tokener_state_array,
+ json_tokener_state_array_add,
+ json_tokener_state_array_sep,
+ json_tokener_state_object_field_start,
+ json_tokener_state_object_field,
+ json_tokener_state_object_field_end,
+ json_tokener_state_object_value,
+ json_tokener_state_object_value_add,
+ json_tokener_state_object_sep
+};
+
+struct json_tokener_srec
+{
+ enum json_tokener_state state, saved_state;
+ struct json_object *obj;
+ struct json_object *current;
+ char *obj_field_name;
+};
+
+#define JSON_TOKENER_MAX_DEPTH 32
+
+struct json_tokener
+{
+ char *str;
+ struct printbuf *pb;
+ int depth, is_double, st_pos, char_offset;
+ enum json_tokener_error err;
+ unsigned int ucs_char;
+ char quote_char;
+ struct json_tokener_srec stack[JSON_TOKENER_MAX_DEPTH];
+};
+
+extern const char* json_tokener_errors[];
+
+extern struct json_tokener* json_tokener_new();
+extern void json_tokener_free(struct json_tokener *tok);
+extern void json_tokener_reset(struct json_tokener *tok);
+extern struct json_object* json_tokener_parse(char *str);
+extern struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
+ char *str, int len);
+
+#endif
Added: freeswitch/trunk/src/mod/applications/mod_http/json_util.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/src/mod/applications/mod_http/json_util.c Wed Dec 10 16:43:26 2008
@@ -0,0 +1,121 @@
+/*
+ * $Id: json_util.c,v 1.4 2006/01/30 23:07:57 mclark Exp $
+ *
+ * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
+ * Michael Clark <michael(a)metaparadigm.com>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See COPYING for details.
+ *
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <string.h>
+#include <errno.h>
+
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif /* HAVE_SYS_TYPES_H */
+
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif /* HAVE_SYS_STAT_H */
+
+#if HAVE_FCNTL_H
+#include <fcntl.h>
+#endif /* HAVE_FCNTL_H */
+
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
+#ifdef WIN32
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+# include <io.h>
+#endif /* defined(WIN32) */
+
+#if !HAVE_OPEN && defined(WIN32)
+# define open _open
+#endif
+
+
+#include "bits.h"
+#include "debug.h"
+#include "printbuf.h"
+#include "json_object.h"
+#include "json_tokener.h"
+#include "json_util.h"
+
+struct json_object* json_object_from_file(char *filename)
+{
+ struct printbuf *pb;
+ struct json_object *obj;
+ char buf[JSON_FILE_BUF_SIZE];
+ int fd, ret;
+
+ if((fd = open(filename, O_RDONLY)) < 0) {
+ mc_error("json_object_from_file: error reading file %s: %s\n",
+ filename, strerror(errno));
+ return error_ptr(-1);
+ }
+ if(!(pb = printbuf_new())) {
+ mc_error("json_object_from_file: printbuf_new failed\n");
+ return error_ptr(-1);
+ }
+ while((ret = read(fd, buf, JSON_FILE_BUF_SIZE)) > 0) {
+ printbuf_memappend(pb, buf, ret);
+ }
+ close(fd);
+ if(ret < 0) {
+ mc_abort("json_object_from_file: error reading file %s: %s\n",
+ filename, strerror(errno));
+ printbuf_free(pb);
+ return error_ptr(-1);
+ }
+ obj = json_tokener_parse(pb->buf);
+ printbuf_free(pb);
+ return obj;
+}
+
+int json_object_to_file(char *filename, struct json_object *obj)
+{
+ char *json_str;
+ int fd, ret;
+ unsigned int wpos, wsize;
+
+ if(!obj) {
+ mc_error("json_object_to_file: object is null\n");
+ return -1;
+ }
+
+ if((fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT, 0644)) < 0) {
+ mc_error("json_object_to_file: error opening file %s: %s\n",
+ filename, strerror(errno));
+ return -1;
+ }
+
+ if(!(json_str = json_object_to_json_string(obj))) { return -1; }
+
+
+ wsize = (unsigned int)(strlen(json_str) & UINT_MAX); /* CAW: probably unnecessary, but the most 64bit safe */
+ wpos = 0;
+ while(wpos < wsize) {
+ if((ret = write(fd, json_str + wpos, wsize-wpos)) < 0) {
+ close(fd);
+ mc_error("json_object_to_file: error writing file %s: %s\n",
+ filename, strerror(errno));
+ return -1;
+ }
+
+ /* because of the above check for ret < 0, we can safely cast and add */
+ wpos += (unsigned int)ret;
+ }
+
+ close(fd);
+ return 0;
+}
Added: freeswitch/trunk/src/mod/applications/mod_http/json_util.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/src/mod/applications/mod_http/json_util.h Wed Dec 10 16:43:26 2008
@@ -0,0 +1,23 @@
+/*
+ * $Id: json_util.h,v 1.4 2006/01/30 23:07:57 mclark Exp $
+ *
+ * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
+ * Michael Clark <michael(a)metaparadigm.com>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See COPYING for details.
+ *
+ */
+
+#ifndef _json_util_h_
+#define _json_util_h_
+
+#include "json_object.h"
+
+#define JSON_FILE_BUF_SIZE 4096
+
+/* utlitiy functions */
+extern struct json_object* json_object_from_file(char *filename);
+extern int json_object_to_file(char *filename, struct json_object *obj);
+
+#endif
Added: freeswitch/trunk/src/mod/applications/mod_http/linkhash.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/src/mod/applications/mod_http/linkhash.c Wed Dec 10 16:43:26 2008
@@ -0,0 +1,217 @@
+/*
+ * $Id: linkhash.c,v 1.4 2006/01/26 02:16:28 mclark Exp $
+ *
+ * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
+ * Michael Clark <michael(a)metaparadigm.com>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See COPYING for details.
+ *
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <stddef.h>
+#include <limits.h>
+
+#include "linkhash.h"
+
+void lh_abort(const char *msg, ...)
+{
+ va_list ap;
+ va_start(ap, msg);
+ vprintf(msg, ap);
+ exit(1);
+}
+
+unsigned long lh_ptr_hash(void *k)
+{
+ /* CAW: refactored to be 64bit nice */
+ return (unsigned long)((((ptrdiff_t)k * LH_PRIME) >> 4) & ULONG_MAX);
+}
+
+int lh_ptr_equal(void *k1, void *k2)
+{
+ return (k1 == k2);
+}
+
+unsigned long lh_char_hash(void *k)
+{
+ unsigned int h = 0;
+ const char* data = k;
+
+ while( *data!=0 ) h = h*129 + (unsigned int)(*data++) + LH_PRIME;
+
+ return h;
+}
+
+int lh_char_equal(void *k1, void *k2)
+{
+ return (strcmp((char*)k1, (char*)k2) == 0);
+}
+
+struct lh_table* lh_table_new(int size, char *name,
+ lh_entry_free_fn *free_fn,
+ lh_hash_fn *hash_fn,
+ lh_equal_fn *equal_fn)
+{
+ int i;
+ struct lh_table *t;
+
+ t = calloc(1, sizeof(struct lh_table));
+ if(!t) lh_abort("lh_table_new: calloc failed\n");
+ t->count = 0;
+ t->size = size;
+ t->name = name;
+ t->table = calloc(size, sizeof(struct lh_entry));
+ if(!t->table) lh_abort("lh_table_new: calloc failed\n");
+ t->free_fn = free_fn;
+ t->hash_fn = hash_fn;
+ t->equal_fn = equal_fn;
+ for(i = 0; i < size; i++) t->table[i].k = LH_EMPTY;
+ return t;
+}
+
+struct lh_table* lh_kchar_table_new(int size, char *name,
+ lh_entry_free_fn *free_fn)
+{
+ return lh_table_new(size, name, free_fn, lh_char_hash, lh_char_equal);
+}
+
+struct lh_table* lh_kptr_table_new(int size, char *name,
+ lh_entry_free_fn *free_fn)
+{
+ return lh_table_new(size, name, free_fn, lh_ptr_hash, lh_ptr_equal);
+}
+
+void lh_table_resize(struct lh_table *t, int new_size)
+{
+ struct lh_table *new_t;
+ struct lh_entry *ent;
+
+ new_t = lh_table_new(new_size, t->name, NULL, t->hash_fn, t->equal_fn);
+ ent = t->head;
+ while(ent) {
+ lh_table_insert(new_t, ent->k, ent->v);
+ ent = ent->next;
+ }
+ free(t->table);
+ t->table = new_t->table;
+ t->size = new_size;
+ t->head = new_t->head;
+ t->tail = new_t->tail;
+ t->resizes++;
+ free(new_t);
+}
+
+void lh_table_free(struct lh_table *t)
+{
+ struct lh_entry *c;
+ for(c = t->head; c != NULL; c = c->next) {
+ if(t->free_fn) {
+ t->free_fn(c);
+ }
+ }
+ free(t->table);
+ free(t);
+}
+
+
+int lh_table_insert(struct lh_table *t, void *k, void *v)
+{
+ unsigned long h, n;
+
+ t->inserts++;
+ if(t->count > t->size * 0.66) lh_table_resize(t, t->size * 2);
+
+ h = t->hash_fn(k);
+ n = h % t->size;
+
+ while( 1 ) {
+ if(t->table[n].k == LH_EMPTY || t->table[n].k == LH_FREED) break;
+ t->collisions++;
+ if(++n == t->size) n = 0;
+ }
+
+ t->table[n].k = k;
+ t->table[n].v = v;
+ t->count++;
+
+ if(t->head == NULL) {
+ t->head = t->tail = &t->table[n];
+ t->table[n].next = t->table[n].prev = NULL;
+ } else {
+ t->tail->next = &t->table[n];
+ t->table[n].prev = t->tail;
+ t->table[n].next = NULL;
+ t->tail = &t->table[n];
+ }
+
+ return 0;
+}
+
+
+struct lh_entry* lh_table_lookup_entry(struct lh_table *t, void *k)
+{
+ unsigned long h = t->hash_fn(k);
+ unsigned long n = h % t->size;
+
+ t->lookups++;
+ while( 1 ) {
+ if(t->table[n].k == LH_EMPTY) return NULL;
+ if(t->table[n].k != LH_FREED &&
+ t->equal_fn(t->table[n].k, k)) return &t->table[n];
+ if(++n == t->size) n = 0;
+ }
+ return NULL;
+}
+
+
+void* lh_table_lookup(struct lh_table *t, void *k)
+{
+ struct lh_entry *e = lh_table_lookup_entry(t, k);
+ if(e) return e->v;
+ return NULL;
+}
+
+
+int lh_table_delete_entry(struct lh_table *t, struct lh_entry *e)
+{
+ ptrdiff_t n = (ptrdiff_t)(e - t->table); /* CAW: fixed to be 64bit nice, still need the crazy negative case... */
+
+ /* CAW: this is bad, really bad, maybe stack goes other direction on this machine... */
+ if(n < 0) { return -2; }
+
+ if(t->table[n].k == LH_EMPTY || t->table[n].k == LH_FREED) return -1;
+ t->count--;
+ if(t->free_fn) t->free_fn(e);
+ t->table[n].v = NULL;
+ t->table[n].k = LH_FREED;
+ if(t->tail == &t->table[n] && t->head == &t->table[n]) {
+ t->head = t->tail = NULL;
+ } else if (t->head == &t->table[n]) {
+ t->head->next->prev = NULL;
+ t->head = t->head->next;
+ } else if (t->tail == &t->table[n]) {
+ t->tail->prev->next = NULL;
+ t->tail = t->tail->prev;
+ } else {
+ t->table[n].prev->next = t->table[n].next;
+ t->table[n].next->prev = t->table[n].prev;
+ }
+ t->table[n].next = t->table[n].prev = NULL;
+ return 0;
+}
+
+
+int lh_table_delete(struct lh_table *t, void *k)
+{
+ struct lh_entry *e = lh_table_lookup_entry(t, k);
+ if(!e) return -1;
+ return lh_table_delete_entry(t, e);
+}
+
Added: freeswitch/trunk/src/mod/applications/mod_http/linkhash.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/src/mod/applications/mod_http/linkhash.h Wed Dec 10 16:43:26 2008
@@ -0,0 +1,261 @@
+/*
+ * $Id: linkhash.h,v 1.6 2006/01/30 23:07:57 mclark Exp $
+ *
+ * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
+ * Michael Clark <michael(a)metaparadigm.com>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See COPYING for details.
+ *
+ */
+
+#ifndef _linkhash_h_
+#define _linkhash_h_
+
+/**
+ * golden prime used in hash functions
+ */
+#define LH_PRIME 0x9e370001UL
+
+/**
+ * sentinel pointer value for empty slots
+ */
+#define LH_EMPTY (void*)-1
+
+/**
+ * sentinel pointer value for freed slots
+ */
+#define LH_FREED (void*)-2
+
+struct lh_entry;
+
+/**
+ * callback function prototypes
+ */
+typedef void (lh_entry_free_fn) (struct lh_entry *e);
+/**
+ * callback function prototypes
+ */
+typedef unsigned long (lh_hash_fn) (void *k);
+/**
+ * callback function prototypes
+ */
+typedef int (lh_equal_fn) (void *k1, void *k2);
+
+/**
+ * An entry in the hash table
+ */
+struct lh_entry {
+ /**
+ * The key.
+ */
+ void *k;
+ /**
+ * The value.
+ */
+ void *v;
+ /**
+ * The next entry
+ */
+ struct lh_entry *next;
+ /**
+ * The previous entry.
+ */
+ struct lh_entry *prev;
+};
+
+
+/**
+ * The hash table structure.
+ */
+struct lh_table {
+ /**
+ * Size of our hash.
+ */
+ int size;
+ /**
+ * Numbers of entries.
+ */
+ int count;
+
+ /**
+ * Number of collisions.
+ */
+ int collisions;
+
+ /**
+ * Number of resizes.
+ */
+ int resizes;
+
+ /**
+ * Number of lookups.
+ */
+ int lookups;
+
+ /**
+ * Number of inserts.
+ */
+ int inserts;
+
+ /**
+ * Number of deletes.
+ */
+ int deletes;
+
+ /**
+ * Name of the hash table.
+ */
+ char *name;
+
+ /**
+ * The first entry.
+ */
+ struct lh_entry *head;
+
+ /**
+ * The last entry.
+ */
+ struct lh_entry *tail;
+
+ struct lh_entry *table;
+
+ /**
+ * A pointer onto the function responsible for freeing an entry.
+ */
+ lh_entry_free_fn *free_fn;
+ lh_hash_fn *hash_fn;
+ lh_equal_fn *equal_fn;
+};
+
+
+/**
+ * Pre-defined hash and equality functions
+ */
+extern unsigned long lh_ptr_hash(void *k);
+extern int lh_ptr_equal(void *k1, void *k2);
+
+extern unsigned long lh_char_hash(void *k);
+extern int lh_char_equal(void *k1, void *k2);
+
+
+/**
+ * Convenience list iterator.
+ */
+#define lh_foreach(table, entry) \
+for(entry = table->head; entry; entry = entry->next)
+
+/**
+ * lh_foreach_safe allows calling of deletion routine while iterating.
+ */
+#define lh_foreach_safe(table, entry, tmp) \
+for(entry = table->head; entry && ((tmp = entry->next) || 1); entry = tmp)
+
+
+
+/**
+ * Create a new linkhash table.
+ * @param size initial table size. The table is automatically resized
+ * although this incurs a performance penalty.
+ * @param name the table name.
+ * @param free_fn callback function used to free memory for entries
+ * when lh_table_free or lh_table_delete is called.
+ * If NULL is provided, then memory for keys and values
+ * must be freed by the caller.
+ * @param hash_fn function used to hash keys. 2 standard ones are defined:
+ * lh_ptr_hash and lh_char_hash for hashing pointer values
+ * and C strings respectively.
+ * @param equal_fn comparison function to compare keys. 2 standard ones defined:
+ * lh_ptr_hash and lh_char_hash for comparing pointer values
+ * and C strings respectively.
+ * @return a pointer onto the linkhash table.
+ */
+extern struct lh_table* lh_table_new(int size, char *name,
+ lh_entry_free_fn *free_fn,
+ lh_hash_fn *hash_fn,
+ lh_equal_fn *equal_fn);
+
+/**
+ * Convenience function to create a new linkhash
+ * table with char keys.
+ * @param size initial table size.
+ * @param name table name.
+ * @param free_fn callback function used to free memory for entries.
+ * @return a pointer onto the linkhash table.
+ */
+extern struct lh_table* lh_kchar_table_new(int size, char *name,
+ lh_entry_free_fn *free_fn);
+
+
+/**
+ * Convenience function to create a new linkhash
+ * table with ptr keys.
+ * @param size initial table size.
+ * @param name table name.
+ * @param free_fn callback function used to free memory for entries.
+ * @return a pointer onto the linkhash table.
+ */
+extern struct lh_table* lh_kptr_table_new(int size, char *name,
+ lh_entry_free_fn *free_fn);
+
+
+/**
+ * Free a linkhash table.
+ * If a callback free function is provided then it is called for all
+ * entries in the table.
+ * @param t table to free.
+ */
+extern void lh_table_free(struct lh_table *t);
+
+
+/**
+ * Insert a record into the table.
+ * @param t the table to insert into.
+ * @param k a pointer to the key to insert.
+ * @param v a pointer to the value to insert.
+ */
+extern int lh_table_insert(struct lh_table *t, void *k, void *v);
+
+
+/**
+ * Lookup a record into the table.
+ * @param t the table to lookup
+ * @param k a pointer to the key to lookup
+ * @return a pointer to the record structure of the value or NULL if it does not exist.
+ */
+extern struct lh_entry* lh_table_lookup_entry(struct lh_table *t, void *k);
+
+/**
+ * Lookup a record into the table
+ * @param t the table to lookup
+ * @param k a pointer to the key to lookup
+ * @return a pointer to the found value or NULL if it does not exist.
+ */
+extern void* lh_table_lookup(struct lh_table *t, void *k);
+
+
+/**
+ * Delete a record from the table.
+ * If a callback free function is provided then it is called for the
+ * for the item being deleted.
+ * @param t the table to delete from.
+ * @param e a pointer to the entry to delete.
+ * @return 0 if the item was deleted.
+ * @return -1 if it was not found.
+ */
+extern int lh_table_delete_entry(struct lh_table *t, struct lh_entry *e);
+
+
+/**
+ * Delete a record from the table.
+ * If a callback free function is provided then it is called for the
+ * for the item being deleted.
+ * @param t the table to delete from.
+ * @param k a pointer to the key to delete.
+ * @return 0 if the item was deleted.
+ * @return -1 if it was not found.
+ */
+extern int lh_table_delete(struct lh_table *t, void *k);
+
+
+#endif
Added: freeswitch/trunk/src/mod/applications/mod_http/mod_http.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/src/mod/applications/mod_http/mod_http.c Wed Dec 10 16:43:26 2008
@@ -0,0 +1,356 @@
+/*
+ * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
+ * Copyright (C) 2008, Eric des Courtis <eric.des.courtis(a)benbria.com>
+ *
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * Eric des Courtis <eric.des.courtis(a)benbria.com>
+ * Copyright (C) Benbria. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Eric des Courtis <eric.des.courtis(a)benbria.com>
+ *
+ *
+ * mod_http.c -- HTTP client implementation for FreeSWITCH
+ *
+ * The purpose is to provide laguages like LUA with a _fast_ HTTP
+ * client implementation.
+ *
+ * Support for SSL will be provided in future versions.
+ * Initial release does not include win32 support.
+ *
+ */
+
+#include <switch.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <sys/queue.h>
+#include "json.h"
+
+#include "http_req.h"
+#include "url_encoding.h"
+
+#define HTTP_SYNTAX "<http_method> <url> <urlejson_headers> [urlejson_body]"
+#define HTTP_PARAMS 4
+#define HTTP_BUFFER_SIZE (256 * 1024)
+
+/* SWITCH_STANDARD_API(http_api_main); */
+
+#define MAX_MEMLOCS 512
+#define GARBAGE_TYPES_INIT() \
+typedef struct memloc{\
+ void *p;\
+ LIST_ENTRY(memloc) memlocs;\
+} memloc_t
+
+#define GARBAGE_CLEANUP() \
+do{\
+ for(memloc_p = head.lh_first; memloc_p != NULL; \
+ memloc_p = memloc_p->memlocs.le_next){\
+ free(memloc_p->p);\
+ }\
+}while(0)
+
+#define GARBAGE_ADD(a) \
+do {\
+ if(memloc_i >= MAX_MEMLOCS){\
+ switch_safe_free(ccmd);\
+ GARBAGE_CLEANUP();\
+ stream->write_function(stream, "-ERR\n");\
+ return SWITCH_STATUS_SUCCESS;\
+ }\
+ memloc_a[memloc_i].p = (void *)a;\
+ LIST_INSERT_HEAD(&head, memloc_a + memloc_i, memlocs);\
+ memloc_i++;\
+}while(0)
+
+#define GARBAGE_INIT() \
+ LIST_HEAD(listhead, memloc) head;\
+ memloc_t memloc_a[MAX_MEMLOCS];\
+ memloc_t *memloc_p;\
+ size_t memloc_i;\
+ LIST_INIT(&head);\
+ memloc_i = 0
+
+GARBAGE_TYPES_INIT();
+
+SWITCH_STANDARD_API(http_api_main)
+{
+ char *ccmd;
+ int argc;
+ char *argv[HTTP_PARAMS];
+ char *buf;
+ char *method;
+ char *url;
+ char *headers_str;
+ char *value;
+ char *body;
+ char *body_dec;
+ char *t;
+ char *json_response;
+ struct json_object *json_http_headers;
+ char *key;
+ struct json_object *val;
+ struct lh_entry *entry;
+ int i;
+ int j;
+ int f;
+ size_t l;
+ size_t m;
+ size_t a = 0;
+ int ret;
+
+ http_header_t *headers;
+ http_request_t request;
+ http_response_t response;
+
+ GARBAGE_INIT();
+
+ (void)memset(&response, 0, sizeof(response));
+
+ if(cmd == NULL){
+ stream->write_function(stream, "-USAGE: %s\n", HTTP_SYNTAX);
+ return SWITCH_STATUS_SUCCESS;
+ }
+
+ ccmd = strdup(cmd);
+ argc = switch_separate_string(ccmd, ' ', argv, HTTP_PARAMS);
+
+ if(argc != HTTP_PARAMS && argc != (HTTP_PARAMS - 1)){
+ switch_safe_free(ccmd);
+ stream->write_function(stream, "-ERR\n");
+ return SWITCH_STATUS_SUCCESS;
+ }
+
+ method = argv[0];
+ url = argv[1];
+ headers_str = argv[2];
+ if(argc == HTTP_PARAMS){
+ body = argv[3];
+ }else{
+ body = (char *)malloc(1 * sizeof(char));
+ if(body == NULL){
+ switch_safe_free(ccmd);
+ stream->write_function(stream, "-ERR\n");
+ return SWITCH_STATUS_SUCCESS;
+ }
+ body[0] = '\0';
+ GARBAGE_ADD(body);
+ }
+
+ buf = (char *)malloc(HTTP_BUFFER_SIZE * sizeof(char));
+ if(buf == NULL){
+ switch_safe_free(ccmd);
+ stream->write_function(stream, "-ERR\n");
+ GARBAGE_CLEANUP();
+ return SWITCH_STATUS_SUCCESS;
+ }
+
+ GARBAGE_ADD(buf);
+
+ request.version = DEFAULT_HTTP_VERSION;
+ l = strlen(url);
+ request.url = (char *)malloc((l + 1) * sizeof(char));
+ if(request.url == NULL){
+ switch_safe_free(ccmd);
+ stream->write_function(stream, "-ERR\n");
+ GARBAGE_CLEANUP();
+ return SWITCH_STATUS_SUCCESS;
+ }
+
+ GARBAGE_ADD(request.url);
+ strcpy(request.url, url);
+ json_http_headers = json_tokener_parse(headers_str);
+
+ i = 0;
+ json_object_object_foreach(json_http_headers, key, val){
+ i++;
+ }
+
+ request.header_len = i;
+ headers = (http_header_t *)malloc(i * sizeof(http_header_t));
+ GARBAGE_ADD(headers);
+
+ i = 0;
+ json_object_object_foreach(json_http_headers, key, val){
+ l = strlen(key);
+ request.headers[i].field_name = (char *)malloc((l + 1) * sizeof(char));
+ if(request.headers[i].field_name == NULL){
+ switch_safe_free(ccmd);
+ stream->write_function(stream, "-ERR\n");
+ GARBAGE_CLEANUP();
+ return SWITCH_STATUS_SUCCESS;
+ }
+ GARBAGE_ADD(request.headers[i].field_name);
+ strcpy(request.headers[i].field_name, key);
+ a += strlen(key);
+
+ value = json_object_to_json_string(val);
+ l = strlen(value);
+ request.headers[i].value = (char *)malloc((l + 1) * sizeof(char));
+ if(request.headers[i].value == NULL){
+ switch_safe_free(ccmd);
+ stream->write_function(stream, "-ERR\n");
+ GARBAGE_CLEANUP();
+ return SWITCH_STATUS_SUCCESS;
+ }
+ GARBAGE_ADD(request.headers[i].value);
+ strcpy(request.headers[i].value, value);
+ a += strlen(value);
+ i++;
+ }
+
+ if(argc == HTTP_PARAMS){
+ l = strlen(body);
+ body_dec = url_decode(body, l);
+ GARBAGE_ADD(body_dec);
+ l = strlen(body_dec);
+ request.body_len = l;
+ request.body = body_dec;
+ }else request.body_len = 0;
+
+ ret = http_req(&request, &response);
+ if(response.version != NULL) GARBAGE_ADD(response.version);
+ if(response.phrase != NULL) GARBAGE_ADD(response.phrase);
+ if(response.headers != NULL) GARBAGE_ADD(response.headers);
+ if(response.body != NULL) GARBAGE_ADD(response.body);
+ for(i = 0; i < response.header_len; i++){
+ GARBAGE_ADD(response.headers[i].field_name);
+ GARBAGE_ADD(response.headers[i].value);
+ }
+
+
+ if(ret == ERROR){
+ switch_safe_free(ccmd);
+ stream->write_function(stream, "-ERR\n");
+ GARBAGE_CLEANUP();
+ return SWITCH_STATUS_SUCCESS;
+ }
+
+ /* This is evil and should be changed in the future */
+ l = 128 + (256 * response.header_len) + (a * 2)
+ + strlen("version") + strlen(response.version)
+ + strlen("status_code") + 3
+ + strlen("phrase") + strlen(response.phrase)
+ + strlen("body") + (response.body_len * 3) + 1
+ + strlen("headers")
+ + 1;
+
+ /* to be safe */
+ l <<= 2;
+
+ json_response = (char *)malloc(l * sizeof(char));
+ if(json_response == NULL){
+ switch_safe_free(ccmd);
+ stream->write_function(stream, "-ERR\n");
+ GARBAGE_CLEANUP();
+ return SWITCH_STATUS_SUCCESS;
+ }
+ GARBAGE_ADD(json_response);
+
+ if(response.body_len != 0){
+ t = (char *)malloc((response.body_len + 1) * sizeof(char));
+ if(t == NULL){
+ switch_safe_free(ccmd);
+ stream->write_function(stream, "-ERR\n");
+ GARBAGE_CLEANUP();
+ return SWITCH_STATUS_SUCCESS;
+ }
+ GARBAGE_ADD(t);
+ (void)memcpy(t, response.body, response.body_len);
+ t[response.body_len] = '\0';
+ response.body = url_encode(t, response.body_len);
+ GARBAGE_ADD(response.body);
+ }
+
+
+ m = snprintf(json_response, l,
+ "{"
+ "\"version\": \"%s\","
+ "\"status_code\": \"%3d\","
+ "\"phrase\": \"%s\","
+ "\"body\": \"%s\","
+ "\"headers\": [",
+ response.version,
+ response.status_code,
+ response.phrase,
+ ((response.body_len <= 0)? "":response.body)
+ );
+
+
+ for(f = HTTP_FALSE, j = 0; j < response.header_len; j++){
+ if(f != HTTP_FALSE){
+ m += snprintf(json_response + m, l - m,
+ ","
+ );
+ }else f = HTTP_TRUE;
+
+ m += snprintf(json_response + m, l - m,
+ "{\"key\": \"%s\",\"value\": \"%s\"}",
+ response.headers[j].field_name,
+ response.headers[j].value
+ );
+ }
+
+
+ m += snprintf(json_response + m, l - m, "]}");
+ json_response[m] = '\0';
+
+
+ switch_log_printf(
+ SWITCH_CHANNEL_LOG,
+ SWITCH_LOG_NOTICE,
+ "RESERVED %d BYTES, USED %d BYTES, HTTP Response as JSON: %s\n",
+ l,
+ m,
+ json_response
+ );
+
+
+ stream->write_function(stream, "%s\n", json_response);
+
+ switch_safe_free(ccmd);
+ GARBAGE_CLEANUP();
+ return SWITCH_STATUS_SUCCESS;
+}
+
+SWITCH_MODULE_LOAD_FUNCTION(mod_http_load);
+SWITCH_MODULE_DEFINITION(mod_http, mod_http_load, NULL, NULL);
+
+SWITCH_MODULE_LOAD_FUNCTION(mod_http_load)
+{
+ switch_api_interface_t *api_interface;
+
+ *module_interface =
+ switch_loadable_module_create_module_interface(pool, modname);
+
+ switch_log_printf(
+ SWITCH_CHANNEL_LOG,
+ SWITCH_LOG_NOTICE,
+ "HTTP request mod enabled\n"
+ );
+
+ SWITCH_ADD_API(
+ api_interface,
+ "http",
+ "Make HTTP requests",
+ http_api_main,
+ HTTP_SYNTAX
+ );
+
+ return SWITCH_STATUS_SUCCESS;
+}
+
Added: freeswitch/trunk/src/mod/applications/mod_http/printbuf.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/src/mod/applications/mod_http/printbuf.c Wed Dec 10 16:43:26 2008
@@ -0,0 +1,144 @@
+/*
+ * $Id: printbuf.c,v 1.5 2006/01/26 02:16:28 mclark Exp $
+ *
+ * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
+ * Michael Clark <michael(a)metaparadigm.com>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See COPYING for details.
+ *
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#if HAVE_STDARG_H
+# include <stdarg.h>
+#else /* !HAVE_STDARG_H */
+# error Not enough var arg support!
+#endif /* HAVE_STDARG_H */
+
+#include "bits.h"
+#include "debug.h"
+#include "printbuf.h"
+
+struct printbuf* printbuf_new()
+{
+ struct printbuf *p;
+
+ if(!(p = calloc(1, sizeof(struct printbuf)))) return NULL;
+ p->size = 32;
+ p->bpos = 0;
+ if(!(p->buf = malloc(p->size))) {
+ free(p);
+ return NULL;
+ }
+ return p;
+}
+
+
+int printbuf_memappend(struct printbuf *p, char *buf, int size)
+{
+ char *t;
+ if(p->size - p->bpos <= size) {
+ int new_size = max(p->size * 2, p->bpos + size + 8);
+#ifdef PRINTBUF_DEBUG
+ mc_debug("printbuf_memappend: realloc "
+ "bpos=%d wrsize=%d old_size=%d new_size=%d\n",
+ p->bpos, size, p->size, new_size);
+#endif /* PRINTBUF_DEBUG */
+ if(!(t = realloc(p->buf, new_size))) return -1;
+ p->size = new_size;
+ p->buf = t;
+ }
+ memcpy(p->buf + p->bpos, buf, size);
+ p->bpos += size;
+ p->buf[p->bpos]= '\0';
+ return size;
+}
+
+#if !HAVE_VSNPRINTF && defined(WIN32)
+# define vsnprintf _vsnprintf
+#elif !HAVE_VSNPRINTF /* !HAVE_VSNPRINTF */
+# error Need vsnprintf!
+#endif /* !HAVE_VSNPRINTF && defined(WIN32) */
+
+#if !HAVE_VASPRINTF
+/* CAW: compliant version of vasprintf */
+static int vasprintf(char **buf, const char *fmt, va_list ap)
+{
+#ifndef WIN32
+ static char _T_emptybuffer = '\0';
+#endif /* !defined(WIN32) */
+ int chars;
+ char *b;
+
+ if(!buf) { return -1; }
+
+#ifdef WIN32
+ chars = _vscprintf(fmt, ap)+1;
+#else /* !defined(WIN32) */
+ /* CAW: RAWR! We have to hope to god here that vsnprintf doesn't overwrite
+ our buffer like on some 64bit sun systems.... but hey, its time to move on */
+ chars = vsnprintf(&_T_emptybuffer, 0, fmt, ap)+1;
+ if(chars < 0) { chars *= -1; } /* CAW: old glibc versions have this problem */
+#endif /* defined(WIN32) */
+
+ b = (char*)malloc(sizeof(char)*chars);
+ if(!b) { return -1; }
+
+ if((chars = vsprintf(b, fmt, ap)) < 0)
+ {
+ free(b);
+ } else {
+ *buf = b;
+ }
+
+ return chars;
+}
+#endif /* !HAVE_VASPRINTF */
+
+int sprintbuf(struct printbuf *p, const char *msg, ...)
+{
+ va_list ap;
+ char *t;
+ int size;
+ char buf[128];
+
+ /* user stack buffer first */
+ va_start(ap, msg);
+ size = vsnprintf(buf, 128, msg, ap);
+ va_end(ap);
+ /* if string is greater than stack buffer, then use dynamic string
+ with vasprintf. Note: some implementation of vsnprintf return -1
+ if output is truncated whereas some return the number of bytes that
+ would have been writen - this code handles both cases. */
+ if(size == -1 || size > 127) {
+ int ret;
+ va_start(ap, msg);
+ if((size = vasprintf(&t, msg, ap)) == -1) return -1;
+ va_end(ap);
+ ret = printbuf_memappend(p, t, size);
+ free(t);
+ return ret;
+ } else {
+ return printbuf_memappend(p, buf, size);
+ }
+}
+
+void printbuf_reset(struct printbuf *p)
+{
+ p->buf[0] = '\0';
+ p->bpos = 0;
+}
+
+void printbuf_free(struct printbuf *p)
+{
+ if(p) {
+ free(p->buf);
+ free(p);
+ }
+}
Added: freeswitch/trunk/src/mod/applications/mod_http/printbuf.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/src/mod/applications/mod_http/printbuf.h Wed Dec 10 16:43:26 2008
@@ -0,0 +1,38 @@
+/*
+ * $Id: printbuf.h,v 1.4 2006/01/26 02:16:28 mclark Exp $
+ *
+ * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
+ * Michael Clark <michael(a)metaparadigm.com>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See COPYING for details.
+ *
+ */
+
+#ifndef _printbuf_h_
+#define _printbuf_h_
+
+#undef PRINTBUF_DEBUG
+
+struct printbuf {
+ char *buf;
+ int bpos;
+ int size;
+};
+
+extern struct printbuf*
+printbuf_new();
+
+extern int
+printbuf_memappend(struct printbuf *p, char *buf, int size);
+
+extern int
+sprintbuf(struct printbuf *p, const char *msg, ...);
+
+extern void
+printbuf_reset(struct printbuf *p);
+
+extern void
+printbuf_free(struct printbuf *p);
+
+#endif
Added: freeswitch/trunk/src/mod/applications/mod_http/url_encoding.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/src/mod/applications/mod_http/url_encoding.c Wed Dec 10 16:43:26 2008
@@ -0,0 +1,125 @@
+/*
+ * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
+ * Copyright (C) 2008, Eric des Courtis <eric.des.courtis(a)benbria.com>
+ *
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * Eric des Courtis <eric.des.courtis(a)benbria.com>
+ * Copyright (C) Benbria. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Eric des Courtis <eric.des.courtis(a)benbria.com>
+ *
+ *
+ * url_encoding.c -- url encoding/decoding
+ *
+ */
+#include "url_encoding.h"
+
+#ifdef DEBUG
+int main(int argc, char *argv[])
+{
+ char *buf1;
+ char *buf2;
+
+
+ buf1 = url_encode("This is a test #$ ");
+ buf2 = url_decode(buf1);
+
+ printf("%s\n", buf2);
+
+ free(buf1);
+ free(buf2);
+ return EXIT_FAILURE;
+}
+
+#endif
+
+char *url_encode(char *url, size_t l)
+{
+ int i;
+ int j;
+ char *buf;
+ unsigned char c;
+
+ buf = (char *)malloc((l * 3) + 1);
+ if(buf == NULL){
+ perror("Could not allocate memory url encoding");
+ return NULL;
+ }
+
+ for(i = 0, j = 0; i < l; i++){
+ c = (unsigned char)url[i];
+ if(c <= 31 || c >= 127
+ || c == '$' || c == '&' || c == '+' || c == ',' || c == '/'
+ || c == ':' || c == ';' || c == '=' || c == '?' || c == '@'
+ || c == ' ' || c == '"' || c == '<' || c == '>' || c == '#'
+ || c == '%' || c == '{' || c == '}' || c == '|' || c == '\\'
+ || c == '^' || c == '~' || c == '[' || c == ']' || c == '`'){
+
+ (void)sprintf(buf + j, "%%%X%X", c >> 4, c & 0x0F);
+ j += 3;
+ }else{
+ buf[j] = url[i];
+ j++;
+ }
+ }
+
+ buf[j] = '\0';
+
+ return buf;
+}
+
+char *url_decode(char *url, size_t l)
+{
+ int i;
+ int j;
+ char *buf;
+ char c;
+ char d0;
+ char d1;
+
+ buf = (char *)malloc((l + 1) * sizeof(char));
+ if(buf == NULL){
+ perror("Could not allocate memory for decoding");
+ return NULL;
+ }
+
+ for(i = 0, j = 0; i < l; j++){
+ c = url[i];
+ if(c == '%'){
+ d0 = url[i + 2];
+ d1 = url[i + 1];
+ d0 = toupper(d0);
+ d1 = toupper(d1);
+
+ if(d0 >= 'A' && d0 <= 'F') d0 = d0 - 'A' + 10;
+ else if(d0 >= '0' && d0 <= '9') d0 = d0 - '0';
+ if(d1 >= 'A' && d1 <= 'F') d1 = d1 - 'A' + 10;
+ else if(d1 >= '0' && d1 <= '9') d1 = d1 - '0';
+
+ buf[j] = (d1 << 4) + d0;
+ i += 3;
+ }else{
+ buf[j] = url[i];
+ i++;
+ }
+ }
+
+ buf[j] = '\0';
+
+ return buf;
+}
+
+
Added: freeswitch/trunk/src/mod/applications/mod_http/url_encoding.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/src/mod/applications/mod_http/url_encoding.h Wed Dec 10 16:43:26 2008
@@ -0,0 +1,42 @@
+/*
+ * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
+ * Copyright (C) 2008, Eric des Courtis <eric.des.courtis(a)benbria.com>
+ *
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * Eric des Courtis <eric.des.courtis(a)benbria.com>
+ * Copyright (C) Benbria. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Eric des Courtis <eric.des.courtis(a)benbria.com>
+ *
+ *
+ * url_encoding.h -- url encoding/decoding
+ *
+ */
+
+#ifndef __URL_ENCODING_H__
+#define __URL_ENCODING_H__
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+
+char *url_encode(char *url, size_t l);
+char *url_decode(char *url, size_t l);
+
+#endif
+
1
0